1 package net.bmahe.genetics4j.core.util;
2
3 import java.util.Arrays;
4
5 import org.apache.commons.lang3.Validate;
6
7 public class MultiIntCounter {
8
9 final int[] indices;
10 final int[] maxIndices;
11
12 public MultiIntCounter(final int... maxIndices) {
13 Validate.notNull(maxIndices);
14 Validate.isTrue(maxIndices.length > 0);
15
16 for (int i = 0; i < maxIndices.length; i++) {
17 final int maxIndex = maxIndices[i];
18 Validate.isTrue(maxIndex > 0);
19 }
20
21 this.indices = new int[maxIndices.length];
22 this.maxIndices = Arrays.copyOf(maxIndices, maxIndices.length);
23 }
24
25 public int[] getIndices() {
26 return indices;
27 }
28
29 public int getIndex(final int index) {
30 Validate.isTrue(index >= 0);
31 Validate.isTrue(index < indices.length);
32
33 return indices[index];
34 }
35
36 public int[] getMaxIndices() {
37 return maxIndices;
38 }
39
40 public int getTotal() {
41 int total = 1;
42 for (int i : maxIndices) {
43 total *= i;
44 }
45 return total;
46 }
47
48 public boolean hasNext() {
49
50
51
52
53 boolean allToTheMax = false;
54 for (int i = 0; i < indices.length && !allToTheMax; i++) {
55 if (indices[i] >= maxIndices[i]) {
56 allToTheMax = true;
57 }
58 }
59 return allToTheMax == false;
60 }
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 result = prime * result + Arrays.hashCode(maxIndices);
103 return result;
104 }
105
106 @Override
107 public boolean equals(Object obj) {
108 if (this == obj)
109 return true;
110 if (obj == null)
111 return false;
112 if (getClass() != obj.getClass())
113 return false;
114 MultiIntCounter other = (MultiIntCounter) obj;
115 if (!Arrays.equals(indices, other.indices))
116 return false;
117 if (!Arrays.equals(maxIndices, other.maxIndices))
118 return false;
119 return true;
120 }
121
122 @Override
123 public String toString() {
124 return "MultiIntCounter [indices=" + Arrays.toString(indices) + ", maxIndices=" + Arrays.toString(maxIndices)
125 + "]";
126 }
127 }