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 public int[] next() {
69
70 Validate.isTrue(hasNext());
71
72 boolean carryOver = true;
73 int currentIndex = 0;
74 while (carryOver && currentIndex < indices.length) {
75
76 indices[currentIndex] += 1;
77
78 if (indices[currentIndex] >= maxIndices[currentIndex] && currentIndex < indices.length - 1) {
79 indices[currentIndex] = 0;
80
81 for (int j = 0; j < currentIndex; j++) {
82 indices[j] = 0;
83 }
84
85 currentIndex++;
86 carryOver = true;
87 } else {
88 carryOver = false;
89 }
90
91 }
92
93 return indices;
94 }
95
96 @Override
97 public int hashCode() {
98 final int prime = 31;
99 int result = 1;
100 result = prime * result + Arrays.hashCode(indices);
101 result = prime * result + Arrays.hashCode(maxIndices);
102 return result;
103 }
104
105 @Override
106 public boolean equals(Object obj) {
107 if (this == obj)
108 return true;
109 if (obj == null)
110 return false;
111 if (getClass() != obj.getClass())
112 return false;
113 MultiIntCounter other = (MultiIntCounter) obj;
114 if (!Arrays.equals(indices, other.indices))
115 return false;
116 if (!Arrays.equals(maxIndices, other.maxIndices))
117 return false;
118 return true;
119 }
120
121 @Override
122 public String toString() {
123 return "MultiIntCounter [indices=" + Arrays.toString(indices) + ", maxIndices=" + Arrays.toString(maxIndices)
124 + "]";
125 }
126 }