import java.util.*; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; // Write your solution in the first method in the LinkedIntList class! class LinkedIntList { private ListNode front; // Write Your solution here! public void expand() { } // Initializes a new empty list. public LinkedIntList() { front = null; } public LinkedIntList(List list) { if (list.isEmpty()) { front = null; } else { front = new ListNode(list.get(0)); ListNode current = front; for (int i = 1; i < list.size(); i++) { current.next = new ListNode(list.get(i)); current = current.next; } } } public boolean isEmpty() { return front == null; } // Returns a comma-separated String representation of this list. public String toString() { if (front == null) { return "[]"; } else { String result = "[" + front.data; ListNode current = front.next; while (current != null) { result += ", " + current.data; current = current.next; } result += "]"; return result; } } public boolean equalsList(List list) { ListNode current = front; for (int num : list) { if (current == null) { return false; } else if (current.data != num) { return false; } current = current.next; } return current == null; } public boolean endsWith(List list) { ListNode start = front; while (start != null) { ListNode current = start; for (int num : list) { if (current == null) { return false; } else if (current.data != num) { break; } current = current.next; } if (current == null) { return true; } start = start.next; } return false; } public boolean startsWith(List list) { ListNode current = front; for (int num : list) { if (current == null) { return false; } else if (current.data != num) { return false; } current = current.next; } return true; } public int getCounts(int n) { int count = 0; boolean inRun = true; ListNode current = front; while (current != null) { if (current.data == n) { if (inRun) { count++; } else { count = -1; } } else if (count > 0) { inRun = false; } current = current.next; } return count; } private class ListNode { public int data; public ListNode next; // Creates a ListNode with the specified integer data and next node. public ListNode(int data, ListNode next) { this.data = data; this.next = next; } // Creates a terminal ListNode with the specified integer data. public ListNode(int data) { this(data, null); } // Creates a terminal ListNode with 0 as its data. public ListNode() { this(0, null); } } } public class TestQ8 { public static String DIVIDER = "-----------------------------------------"; public static void main(String[] args) throws Exception { int score = 0; System.out.println("Testing..."); System.out.println(); score += testCase(new TestEmpty(), "Test Empty (requires loop attempt)", 1); score += testCase(new TestCreatesDuplicates(), "Test Creates Duplicates (Middle)", 2); score += testCase(new TestEnd(), "Test End", 2); score += testCase(new TestFront(), "Test Front (looking only at first nodes)", 3); score += testCase(new TestGeneral(), "Test General (looking at all but first nodes)", 4); System.out.print(score + " / 12 POINTS"); System.out.println(); System.exit(0); } public static int testCase(Callable test, String testName, int totalPoints) throws Exception { System.out.println(DIVIDER); System.out.println(testName); ExecutorService executor = Executors.newSingleThreadExecutor(); Future future = executor.submit(test); int points = 0; try { points = future.get(2, TimeUnit.SECONDS); System.out.println("Score: " + points + " / " + totalPoints); } catch (TimeoutException e) { points = 0; future.cancel(true); System.out.print("Score: 0 / " + totalPoints); System.out.println(" TIMEOUT"); } System.out.println(DIVIDER); System.out.println(); executor.shutdownNow(); return points; } private static abstract class Test { public boolean test(List list, List expected) { return test(list, expected, false); } public boolean test(List list, List expected, boolean ignoreFront) { LinkedIntList linkedList = new LinkedIntList(list); try { linkedList.expand(); if (ignoreFront && linkedList.endsWith(expected)) { return true; } else if (linkedList.equalsList(expected)) { return true; } else { System.out.println(" expected: " + expected); System.out.println(" actual : " + linkedList); } } catch (NullPointerException e) { System.out.println("NullPointer!"); } return false; } public boolean testFront(List list, List expected) { LinkedIntList linkedList = new LinkedIntList(list); try { linkedList.expand(); if (linkedList.startsWith(expected)) { return true; } else { System.out.println(" expected: " + expected); System.out.println(" actual : " + linkedList); } } catch (NullPointerException e) { System.out.println("NullPointer!"); } return false; } public boolean testCounts(List list, int count, int value) { return testCounts(list, count, value, false); } public boolean testCounts(List list, int count, int value, boolean lenient) { LinkedIntList linkedList = new LinkedIntList(list); try { linkedList.expand(); int actualCount = linkedList.getCounts(value); if (count == actualCount) { return true; } else if (lenient && (actualCount + 1 == count || actualCount - 1 == count)) { return true; } else { System.out.println(" actual : " + linkedList); System.out.println(" expected " + count + " " + value + "'s"); } } catch (NullPointerException e) { System.out.println("NullPointer!"); } return false; } } private static class TestEmpty extends Test implements Callable { @Override public Integer call() throws Exception { return test(Arrays.asList(), Arrays.asList()) ? 1 : 0; } } private static class TestEnd extends Test implements Callable { @Override public Integer call() throws Exception { boolean correct = test(Arrays.asList(1, 5, 3, 8, 4, 2), Arrays.asList(8, 8, 8, 2, 2, 2, 2), true) && testCounts(Arrays.asList(1, 5, 3, 8, 4, 2), 3, 8); return correct ? 2 : 0; } } private static class TestCreatesDuplicates extends Test implements Callable { @Override public Integer call() throws Exception { int points = 0; points += testCounts(Arrays.asList(1, 5, 4, 10, 3, 8), 4, 10, true) ? 1 : 0; points += testCounts(Arrays.asList(1, 5, 4, 10, 3, 8), 4, 10) ? 1 : 0; return points; } } private static class TestFront extends Test implements Callable { @Override public Integer call() throws Exception { boolean correct = testFront(Arrays.asList(1, 4, 3, 8), Arrays.asList(4)) && testCounts(Arrays.asList(1, 4, 3, 8), 1, 4) && testFront(Arrays.asList(5, 4, 3, 8), Arrays.asList(4, 4, 4, 4, 4)) && testCounts(Arrays.asList(5, 4, 3, 8), 5, 4); return correct ? 3 : 0; } } private static class TestGeneral extends Test implements Callable { @Override public Integer call() throws Exception { int points = 0; points += test(Arrays.asList(2, 5, 1, 6, 3, 7, 3, 8, 1, 5, 4, 2), Arrays.asList(6, 7, 7, 7, 8, 8, 8, 5, 2, 2, 2, 2), true) ? 4 : 0; return points; } } }