diff --git a/src/datastructures/worklists/MinFourHeap.java b/src/datastructures/worklists/MinFourHeap.java index bb02bd635d57d268aa12da0d8dcaf8c3fc5254b6..bf285ead481f535c08330a8565188eff13db6b35 100644 --- a/src/datastructures/worklists/MinFourHeap.java +++ b/src/datastructures/worklists/MinFourHeap.java @@ -3,15 +3,17 @@ package datastructures.worklists; import cse332.exceptions.NotYetImplementedException; import cse332.interfaces.worklists.PriorityWorkList; +import java.util.Comparator; + /** * See cse332/interfaces/worklists/PriorityWorkList.java * for method specifications. */ -public class MinFourHeap<E extends Comparable<E>> extends PriorityWorkList<E> { +public class MinFourHeap<E> extends PriorityWorkList<E> { /* Do not change the name of this field; the tests rely on it to work correctly. */ private E[] data; - public MinFourHeap() { + public MinFourHeap(Comparator<E> c) { throw new NotYetImplementedException(); } diff --git a/src/datastructures/worklists/MinFourHeapComparable.java b/src/datastructures/worklists/MinFourHeapComparable.java new file mode 100644 index 0000000000000000000000000000000000000000..05d337349c7f7aead78f08e27f178fa0e0e1b95b --- /dev/null +++ b/src/datastructures/worklists/MinFourHeapComparable.java @@ -0,0 +1,47 @@ +package datastructures.worklists; + +import cse332.exceptions.NotYetImplementedException; +import cse332.interfaces.worklists.PriorityWorkList; + +/** + * See cse332/interfaces/worklists/PriorityWorkList.java + * for method specifications. + */ +public class MinFourHeapComparable<E extends Comparable<E>> extends PriorityWorkList<E> { + /* Do not change the name of this field; the tests rely on it to work correctly. */ + private E[] data; + + public MinFourHeapComparable() { + throw new NotYetImplementedException(); + } + + @Override + public boolean hasWork() { + throw new NotYetImplementedException(); + } + + @Override + public void add(E work) { + throw new NotYetImplementedException(); + } + + @Override + public E peek() { + throw new NotYetImplementedException(); + } + + @Override + public E next() { + throw new NotYetImplementedException(); + } + + @Override + public int size() { + throw new NotYetImplementedException(); + } + + @Override + public void clear() { + throw new NotYetImplementedException(); + } +} diff --git a/src/tests/gitlab/ckpt1/Ckpt1Tests.java b/src/tests/gitlab/ckpt1/Ckpt1Tests.java index 0bc8b47cdc1b5af9b1960bcbe1da5225f64b87a8..3e0cdbb84e86aa973ef5ebe00d373423f29905ed 100644 --- a/src/tests/gitlab/ckpt1/Ckpt1Tests.java +++ b/src/tests/gitlab/ckpt1/Ckpt1Tests.java @@ -1,13 +1,14 @@ package tests.gitlab.ckpt1; import datastructures.worklists.MinFourHeap; +import datastructures.worklists.MinFourHeapComparable; import org.junit.runner.RunWith; import org.junit.runners.Suite; @RunWith(Suite.class) @Suite.SuiteClasses({ - MinFourHeap.class, + MinFourHeapComparable.class, MoveToFrontListTests.class, CircularArrayComparatorTests.class }) diff --git a/src/tests/gitlab/ckpt1/MinFourHeapComparableTests.java b/src/tests/gitlab/ckpt1/MinFourHeapComparableTests.java new file mode 100644 index 0000000000000000000000000000000000000000..0073cb721f1973a0c4e9d3fb607a5fd13cb45242 --- /dev/null +++ b/src/tests/gitlab/ckpt1/MinFourHeapComparableTests.java @@ -0,0 +1,170 @@ +package tests.gitlab.ckpt1; + +import cse332.interfaces.worklists.PriorityWorkList; +import datastructures.worklists.MinFourHeapComparable; +import org.junit.Before; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.PriorityQueue; +import java.util.Queue; +import java.util.Random; + +import static org.junit.Assert.*; + +public class MinFourHeapComparableTests extends WorklistGradingTests { + private static Random RAND; + + @Before + public void init() { + STUDENT_STR = new MinFourHeapComparable<>(); + STUDENT_DOUBLE = new MinFourHeapComparable<>(); + STUDENT_INT = new MinFourHeapComparable<>(); + RAND = new Random(42); + } + + @Test(timeout = 3000) + public void testHeapWith5Items() { + PriorityWorkList<String> heap = new MinFourHeapComparable<>(); + String[] tests = { "a", "b", "c", "d", "e" }; + for (int i = 0; i < 5; i++) { + String str = tests[i] + "a"; + heap.add(str); + } + + for (int i = 0; i < 5; i++) { + String str_heap = heap.next(); + String str = (char) ('a' + i) + "a"; + assertEquals(str, str_heap); + } + } + + @Test(timeout = 3000) + public void testOrderingDoesNotMatter() { + PriorityWorkList<String> ordered = new MinFourHeapComparable<>(); + PriorityWorkList<String> reversed = new MinFourHeapComparable<>(); + PriorityWorkList<String> random = new MinFourHeapComparable<>(); + + addAll(ordered, new String[]{"a", "b", "c", "d", "e"}); + addAll(reversed, new String[]{"e", "d", "c", "b", "a"}); + addAll(random, new String[]{"d", "b", "c", "e", "a"}); + + assertTrue(isSame("a", ordered.peek(), reversed.peek(), random.peek())); + assertTrue(isSame("a", ordered.next(), reversed.next(), random.next())); + assertTrue(isSame("b", ordered.next(), reversed.next(), random.next())); + + addAll(ordered, new String[] {"a", "a", "b", "c", "z"}); + addAll(reversed, new String[] {"z", "c", "b", "a", "a"}); + addAll(random, new String[] {"c", "z", "a", "b", "a"}); + + String[] expected = new String[] {"a", "a", "b", "c", "c", "d", "e", "z"}; + for (String e : expected) { + assertTrue(isSame(e, ordered.peek(), reversed.peek(), random.peek())); + assertTrue(isSame(e, ordered.next(), reversed.next(), random.next())); + } + } + + private boolean isSame(String... args) { + String first = args[0]; + for (String arg : args) { + if (!first.equals(arg)) { + return false; + } + } + return true; + } + + @Test(timeout = 3000) + public void testHugeHeap() { + PriorityWorkList<String> heap = new MinFourHeapComparable<>(); + int n = 10000; + + // Add them + for (int i = 0; i < n; i++) { + String str = String.format("%05d", i * 37 % n); + heap.add(str); + } + // Delete them all + for (int i = 0; i < n; i++) { + String s = heap.next(); + assertEquals(i , Integer.parseInt(s)); + } + } + + @Test(timeout = 3000) + public void testWithCustomComparable() { + PriorityWorkList<Coordinate> student = new MinFourHeapComparable<>(); + Queue<Coordinate> reference = new PriorityQueue<>(); + + for (int i = 0; i < 10000; i++) { + Coordinate coord = new Coordinate(RAND.nextInt(10000) - 5000, RAND.nextInt(10000) - 5000); + student.add(coord); + reference.add(coord); + } + assertEquals(reference.size(), student.size()); + + while (!reference.isEmpty()) { + assertEquals(reference.peek() , student.peek()); + assertEquals(reference.remove() , student.next()); + } + } + + public static class Coordinate implements Comparable<Coordinate> { + private int x; + private int y; + + public Coordinate(int x, int y) { + this.x = x; + this.y = y; + } + + // What exactly this comparable method is doing is somewhat arbitrary. + public int compareTo(Coordinate other) { + if (this.x != other.x) { + return this.x - other.x; + } else { + return this.y - other.y; + } + } + } + + @Test(timeout = 3000) + public void checkStructure() { + PriorityWorkList<Integer> heap = new MinFourHeapComparable<>(); + addAll(heap, new Integer[] {10, 10, 15, 1, 17, 16, 100, 101, 102, 103, 105, 106, 107, 108}); + + Object[] heapData = getField(heap, "data"); + String heapStr = Arrays.toString(heapData); + String heapExp = "[1, 10, 15, 10, 17, 16, 100, 101, 102, 103, 105, 106, 107, 108"; + + heap.next(); + heap.next(); + heap.next(); + + Object[] heapData2 = getField(heap, "data"); + String heapStr2 = Arrays.toString(heapData2); + String heapExp2 = "[15, 16, 103, 107, 17, 108, 100, 101, 102, 106, 105,"; + + assertTrue(heapStr.contains(heapExp)); + assertTrue(heapStr2.contains(heapExp2)); + } + + protected <T> T getField(Object o, String fieldName) { + try { + Field field = o.getClass().getSuperclass().getDeclaredField(fieldName); + field.setAccessible(true); + Object f = field.get(o); + return (T) f; + } catch (Exception var6) { + try { + Field field = o.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + Object f = field.get(o); + return (T) f; + } catch (Exception var5) { + return null; + } + } + } +} diff --git a/src/tests/gitlab/ckpt2/Ckpt2Tests.java b/src/tests/gitlab/ckpt2/Ckpt2Tests.java index 71e00cc118646ba2fac84603e60a533c99dfd4b0..7094e157928def380bfbb7f8a47a0b137affc4bb 100644 --- a/src/tests/gitlab/ckpt2/Ckpt2Tests.java +++ b/src/tests/gitlab/ckpt2/Ckpt2Tests.java @@ -12,7 +12,8 @@ import org.junit.runners.Suite; QuickSortTests.class, TopKSortTests.class, HeapSortTests.class, - HashTrieMapTests.class + HashTrieMapTests.class, + MinFourHeapTests.class }) public class Ckpt2Tests { diff --git a/src/tests/gitlab/ckpt1/MinFourHeapTests.java b/src/tests/gitlab/ckpt2/MinFourHeapTests.java similarity index 87% rename from src/tests/gitlab/ckpt1/MinFourHeapTests.java rename to src/tests/gitlab/ckpt2/MinFourHeapTests.java index 76d93630798d508b5541cb0b5d1b9087f7c88828..2b07726b653af0d3744fa1a2e085102e4067cc99 100644 --- a/src/tests/gitlab/ckpt1/MinFourHeapTests.java +++ b/src/tests/gitlab/ckpt2/MinFourHeapTests.java @@ -1,4 +1,5 @@ -package tests.gitlab.ckpt1; +package tests.gitlab.ckpt2; + import cse332.interfaces.worklists.PriorityWorkList; import datastructures.worklists.MinFourHeap; @@ -19,15 +20,15 @@ public class MinFourHeapTests extends WorklistGradingTests { @Before public void init() { - STUDENT_STR = new MinFourHeap<>(); - STUDENT_DOUBLE = new MinFourHeap<>(); - STUDENT_INT = new MinFourHeap<>(); + STUDENT_STR = new MinFourHeap<>(String::compareTo); + STUDENT_DOUBLE = new MinFourHeap<>(Double::compareTo); + STUDENT_INT = new MinFourHeap<>(Integer::compareTo); RAND = new Random(42); } @Test(timeout = 3000) public void testHeapWith5Items() { - PriorityWorkList<String> heap = new MinFourHeap<>(); + PriorityWorkList<String> heap = new MinFourHeap<>(String::compareTo); String[] tests = { "a", "b", "c", "d", "e" }; for (int i = 0; i < 5; i++) { String str = tests[i] + "a"; @@ -43,9 +44,9 @@ public class MinFourHeapTests extends WorklistGradingTests { @Test(timeout = 3000) public void testOrderingDoesNotMatter() { - PriorityWorkList<String> ordered = new MinFourHeap<>(); - PriorityWorkList<String> reversed = new MinFourHeap<>(); - PriorityWorkList<String> random = new MinFourHeap<>(); + PriorityWorkList<String> ordered = new MinFourHeap<>(String::compareTo); + PriorityWorkList<String> reversed = new MinFourHeap<>(String::compareTo); + PriorityWorkList<String> random = new MinFourHeap<>(String::compareTo); addAll(ordered, new String[]{"a", "b", "c", "d", "e"}); addAll(reversed, new String[]{"e", "d", "c", "b", "a"}); @@ -78,7 +79,7 @@ public class MinFourHeapTests extends WorklistGradingTests { @Test(timeout = 3000) public void testHugeHeap() { - PriorityWorkList<String> heap = new MinFourHeap<>(); + PriorityWorkList<String> heap = new MinFourHeap<>(String::compareTo); int n = 10000; // Add them @@ -95,7 +96,7 @@ public class MinFourHeapTests extends WorklistGradingTests { @Test(timeout = 3000) public void testWithCustomComparable() { - PriorityWorkList<Coordinate> student = new MinFourHeap<>(); + PriorityWorkList<Coordinate> student = new MinFourHeap<>(Coordinate::compareTo); Queue<Coordinate> reference = new PriorityQueue<>(); for (int i = 0; i < 10000; i++) { @@ -132,7 +133,7 @@ public class MinFourHeapTests extends WorklistGradingTests { @Test(timeout = 3000) public void checkStructure() { - PriorityWorkList<Integer> heap = new MinFourHeap<>(); + PriorityWorkList<Integer> heap = new MinFourHeap<>(Integer::compareTo); addAll(heap, new Integer[] {10, 10, 15, 1, 17, 16, 100, 101, 102, 103, 105, 106, 107, 108}); Object[] heapData = getField(heap, "data"); @@ -169,3 +170,4 @@ public class MinFourHeapTests extends WorklistGradingTests { } } } +