package org.sglj.util.struct; import java.util.Arrays; import java.util.Random; import junit.framework.Assert; import org.junit.Test; import org.sglj.util.struct.RangeMinimumQuery; public class RangeMinimumQueryTest { @Test public void test01() { // 0 1 2 3 4 5 6 7 8 9 RmqTester rmq = new RmqTester(new Integer[]{2, 4, 3, 1, 6, 7, 8, 9, 1, 7}); System.out.println(rmq); for (int d = 1; d < rmq.size(); ++d) { for (int i = 0; i + d < rmq.size(); ++i) { System.out.print("min [" + i + ", " + (i + d) + "): "); System.out.println(rmq.retrieveQuery(i, i + d)); } } System.out.println(rmq.retrieveQuery(2, 2)); } @Test public void test02() { RmqTester rmq = new RmqTester(new Integer[]{2, 4, 1, 3}); System.out.println(rmq); for (int d = 1; d < rmq.size(); ++d) { for (int i = 0; i + d < rmq.size(); ++i) { System.out.print("min [" + i + ", " + (i + d) + "): "); System.out.println(rmq.retrieveQuery(i, i + d)); } } System.out.println(rmq.retrieveQuery(3, 3)); } static Random RANDOM = new Random(); @Test public void testRandom01() { for (int i = 1; i < 20; ++i) randomTest(i, 1000, 100); } @Test public void testRandom02() { randomTest(100, 100, 0x3f3f3f3f); } static void randomTest(final int n, int q, final int maxVal) { RmqTester rmq = new RmqTester(n); for (int i = 0; i < n; ++i) { rmq.set(i, RANDOM.nextInt(maxVal)); } rmq.preprocess(); System.out.println(rmq); while (q-- > 0) { int from = RANDOM.nextInt(n), to = RANDOM.nextInt(n + 1); if (from > to) { int t = from; from = to; to = t; } rmq.retrieveQuery(from, to); } } private static class RmqTester extends RangeMinimumQuery<Integer, Integer> { int bf[]; public RmqTester(int capacity) { super(capacity); bf = new int[capacity]; Arrays.fill(bf, Integer.MAX_VALUE); } public RmqTester(Integer[] arr) { super(arr); bf = new int[arr.length]; for (int i = 0; i < arr.length; ++i) bf[i] = arr[i]; } @Override public Integer mergeCodomains(Integer a, Integer b) { return Math.min(a, b); } @Override protected Integer createIdentityData(Integer element) { return element == null ? Integer.MAX_VALUE : element; } @Override public void set(int index, Integer element) { super.set(index, element); if (bf != null) bf[index] = element; } @Override public Integer retrieveQuery(int fromIndex, int toIndex) { Integer actual = super.retrieveQuery(fromIndex, toIndex); int expected = Integer.MAX_VALUE; for (int i = fromIndex; i < toIndex; ++i) expected = Math.min(expected, bf[i]); Assert.assertEquals(expected, (int)actual); return actual; } } }