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