1 package net.bmahe.genetics4j.core.util;
2
3 import java.util.Arrays;
4 import java.util.Objects;
5
6 import org.apache.commons.lang3.Validate;
7
8 public class MultiIntCounter {
9
10 final int[] indices;
11 final int[] maxIndices;
12
13 public MultiIntCounter(final int... maxIndices) {
14 Objects.requireNonNull(maxIndices);
15 Validate.isTrue(maxIndices.length > 0);
16
17 for (int i = 0; i < maxIndices.length; i++) {
18 final int maxIndex = maxIndices[i];
19 Validate.isTrue(maxIndex > 0);
20 }
21
22 this.indices = new int[maxIndices.length];
23 this.maxIndices = Arrays.copyOf(maxIndices, maxIndices.length);
24 }
25
26 public int[] getIndices() {
27 return indices;
28 }
29
30 public int getIndex(final int index) {
31 Validate.isTrue(index >= 0);
32 Validate.isTrue(index < indices.length);
33
34 return indices[index];
35 }
36
37 public int[] getMaxIndices() {
38 return maxIndices;
39 }
40
41 public int getTotal() {
42 int total = 1;
43 for (int i : maxIndices) {
44 total *= i;
45 }
46 return total;
47 }
48
49 public boolean hasNext() {
50
51
52
53
54 boolean allToTheMax = false;
55 for (int i = 0; i < indices.length && !allToTheMax; i++) {
56 if (indices[i] >= maxIndices[i]) {
57 allToTheMax = true;
58 }
59 }
60 return allToTheMax == false;
61 }
62
63
64
65
66
67
68
69 public int[] next() {
70
71 Validate.isTrue(hasNext());
72
73 boolean carryOver = true;
74 int currentIndex = 0;
75 while (carryOver && currentIndex < indices.length) {
76
77 indices[currentIndex] += 1;
78
79 if (indices[currentIndex] >= maxIndices[currentIndex] && currentIndex < indices.length - 1) {
80 indices[currentIndex] = 0;
81
82 for (int j = 0; j < currentIndex; j++) {
83 indices[j] = 0;
84 }
85
86 currentIndex++;
87 carryOver = true;
88 } else {
89 carryOver = false;
90 }
91
92 }
93
94 return indices;
95 }
96
97 @Override
98 public int hashCode() {
99 final int prime = 31;
100 int result = 1;
101 result = prime * result + Arrays.hashCode(indices);
102 return prime * result + Arrays.hashCode(maxIndices);
103 }
104
105 @Override
106 public boolean equals(Object obj) {
107 if (this == obj) {
108 return true;
109 }
110 if (obj == null) {
111 return false;
112 }
113 if (getClass() != obj.getClass()) {
114 return false;
115 }
116 MultiIntCounter other = (MultiIntCounter) obj;
117 if (!Arrays.equals(indices, other.indices)) {
118 return false;
119 }
120 return Arrays.equals(maxIndices, other.maxIndices);
121 }
122
123 @Override
124 public String toString() {
125 return "MultiIntCounter [indices=" + Arrays.toString(indices) + ", maxIndices=" + Arrays.toString(maxIndices)
126 + "]";
127 }
128 }