1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.util;
23
24 import java.lang.reflect.Constructor;
25 import java.lang.reflect.InvocationTargetException;
26 import java.lang.reflect.Method;
27 import java.util.Comparator;
28 import java.util.Iterator;
29 import java.util.NoSuchElementException;
30
31 import org.hipparchus.exception.MathIllegalArgumentException;
32 import org.junit.Assert;
33 import org.junit.Test;
34
35
36
37
38 public class CombinationsTest {
39 @Test
40 public void testAccessor1() {
41 final int n = 5;
42 final int k = 3;
43 Assert.assertEquals(n, new Combinations(n, k).getN());
44 }
45 @Test
46 public void testAccessor2() {
47 final int n = 5;
48 final int k = 3;
49 Assert.assertEquals(k, new Combinations(n, k).getK());
50 }
51
52 @Test
53 public void testLexicographicIterator() {
54 checkLexicographicIterator(new Combinations(5, 3));
55 checkLexicographicIterator(new Combinations(6, 4));
56 checkLexicographicIterator(new Combinations(8, 2));
57 checkLexicographicIterator(new Combinations(6, 1));
58 checkLexicographicIterator(new Combinations(3, 3));
59 checkLexicographicIterator(new Combinations(1, 1));
60 checkLexicographicIterator(new Combinations(1, 0));
61 checkLexicographicIterator(new Combinations(0, 0));
62 checkLexicographicIterator(new Combinations(4, 2));
63 checkLexicographicIterator(new Combinations(123, 2));
64 }
65
66 @Test(expected=MathIllegalArgumentException.class)
67 public void testLexicographicComparatorWrongIterate1() {
68 final int n = 5;
69 final int k = 3;
70 final Comparator<int[]> comp = new Combinations(n, k).comparator();
71 comp.compare(new int[] {1}, new int[] {0, 1, 2});
72 }
73
74 @Test(expected=MathIllegalArgumentException.class)
75 public void testLexicographicComparatorWrongIterate2() {
76 final int n = 5;
77 final int k = 3;
78 final Comparator<int[]> comp = new Combinations(n, k).comparator();
79 comp.compare(new int[] {0, 1, 2}, new int[] {0, 1, 2, 3});
80 }
81
82 @Test(expected=MathIllegalArgumentException.class)
83 public void testLexicographicComparatorWrongIterate3() {
84 final int n = 5;
85 final int k = 3;
86 final Comparator<int[]> comp = new Combinations(n, k).comparator();
87 comp.compare(new int[] {1, 2, 5}, new int[] {0, 1, 2});
88 }
89
90 @Test(expected=MathIllegalArgumentException.class)
91 public void testLexicographicComparatorWrongIterate4() {
92 final int n = 5;
93 final int k = 3;
94 final Comparator<int[]> comp = new Combinations(n, k).comparator();
95 comp.compare(new int[] {1, 2, 4}, new int[] {-1, 1, 2});
96 }
97
98 @Test
99 public void testLexicographicComparator() {
100 final int n = 5;
101 final int k = 3;
102 final Comparator<int[]> comp = new Combinations(n, k).comparator();
103 Assert.assertEquals(1, comp.compare(new int[] {1, 2, 4},
104 new int[] {1, 2, 3}));
105 Assert.assertEquals(-1, comp.compare(new int[] {0, 1, 4},
106 new int[] {0, 2, 4}));
107 Assert.assertEquals(0, comp.compare(new int[] {1, 3, 4},
108 new int[] {1, 3, 4}));
109 }
110
111
112
113
114 @Test
115 public void testLexicographicComparatorUnsorted() {
116 final int n = 5;
117 final int k = 3;
118 final Comparator<int[]> comp = new Combinations(n, k).comparator();
119 Assert.assertEquals(1, comp.compare(new int[] {1, 4, 2},
120 new int[] {1, 3, 2}));
121 Assert.assertEquals(-1, comp.compare(new int[] {0, 4, 1},
122 new int[] {0, 4, 2}));
123 Assert.assertEquals(0, comp.compare(new int[] {1, 4, 3},
124 new int[] {1, 3, 4}));
125 }
126
127 @Test
128 public void testEmptyCombination() {
129 final Iterator<int[]> iter = new Combinations(12345, 0).iterator();
130 Assert.assertTrue(iter.hasNext());
131 final int[] c = iter.next();
132 Assert.assertEquals(0, c.length);
133 Assert.assertFalse(iter.hasNext());
134 }
135
136 @Test
137 public void testFullSetCombination() {
138 final int n = 67;
139 final Iterator<int[]> iter = new Combinations(n, n).iterator();
140 Assert.assertTrue(iter.hasNext());
141 final int[] c = iter.next();
142 Assert.assertEquals(n, c.length);
143
144 for (int i = 0; i < n; i++) {
145 Assert.assertEquals(i, c[i]);
146 }
147
148 Assert.assertFalse(iter.hasNext());
149 }
150
151
152
153
154
155
156
157
158 private void checkLexicographicIterator(Combinations c) {
159 final Comparator<int[]> comp = c.comparator();
160 final int n = c.getN();
161 final int k = c.getK();
162
163 int[] lastIterate = null;
164
165 long numIterates = 0;
166 for (int[] iterate : c) {
167 Assert.assertEquals(k, iterate.length);
168
169
170 if (lastIterate != null) {
171 Assert.assertTrue(comp.compare(iterate, lastIterate) == 1);
172 }
173
174
175 for (int i = 1; i < iterate.length; i++) {
176 Assert.assertTrue(iterate[i] > iterate[i - 1]);
177 }
178
179 lastIterate = iterate;
180 ++numIterates;
181 }
182
183
184 Assert.assertEquals(CombinatoricsUtils.binomialCoefficient(n, k),
185 numIterates);
186 }
187
188 @Test
189 public void testCombinationsIteratorFail() {
190 try {
191 new Combinations(4, 5).iterator();
192 Assert.fail("expecting MathIllegalArgumentException");
193 } catch (MathIllegalArgumentException ex) {
194
195 }
196
197 try {
198 new Combinations(-1, -2).iterator();
199 Assert.fail("expecting MathIllegalArgumentException");
200 } catch (MathIllegalArgumentException ex) {
201
202 }
203 }
204
205 @Test
206 public void testLexicographicIteratorUnreachable() {
207
208
209
210 try {
211 Class<?> lexicographicIteratorClass = null;
212 for (Class<?> c : Combinations.class.getDeclaredClasses()) {
213 if (c.getCanonicalName().endsWith(".LexicographicIterator")) {
214 lexicographicIteratorClass = c;
215 }
216 }
217 Constructor<?> ctr = lexicographicIteratorClass.getDeclaredConstructor(Integer.TYPE, Integer.TYPE);
218 Method hasNext = lexicographicIteratorClass.getDeclaredMethod("hasNext");
219 Method next = lexicographicIteratorClass.getDeclaredMethod("next");
220 Method remove = lexicographicIteratorClass.getDeclaredMethod("remove");
221 Assert.assertFalse((Boolean) hasNext.invoke(ctr.newInstance(3, 0)));
222 Assert.assertFalse((Boolean) hasNext.invoke(ctr.newInstance(3, 3)));
223 Assert.assertTrue((Boolean) hasNext.invoke(ctr.newInstance(3, 2)));
224 try {
225 next.invoke(ctr.newInstance(3, 0));
226 Assert.fail("an exception should have been thrown");
227 } catch (InvocationTargetException ite) {
228 Assert.assertTrue(ite.getCause() instanceof NoSuchElementException);
229 }
230 try {
231 remove.invoke(ctr.newInstance(3, 2));
232 Assert.fail("an exception should have been thrown");
233 } catch (InvocationTargetException ite) {
234 Assert.assertTrue(ite.getCause() instanceof UnsupportedOperationException);
235 }
236 } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException |
237 InvocationTargetException | InstantiationException e) {
238 Assert.fail(e.getLocalizedMessage());
239 }
240 }
241
242 @Test
243 public void testSingletonIteratorUnreachable() {
244
245 try {
246 Class<?> singletonIteratorClass = null;
247 for (Class<?> c : Combinations.class.getDeclaredClasses()) {
248 if (c.getCanonicalName().endsWith(".SingletonIterator")) {
249 singletonIteratorClass = c;
250 }
251 }
252 Constructor<?> ctr = singletonIteratorClass.getDeclaredConstructor(Integer.TYPE);
253 Method hasNext = singletonIteratorClass.getDeclaredMethod("hasNext");
254 Method next = singletonIteratorClass.getDeclaredMethod("next");
255 Method remove = singletonIteratorClass.getDeclaredMethod("remove");
256 Object iterator = ctr.newInstance(3);
257 Assert.assertTrue((Boolean) hasNext.invoke(iterator));
258 int[] ret = (int[]) next.invoke(iterator);
259 Assert.assertEquals(3, ret.length);
260 Assert.assertEquals(0, ret[0]);
261 Assert.assertEquals(1, ret[1]);
262 Assert.assertEquals(2, ret[2]);
263 Assert.assertFalse((Boolean) hasNext.invoke(iterator));
264 try {
265 next.invoke(iterator);
266 Assert.fail("an exception should have been thrown");
267 } catch (InvocationTargetException ite) {
268 Assert.assertTrue(ite.getCause() instanceof NoSuchElementException);
269 }
270 try {
271 remove.invoke(iterator);
272 Assert.fail("an exception should have been thrown");
273 } catch (InvocationTargetException ite) {
274 Assert.assertTrue(ite.getCause() instanceof UnsupportedOperationException);
275 }
276 } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException |
277 InvocationTargetException | InstantiationException e) {
278 Assert.fail(e.getLocalizedMessage());
279 }
280 }
281
282 }