diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.classpath new file mode 100644 index 0000000..8e3d409 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.project b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.project new file mode 100644 index 0000000..fa15deb --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.project @@ -0,0 +1,17 @@ + + + Assn08_MutationArrayLists + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/Deque.java b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/Deque.java new file mode 100644 index 0000000..e2c24d5 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/Deque.java @@ -0,0 +1,188 @@ +// +--------------------+ +// | Deque | +// +--------------------+ +// | Sentinel header |-+ +// +--------------------+ | +// | +// +--------------------------+ +// | +// | +// | +---------------+ +// | | ANode | +// | +---------------+ +// | | ANode next | +// | | ANode prev | +// | +---------------+ +// | /_\ /_\ +// | | | +// | +----+ | +// V | | +//+-------------+ +---------+ +//| Sentinel | | Node | +//+-------------+ +---------+ +//+-------------+ | T data | +// +---------+ +// +// +//interface IPred { +// boolean apply(T t); +//} +// +//class MatchToData implements IPred { +// T match; +// MatchToData(T match) { +// this.match = match; +// } +// public boolean apply(T t) { +// return t.equals(match); +// } +//} + +abstract class ANode { + ANode next; + ANode prev; + ANode(ANode next, ANode prev) { + this.next = next; + this.prev = prev; + } + // inserts this node between before and after nodes + void insertBetween(ANode next, ANode prev) { + if (prev == null || next == null) { + throw new IllegalArgumentException("Cannot assign next or prev to null"); + } + prev.next = this; + this.prev = prev; + this.next = next; + next.prev = this; + } + // inserts this node after provided node + void insertAfter(ANode prev) { + this.insertBetween(prev.next, prev); + } + // inserts this node before provided node + void insertBefore(ANode next) { + this.insertBetween(next, next.prev); + } + int size() { + if (this.next == null) { + return 0; + } else { + return this.next.sizeHelper(0); + } + } + abstract void remove(); + abstract int sizeHelper(int cnt); + abstract ANode find(IPred p); +} + +class Sentinel extends ANode { + Sentinel(ANode next, ANode prev) { + super(next, prev); + } + Sentinel() { + this(null, null); + this.insertBetween(this, this); + } + int sizeHelper(int cnt) { + return cnt; + } + ANode removeNext() { + if (this.next == this) { + throw new RuntimeException("Cannot remove item from empty list"); + } + ANode r = this.next; + this.next.remove(); + return r; + } + ANode removePrev() { + if (this.next == this) { + throw new RuntimeException("Cannot remove item from empty list"); + } + ANode r = this.prev; + this.prev.remove(); + return r; + } + void remove() { + throw new RuntimeException("Cannot remove sentinel node"); + } + ANode find(IPred p) { + return this; + } +} + +class Node extends ANode { + T data; + Node(T data, ANode next, ANode prev) { + super(next, prev); + this.data = data; + this.insertBetween(prev, next); + } + Node(T data) { + super(null, null); + this.data = data; + } + int sizeHelper(int cnt) { + return this.next.sizeHelper(cnt + 1); + } + void remove() { + this.prev.next = this.next; + this.next.prev = this.prev; + } + ANode find(IPred pred) { + if (pred.apply(this.data)) { + return this; + } else { + return this.next.find(pred); + } + } +} + +class Deque { + Sentinel header; + Deque(Sentinel header) { + this.header = header; + } + Deque() { + this(new Sentinel()); + } + // returns the number of nodes in a list Deque, not including the header node + int size() { + return this.header.size(); // + } + // inserts node n at the front of the list. + void addAtHead(Node n) { + n.insertAfter(this.header); + } + // inserts node n at the end of the list. + void addAtTail(Node n) { + n.insertBefore(this.header); + } + // returns and removes the first node from this Deque. + // Throw a RuntimeException if an attempt is made to remove + // from an empty list. + ANode removeFromHead() { + return this.header.removeNext(); + } + // returns and removes the last node from this Deque. + // Throw a RuntimeException if an attempt is made to remove + // from an empty list. + ANode removeFromTail() { + return this.header.removePrev(); + } + // returns the first node in this Deque where the predicate returns true + // if nothing is found return header + ANode find(IPred p) { + // start at first node so when we hit sentinel we return sentinel + return this.header.next.find(p); + } + // removes the given node from this Deque + // If the given node is the Sentinel header, the method does nothing + void removeNode(Node n) { + ANode found = this.find(new MatchToData(n.data)); + // we dont want to remove the sentinel node + if (found instanceof Sentinel) { + return; + } + found.remove(); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/ExamplesDeque.java b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/ExamplesDeque.java new file mode 100644 index 0000000..6d6bed5 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/ExamplesDeque.java @@ -0,0 +1,217 @@ +import tester.Tester; +class ExamplesDeque { + + Deque dq0; + Deque dq1; + Deque dq2; + Sentinel sent0; + Sentinel sent1; + Sentinel sent2; + Node nabc; + Node nbcd; + Node ncde; + Node ndef; + Node nHello; + Node nWorld; + Node nWelcome; + Node nTo; + Node nHTDP2; + + void testConstrutor(Tester t) { + nabc = new Node("abc"); + t.checkExpect(nabc.next, null); + t.checkExpect(nabc.prev, null); + sent1 = new Sentinel(); + t.checkExpect(sent1.next, sent1); + t.checkExpect(sent1.prev, sent1); + dq0 = new Deque(); + t.checkExpect(dq0.header, new Sentinel()); + dq1 = new Deque(sent1); + t.checkExpect(dq1.header, sent1); + + nbcd = new Node("bcd", sent1, sent1); + t.checkExpect(sent1.prev, nbcd); + t.checkExpect(sent1.next, nbcd); + t.checkExpect(nbcd.prev, sent1); + t.checkExpect(nbcd.next, sent1); + + sent0 = new Sentinel(); + Node null1 = null; //needed to suppress warning in CheckException() + t.checkException( + new IllegalArgumentException("Cannot assign next or prev to null"), + sent0, + "insertBetween", + null1, + null1); + } + + void testInsert(Tester t) { + sent1 = new Sentinel(); + nabc = new Node("abc"); + nbcd = new Node("bcd"); + ncde = new Node("cde"); + ndef = new Node("def"); + + nabc.insertBetween(sent1, sent1); + t.checkExpect(nabc.next, sent1); + t.checkExpect(nabc.prev, sent1); + t.checkExpect(sent1.next, nabc); + t.checkExpect(sent1.prev, nabc); + + nbcd.insertAfter(nabc); + t.checkExpect(sent1.next, nabc); + t.checkExpect(nabc.prev, sent1); + t.checkExpect(nabc.next, nbcd); + t.checkExpect(nbcd.prev, nabc); + t.checkExpect(nbcd.next, sent1); + t.checkExpect(sent1.prev, nbcd); + + ncde.insertBefore(sent1); + t.checkExpect(sent1.next, nabc); + t.checkExpect(nabc.prev, sent1); + t.checkExpect(nabc.next, nbcd); + t.checkExpect(nbcd.prev, nabc); + t.checkExpect(nbcd.next, ncde); + t.checkExpect(ncde.prev, nbcd); + t.checkExpect(ncde.next, sent1); + t.checkExpect(sent1.prev, ncde); + } + + void reset() { + dq0 = new Deque(); // empty dq + sent0 = new Sentinel(); // empty sentinel + + // +---------------+ + // | dq1 | + // +---------------+ + // | header ----------+ + // +---------------+ | + // +--------------+ + // | + // v + // +------------------+ + //+---------->| sent1 |<-------------------------------------------+ + //| +------------------+ | + //| +---- next | | + //| | | prev ------------------------------------------------+ | + //| | +------------------+ | | + //| | | | + //| v v | + //| +--------------+ +--------------+ +--------------+ +--------------+ | + //| | nabc | | nbcd | | ncde | | ndef | | + //| +--------------+ +--------------+ +--------------+ +--------------+ | + //| | "abc" | | "bcd" | | "cde" | | "def" | | + //| | next ----------->| next ----------->| next ----------->| next ----------+ + //+-- prev |<--- prev |<--- prev |<--- prev | + //+--------------+ +--------------+ +--------------+ +--------------+ + + sent1 = new Sentinel(); + nabc = new Node("abc"); + nbcd = new Node("bcd"); + ncde = new Node("cde"); + ndef = new Node("def"); + nabc.insertAfter(sent1); + nbcd.insertAfter(nabc); + ncde.insertAfter(nbcd); + ndef.insertAfter(ncde); + dq1 = new Deque(sent1); // provided dq + + sent2 = new Sentinel(); + nHello = new Node("Hello"); + nWorld = new Node("world"); + nWelcome = new Node("welcome"); + nTo = new Node("to"); + nHTDP2 = new Node("HTDP2"); + dq2 = new Deque(sent2); + } + void testAddAt(Tester t) { + reset(); + t.checkExpect(dq2.header.next, sent2); + dq2.addAtHead(nHello); + t.checkExpect(dq2.header.next, nHello); + t.checkExpect(dq2.header.prev, nHello); + dq2.addAtTail(nWorld); + t.checkExpect(dq2.header.next, nHello); + t.checkExpect(nHello.prev, sent2); + t.checkExpect(nHello.next, nWorld); + t.checkExpect(dq2.header.prev, nWorld); + } + void testRemoveAt(Tester t) { + reset(); + t.checkExpect(this.dq1.removeFromHead(), this.nabc); + t.checkExpect(this.sent1.next, this.nbcd); + t.checkExpect(this.nbcd.prev, sent1); + t.checkExpect(this.dq1.removeFromTail(), this.ndef); + t.checkExpect(this.sent1.prev, this.ncde); + t.checkExpect(this.ncde.next, this.sent1); + + t.checkException( + new RuntimeException("Cannot remove item from empty list"), + sent0, + "removeNext"); + t.checkException( + new RuntimeException("Cannot remove item from empty list"), + sent0, + "removePrev"); + t.checkException( + new RuntimeException("Cannot remove sentinel node"), + sent0, + "remove"); + } + void testSize(Tester t) { + reset(); + t.checkExpect(dq0.size(), 0); + t.checkExpect(dq1.size(), 4); + + t.checkExpect(sent2.size(), 0); + t.checkExpect(dq2.size(), 0); + dq2.addAtHead(nHello); + t.checkExpect(dq2.size(), 1); + dq2.addAtHead(nWorld); + t.checkExpect(dq2.size(), 2); + dq2.addAtHead(nWelcome); + t.checkExpect(dq2.size(), 3); + dq2.addAtHead(nTo); + t.checkExpect(dq2.size(), 4); + dq2.addAtHead(nHTDP2); + t.checkExpect(dq2.size(), 5); + } + void testFind(Tester t) { + reset(); + t.checkExpect(dq0.find(new MatchToData("abc")), sent0); + t.checkExpect(dq1.find(new MatchToData("abc")), nabc); + t.checkExpect(dq1.find(new MatchToData("bcd")), nbcd); + t.checkExpect(dq1.find(new MatchToData("cde")), ncde); + t.checkExpect(dq1.find(new MatchToData("def")), ndef); + t.checkExpect(dq1.find(new MatchToData("cannotFind")), sent1); + } + void testRemoveNode(Tester t) { + reset(); + + // node not found so nothing happens + t.checkExpect(dq0.size(), 0); + dq0.removeNode(nabc); + t.checkExpect(dq0.header, sent0); + t.checkExpect(dq0.size(), 0); + + // remove first node + t.checkExpect(dq1.size(), 4); + dq1.removeNode(nabc); + t.checkExpect(dq1.size(), 3); + t.checkExpect(dq1.header.next, nbcd); + + // remove a middle node + reset(); + t.checkExpect(dq1.size(), 4); + dq1.removeNode(nbcd); + t.checkExpect(dq1.size(), 3); + t.checkExpect(nabc.next, ncde); + + // remove last node + reset(); + t.checkExpect(dq1.size(), 4); + dq1.removeNode(ndef); + t.checkExpect(dq1.size(), 3); + t.checkExpect(sent1.prev, ncde); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/PermExamples.java b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/PermExamples.java new file mode 100644 index 0000000..52390f3 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/PermExamples.java @@ -0,0 +1,57 @@ +import java.util.*; +import tester.Tester; +class ExamplesPerms { + ArrayList alphabet; + ArrayList testCode1; + ArrayList testCode2; + PermutationCode pCode1; + PermutationCode pCode2; + void init() { + alphabet = new ArrayList(Arrays.asList( + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'y', 'z')); + testCode1 = new ArrayList(Arrays.asList( + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z')); + testCode2 = new ArrayList(Arrays.asList( + 't', 'k', 'j', 'i', 'l', 'v', 'm', 'd', 'c', 'x', + 'w', 'q', 'u', 'f', 'b', 'y', 'o', 'a', 'z', 'h', + 'p', 'n', 's', 'r', 'g', 'e')); + pCode1 = new PermutationCode(this.testCode1); + pCode2 = new PermutationCode(314); + + } + + void testConstructor(Tester t) { + init(); + t.checkExpect(pCode1.code, testCode1); + t.checkExpect(pCode2.code, testCode2); + } + void testEncode(Tester t) { + init(); + t.checkExpect(pCode1.encode("hello world"), "HELLO WORLD"); + t.checkExpect(pCode2.alphabet, this.alphabet); + t.checkExpect(pCode2.code, this.testCode2); + t.checkExpect(pCode2.encode("hello world"), "dlqqb sbaqi"); + + t.checkException( + new RuntimeException("Could not encode given character: !"), + pCode1, + "encode", + "!"); + } + void testDecode(Tester t) { + init(); + t.checkExpect(pCode1.decode("HELLO WORLD"), "hello world"); + t.checkExpect(pCode2.decode("dlqqb sbaqi"), "hello world"); + + t.checkException( + new RuntimeException("Could not decode given character: !"), + pCode1, + "decode", + "!"); + + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/Permutation.java b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/Permutation.java new file mode 100644 index 0000000..7e7449a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Assn08_MutationArrayLists/src/Permutation.java @@ -0,0 +1,109 @@ +import java.util.*; + +interface IPred { + boolean apply(T t); +} + +class MatchToData implements IPred { + T match; + MatchToData(T match) { + this.match = match; + } + public boolean apply(T t) { + return t.equals(match); + } +} + +class ArrayUtils { + //Returns the index of the first item passing the predicate, + //or -1 if no such item was found + int find(ArrayList arr, IPred whichOne) { + return this.findHelp(arr, whichOne, 0); + } + // Returns the index of the first item passing the predicate at or after the + //given index, or -1 if no such such item was found + int findHelp(ArrayList arr, IPred whichOne, int index) { + if (index >= arr.size()) { + return -1; + } else if (whichOne.apply(arr.get(index))) { + return index; + } else { + return findHelp(arr, whichOne, index + 1); + } + } +} + +/** + * A class that defines a new permutation code, as well as methods for encoding + * and decoding of the messages that use this code. + */ +class PermutationCode { + // The original list of characters to be encoded + ArrayList alphabet = new ArrayList(Arrays.asList( + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', + 't', 'u', 'v', 'w', 'x', 'y', 'z')); + + ArrayList code = new ArrayList(26); + + // A random number generator + Random rand = new Random(); + + // Create a new instance of the encoder/decoder with a new permutation code + PermutationCode() { + this.code = this.initEncoder(rand); + } + PermutationCode(int seed) { + this.code = this.initEncoder(new Random(seed)); + } + // Create a new instance of the encoder/decoder with the given code + PermutationCode(ArrayList code) { + this.code = code; + } + + // Initialize the encoding permutation of the characters + ArrayList initEncoder(Random rand) { + ArrayList tempArray = new ArrayList(this.alphabet); + ArrayList resultArray = new ArrayList(); + int size = tempArray.size(); + for (int i = 0; i < size; i++) { + resultArray.add(tempArray.remove(rand.nextInt(size - i))); + } + return resultArray; + } + // produce an encoded String from the given String + String encode(String source) { + String r = ""; + ArrayUtils u = new ArrayUtils(); + for (int i = 0; i < source.length(); i++) { + if (source.charAt(i) == ' ') { + r = r + ' '; + } else { + int alphabetIdx = u.find(this.alphabet, new MatchToData(source.charAt(i))); + if (alphabetIdx < 0) { + throw new RuntimeException( + "Could not encode given character: " + source.charAt(i)); + } + r = r + code.get(alphabetIdx); + } + } + return r; + } + // produce a decoded String from the given String + String decode(String source) { + String r = ""; + ArrayUtils u = new ArrayUtils(); + for (int i = 0; i < source.length(); i++) { + if (source.charAt(i) == ' ') { + r = r + ' '; + } else { + int alphabetIdx = u.find(this.code, new MatchToData(source.charAt(i))); + if (alphabetIdx < 0) { + throw new RuntimeException("Could not decode given character: " + source.charAt(i)); + } + r = r + alphabet.get(alphabetIdx); + } + } + return r; + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.classpath new file mode 100644 index 0000000..8e3d409 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.project new file mode 100644 index 0000000..a264af4 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.project @@ -0,0 +1,17 @@ + + + Lect21&22_ArrayLists + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/src/ArrayLists.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/src/ArrayLists.java new file mode 100644 index 0000000..79b0026 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect21&22_ArrayLists/src/ArrayLists.java @@ -0,0 +1,344 @@ +import tester.Tester; +import java.util.ArrayList; +import java.util.Arrays; + +//Represents functions of signature A -> R, for some argument type A and +//result type R +interface IFunc { + R apply(A input); +} + +interface IFunc2 { + R apply(A1 arg1, A2 arg2); +} + +interface IPred { + boolean apply(T t); +} + +interface IComparator { + int compare(T t1, T t2); +} + +class DoubleInteger implements IFunc { + public Integer apply(Integer input) { + return input * 2; + } +} + +class SumIntegers implements IFunc2 { + public Integer apply(Integer arg1, Integer arg2) { + return arg1 + arg2; + } +} + +class AppendIntToString implements IFunc2 { + public String apply(Integer arg1, String arg2) { + return arg2 + arg1.toString(); + } +} + +class MatchString implements IPred { + String find; + MatchString(String find) { + this.find = find; + } + public boolean apply(String s) { + return this.find.compareTo(s) == 0; + } +} + +class CompareStrings implements IComparator { + public int compare(String s1, String s2) { + return s1.compareTo(s2); + } +} + +class CompareInts implements IComparator { + public int compare(Integer i1, Integer i2) { + return i1 - i2; + } +} + +class ArrayUtils { + // EFFECT: Exchanges the values at the given two indices in the given array + void swap(ArrayList arr, int index1, int index2) { + T oldValueAtIndex1 = arr.get(index1); + T oldValueAtIndex2 = arr.get(index2); + + arr.set(index2, oldValueAtIndex1); + arr.set(index1, oldValueAtIndex2); + } + ArrayList map(ArrayList arr, IFunc func) { + ArrayList result = new ArrayList(); + for (T t : arr) { + result.add(func.apply(t)); + } + return result; + } + U foldr(ArrayList arr, IFunc2 func, U base) { + U result = base; + for (T t : arr) { + result = func.apply(t, result); + } + return result; + } + U foldl(ArrayList arr, IFunc2 func, U base) { + return this.foldlHelp(arr, func, base, arr.size() - 1); + } + U foldlHelp(ArrayList source, IFunc2 func, U base, int curIdx) { + U result = base; + if (curIdx < 0) { + return result; + } else { + result = func.apply(source.get(curIdx), result); + return this.foldlHelp(source, func, result, curIdx - 1); + } + } + + U foldl_Loop(ArrayList arr, IFunc2 func, U base) { + ArrayList reversedList = this.reverseList(arr); + return this.foldr(reversedList, func, base); + } + ArrayList reverseList(ArrayList arr) { + ArrayList result = new ArrayList(); + for (T t : arr) { + result.add(0, t); + } + return result; + } + //Returns the index of the first item passing the predicate, + //or -1 if no such item was found + int find(ArrayList arr, IPred whichOne) { + return this.findHelp(arr, whichOne, 0); + } + // Returns the index of the first item passing the predicate at or after the + //given index, or -1 if no such such item was found + int findHelp(ArrayList arr, IPred whichOne, int index) { + if (index >= arr.size()) { + return -1; + } else if (whichOne.apply(arr.get(index))) { + return index; + } else { + return findHelp(arr, whichOne, index + 1); + } + } + // Returns the index of the target string in the given ArrayList, or -1 if the string is not found + //Assumes that the given ArrayList is sorted aphabetically + int binarySearch_v1(ArrayList strings, String target) { + return binarySearchHelp_v1(strings, target, 0, strings.size() - 1); + } + int binarySearchHelp_v1(ArrayList strings, String target, int lowIdx, int highIdx) { + int midIdx = (lowIdx + highIdx) / 2; + if (lowIdx > highIdx) { + return -1; // not found + } else if (target.compareTo(strings.get(midIdx)) == 0) { + return midIdx; // found it! + } else if (target.compareTo(strings.get(midIdx)) > 0) { + return this.binarySearchHelp_v1(strings, target, midIdx + 1, highIdx); // too low + } else { + return this.binarySearchHelp_v1(strings, target, lowIdx, midIdx - 1); // too high + } + } + //Returns the index of the target string in the given ArrayList, or -1 if the string is not found + //Assumes that the given ArrayList is sorted aphabetically + int binarySearch_v2(ArrayList strings, String target) { + return this.binarySearchHelp_v2(strings, target, 0, strings.size()); + } + //Returns the index of the target string in the given ArrayList, or -1 if the string is not found + //Assumes that the given ArrayList is sorted aphabetically + //Assumes that [lowIdx, highIdx) is a semi-open interval of indices + int binarySearchHelp_v2(ArrayList strings, String target, int lowIdx, int highIdx) { + int midIdx = (lowIdx + highIdx) / 2; + if (lowIdx >= highIdx) { + return -1; // not found + } else if (target.compareTo(strings.get(midIdx)) == 0) { + return midIdx; // found it! + } else if (target.compareTo(strings.get(midIdx)) > 0) { + return this.binarySearchHelp_v2(strings, target, midIdx + 1, highIdx); // too low + } else { + return this.binarySearchHelp_v2(strings, target, lowIdx, midIdx); // too high + } + } + int gen_binarySearch_v2(ArrayList arr, T target, IComparator comp) { + return this.gen_binarySearchHelp_v2(arr, target, comp, 0, arr.size()); + } + int gen_binarySearchHelp_v2(ArrayList arr, T target, IComparator comp, + int lowIdx, int highIdx) { + int midIdx = (lowIdx + highIdx) / 2; + if (lowIdx >= highIdx) { + return -1; + } else if (comp.compare(target, arr.get(midIdx)) == 0) { + return midIdx; + } else if (comp.compare(target, arr.get(midIdx)) > 0) { + return this.gen_binarySearchHelp_v2(arr, target, comp, midIdx + 1, highIdx); + } else { + return this.gen_binarySearchHelp_v2(arr, target, comp, lowIdx, midIdx); + } + } + // EFFECT: Sorts the given list of strings alphabetically + void sort(ArrayList arr) { + for (int idx = 0; idx < arr.size(); idx = idx + 1) { + int idxOfMinValue = this.findMinValue(arr, idx, idx + 1); + this.swap(arr, idx, idxOfMinValue); + } + } + int findMinValue(ArrayList arr, int minValIdx, int currIdx) { + if (currIdx >= arr.size()) { + return minValIdx; + } else if (arr.get(minValIdx).compareTo(arr.get(currIdx)) < 0) { + return this.findMinValue(arr, minValIdx, currIdx + 1); + } else { + return this.findMinValue(arr, currIdx, currIdx + 1); + } + } + + // returns an ArrayList consisting of one item from arr1, then one from arr2, alternating until one list is expended + // attaches rest of other list to the end; + ArrayList interleave(ArrayList arr1, ArrayList arr2) { + ArrayList r = new ArrayList(); + for (int idx = 0; idx < arr1.size() || idx < arr2.size(); idx++) { + if (idx >= arr1.size()) { + r.add(arr2.get(idx)); + } else if (idx >= arr2.size()) { + r.add(arr1.get(idx)); + } else { + r.add(arr1.get(idx)); + r.add(arr2.get(idx)); + } + } + return r; + } + // returns a new list containing the first, third, fifth ... items of the list, followed by the second, fourth, sixth ... items. + ArrayList unshuffle(ArrayList arr) { + ArrayList list1 = new ArrayList(); + ArrayList list2 = new ArrayList(); + for (int idx = 0; idx < arr.size(); idx++) { + if (idx % 2 == 0) { + list1.add(arr.get(idx)); + } else { + list2.add(arr.get(idx)); + } + } + list1.addAll(list2); + return list1; + } +} + +class ExampleArrayLists { + ArrayUtils u; + ArrayList nums; + ArrayList strings; + ArrayList nums_unsorted; + ArrayList strings_unsorted; + ArrayList numsInterleave; + ArrayList stringsInterleave; + + void init() { + u = new ArrayUtils(); + nums = new ArrayList(Arrays.asList(1, 2, 3)); + nums_unsorted = new ArrayList(Arrays.asList(2, 3, 1)); + + strings = new ArrayList( + Arrays.asList("apple", "banana", "cherry", "date", + "fig", "grape", "honeydew", "kiwi", "watermelon")); + strings_unsorted = new ArrayList( + Arrays.asList("cherry", "apple", "watermelon", "banana", + "fig", "date", "honeydew", "kiwi", "grape")); + + numsInterleave = new ArrayList(Arrays.asList(1, 4, 2, 5, 3, 6)); + stringsInterleave = new ArrayList( + Arrays.asList("apple", "artichoke", "banana", "broccoli", "cherry", "carrot", "date", + "fig", "grape", "honeydew", "kiwi", "watermelon")); + } + void testAdd(Tester t) { + ArrayList someStrings = new ArrayList(); + someStrings.add("First string"); + someStrings.add("Second string"); + t.checkExpect(someStrings.get(0), "First string"); + t.checkExpect(someStrings.get(1), "Second string"); + + // Insert this item at index 1, and move everything else back + someStrings.add(1, "Squeezed in"); + t.checkExpect(someStrings.get(0), "First string"); + t.checkExpect(someStrings.get(1), "Squeezed in"); + t.checkExpect(someStrings.get(2), "Second string"); + } + void testSwap(Tester t) { + ArrayList someStrings = new ArrayList(); + someStrings.add("Second string"); + someStrings.add("First string"); + + ArrayUtils u = new ArrayUtils(); + u.swap(someStrings, 0, 1); + + t.checkExpect(someStrings.get(0), "First string"); + t.checkExpect(someStrings.get(1), "Second string"); + } + void testMap(Tester t) { + init(); + t.checkExpect(this.u.map(this.nums, new DoubleInteger()), + new ArrayList(Arrays.asList(2, 4, 6))); + } + void testFold(Tester t) { + init(); + t.checkExpect(u.foldr(nums, new SumIntegers(), 0), 6); + t.checkExpect(u.foldr(nums, new AppendIntToString(), ""), "123"); + t.checkExpect(u.foldl(nums, new AppendIntToString(), ""), "321"); + t.checkExpect(u.foldl_Loop(nums, new AppendIntToString(), ""), "321"); + } + void testFind(Tester t) { + init(); + t.checkExpect(u.find(this.strings, new MatchString("apple")), 0); + t.checkExpect(u.find(this.strings, new MatchString("cherry")), 2); + t.checkExpect(u.find(this.strings, new MatchString("watermelon")), 8); + t.checkExpect(u.find(this.strings, new MatchString("notFound")), -1); + + t.checkExpect(u.binarySearch_v1(strings, "apple"), 0); + t.checkExpect(u.binarySearch_v1(this.strings, "cherry"), 2); + t.checkExpect(u.binarySearch_v1(this.strings, "watermelon"), 8); + t.checkExpect(u.binarySearch_v1(this.strings, "notFound"), -1); + + t.checkExpect(u.binarySearch_v2(strings, "apple"), 0); + t.checkExpect(u.binarySearch_v2(this.strings, "cherry"), 2); + t.checkExpect(u.binarySearch_v2(this.strings, "watermelon"), 8); + t.checkExpect(u.binarySearch_v2(this.strings, "notFound"), -1); + + CompareStrings compStr = new CompareStrings(); + t.checkExpect(u.gen_binarySearch_v2(strings, "apple", compStr), 0); + t.checkExpect(u.gen_binarySearch_v2(this.strings, "cherry", compStr), 2); + t.checkExpect(u.gen_binarySearch_v2(this.strings, "watermelon", compStr), 8); + t.checkExpect(u.gen_binarySearch_v2(this.strings, "notFound", compStr), -1); + + CompareInts compInt = new CompareInts(); + t.checkExpect(u.gen_binarySearch_v2(this.nums, 1, compInt), 0); + t.checkExpect(u.gen_binarySearch_v2(this.nums, 2, compInt), 1); + t.checkExpect(u.gen_binarySearch_v2(this.nums, 3, compInt), 2); + t.checkExpect(u.gen_binarySearch_v2(this.nums, 0, compInt), -1); + } + void testSort(Tester t) { + init(); + t.checkExpect(strings_unsorted.equals(strings), false); + u.sort(strings_unsorted); + t.checkExpect(strings_unsorted.equals(strings), true); + } + void testInterleave(Tester t) { + ArrayList moreNums = new ArrayList(Arrays.asList(4, 5, 6)); + ArrayList moreStrings = new ArrayList( + Arrays.asList("artichoke", "broccoli", "carrot")); + init(); + t.checkExpect(u.interleave(nums, moreNums), numsInterleave); + t.checkExpect(u.interleave(strings, moreStrings), stringsInterleave); + } + void testUnshuffle(Tester t) { + init(); + ArrayList numsUnshuffled = new ArrayList(Arrays.asList(1, 2, 3, 4, 5, 6)); + ArrayList stringsUnshuffled = new ArrayList( + Arrays.asList("apple", "banana", "cherry", "date", + "grape", "kiwi", "artichoke", "broccoli", + "carrot", "fig", "honeydew", "watermelon")); + + t.checkExpect(u.unshuffle(numsInterleave), numsUnshuffled); + t.checkExpect(u.unshuffle(stringsInterleave), stringsUnshuffled); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.classpath new file mode 100644 index 0000000..8e3d409 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.project new file mode 100644 index 0000000..b755ada --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.project @@ -0,0 +1,17 @@ + + + Lect23_ForEach&CountedLoops + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=11 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning +org.eclipse.jdt.core.compiler.release=enabled +org.eclipse.jdt.core.compiler.source=11