diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/src/ArrayLists.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/src/ArrayLists.java new file mode 100644 index 0000000..b05a6f7 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/src/ArrayLists.java @@ -0,0 +1,380 @@ +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 IntToString implements IFunc { + public String apply(Integer input) { + return input.toString(); + } +} + +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; + } + ArrayList buildList(int n, IFunc func) { + ArrayList resultArray = new ArrayList(); + for (int i = 0; i < n; i++) { + resultArray.add(func.apply(i)); + } + return resultArray; + } + //Capitalizes the titles of all books in the given ArrayList + void capitalizeTitles(ArrayList books) { + for (Book b : books) { + b.capitalizeTitle(); + } + } +} + +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); + } + void testBuildList(Tester t) { + init(); + t.checkExpect(u.buildList(5, new IntToString()), + new ArrayList(Arrays.asList("0", "1", "2", "3", "4"))); + } + void testCapTitles(Tester t) { + Book htdpLow = new Book("htDP", "MF", 0.0, 2014); + Book hpLow = new Book("hp", "JKR", 9000.00, 2015); + Book gatsbyLow = new Book("the great gatsby", "FSF", 15.99, 1930); + Book htdpUp = new Book("HTDP", "MF", 0.0, 2014); + Book hpUp = new Book("HP", "JKR", 9000.00, 2015); + Book gatsbyUp = new Book("THE GREAT GATSBY", "FSF", 15.99, 1930); + ArrayList bookList = new ArrayList(Arrays.asList( + htdpLow, hpLow, gatsbyLow)); + ArrayList bookListUp = new ArrayList(Arrays.asList( + htdpUp, hpUp, gatsbyUp)); + u.capitalizeTitles(bookList); + t.checkExpect(bookList, bookListUp); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/src/Books.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/src/Books.java new file mode 100644 index 0000000..5e317d6 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect23_ForEach&CountedLoops/src/Books.java @@ -0,0 +1,27 @@ +class Book { + String name; + String author; + double price; + int year; + Book(String name, String author, double price, int year) { + this.name = name; + this.author = author; + this.price = price; + this.year = year; + } + double getPrice() { + return this.price; + } + // to return the discounted price of this book given the discount rate + double discount(double rate) { + return this.price - (rate * this.price); + } + // to return a new book with the same author and name as this book, + // but with price discounted at the given rate + Book discountedBook(double rate) { + return new Book(this.name, this.author, this.discount(rate), this.year); + } + void capitalizeTitle() { + this.name = this.name.toUpperCase(); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.classpath new file mode 100644 index 0000000..8e3d409 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.project new file mode 100644 index 0000000..936b386 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.project @@ -0,0 +1,17 @@ + + + Lect24_WhileLoops + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.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/Lect24_WhileLoops/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/.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/Lect24_WhileLoops/src/ArrayLists.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/src/ArrayLists.java new file mode 100644 index 0000000..3fd0ad5 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/src/ArrayLists.java @@ -0,0 +1,372 @@ +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 IntToString implements IFunc { + public String apply(Integer input) { + return input.toString(); + } +} + +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); + } + } + // new while loop version + int findMinValue(ArrayList arr, int minValIdx, int currIdx) { + while (currIdx < arr.size()) { + if (arr.get(minValIdx).compareTo(arr.get(currIdx)) < 0) { + return this.findMinValue(arr, minValIdx, currIdx + 1); + } else { + return this.findMinValue(arr, currIdx, currIdx + 1); + } + } + return minValIdx; + } + // old for loop version + int findMinValue_old(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; + } + ArrayList buildList(int n, IFunc func) { + ArrayList resultArray = new ArrayList(); + for (int i = 0; i < n; i++) { + resultArray.add(func.apply(i)); + } + return resultArray; + } +} + +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); + } + void testBuildList(Tester t) { + init(); + t.checkExpect(u.buildList(5, new IntToString()), + new ArrayList(Arrays.asList("0", "1", "2", "3", "4"))); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/src/nProblem.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/src/nProblem.java new file mode 100644 index 0000000..30d0ef9 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect24_WhileLoops/src/nProblem.java @@ -0,0 +1,47 @@ +import tester.Tester; +import java.util.ArrayList; +import java.util.Arrays; + +class Utils2 { + boolean getsToOne(int n) { + ArrayList listN = new ArrayList(); + listN.add(n); + while (n > 1) { + if (n % 2 == 0) { + n = n / 2; + } else { + n = 3 * n + 1; + } + if (listN.contains(n)) { + return false; + } + listN.add(n); + } + return true; + } + ArrayList getsToOne_detail(int n) { + ArrayList listN = new ArrayList(); + listN.add(n); + while (n > 1) { + if (n % 2 == 0) { + n = n / 2; + } else { + n = 3 * n + 1; + } + listN.add(n); + } + return listN; + } +} + +class ExampleNProblem { + Utils2 u = new Utils2(); + + void testNProblem(Tester t) { + ArrayList n10List = new ArrayList(Arrays.asList( + 10, 5, 16, 8, 4, 2, 1)); + t.checkExpect(u.getsToOne(10), true); + t.checkExpect(u.getsToOne_detail(10), n10List); + + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.classpath b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.classpath new file mode 100644 index 0000000..8e3d409 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.project b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.project new file mode 100644 index 0000000..98c8519 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.project @@ -0,0 +1,17 @@ + + + Lect25_Iterators + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.settings/org.eclipse.core.resources.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.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/Lect25_Iterators/.settings/org.eclipse.jdt.core.prefs b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..e71285a --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/.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/Lect25_Iterators/src/Deque.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/Deque.java new file mode 100644 index 0000000..54c288d --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/Deque.java @@ -0,0 +1,182 @@ +import java.util.Iterator; + +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); + abstract boolean isNode(); + abstract T getData(); +} + +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; + } + boolean isNode() { + return false; + } + T getData() { + throw new RuntimeException("Sentinels do not contain data"); + } +} + +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); + } + } + boolean isNode() { + return true; + } + T getData() { + return this.data; + } +} + +class Deque implements Iterable { + 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(); + } + public Iterator iterator() { + // Choose a forward iteration by default + return new DequeForwardIterator(this); + } + // But...also provide a reverse iterator if needed + Iterator reverseIterator() { + return new DequeReverseIterator(this); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/IBinaryTree.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/IBinaryTree.java new file mode 100644 index 0000000..e5640b1 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/IBinaryTree.java @@ -0,0 +1,220 @@ +interface IComparator { + public int compare(T t1, T t2); +} + +class StringByAlpha implements IComparator { + public int compare(String str1, String str2) { + return str1.compareTo(str2); + } +} + +abstract class IBinaryTree { + public T getData() { + throw new RuntimeException("No data item in an empty tree"); + } + public IBinaryTree getLeft() { + return this; + } + public IBinaryTree getRight() { + return this; + } + public IBinaryTree order(IComparator comp) { + return this; + } + public IBinaryTree insert(T t, IComparator comp) { + return new BSTNode(t, new Leaf(), new Leaf()); + } + public boolean present(T t, IComparator comp) { + return false; + } + public T getLeftMost(IComparator comp) { + throw new RuntimeException("No leftmost item of an empty tree"); + } + public T getRightMost(IComparator comp) { + throw new RuntimeException("No rightmost item of an empty tree"); + } + public T getLeftMostHelper(T rsf, IComparator comp) { + return rsf; + } + public T getRighttMostHelper(T rsf, IComparator comp) { + return rsf; + } + public IBinaryTree removeLeftMost(IComparator comp) { + throw new RuntimeException("No left item of an empty tree"); + } + public IBinaryTree removeRightMost(IComparator comp) { + throw new RuntimeException("No right item of an empty tree"); + } + public IBinaryTree removeLeftMostHelper(T t, IComparator comp) { + return this; + } + public IBinaryTree removeRightMostHelper(T t, IComparator comp) { + return this; + } + public boolean sameTree(IBinaryTree that, IComparator comp) { + return that.sameLeaf(); + } + public boolean sameNode(T t, IBinaryTree that, IComparator comp) { + return false; + } + public boolean sameLeaf() { + return false; + } + public boolean sameData(IBinaryTree that, IComparator thisComp, IComparator thatComp) { + return that.sameLeaf(); + } + public boolean sameDataHelper(IBinaryTree that, IComparator comp) { + return true; + } + public IList buildList(IComparator comp) { + return new MtList(); + } + abstract boolean isNode(); + abstract BSTNode getNode(); +} + +class Leaf extends IBinaryTree { + Leaf() {} + @Override + public boolean sameLeaf() { + return true; + } + public boolean isNode() { + return false; + } + public BSTNode getNode() { + throw new RuntimeException("Cannot return node of leaf"); + } +} + +class BSTNode extends IBinaryTree { + T data; + IBinaryTree left; + IBinaryTree right; + BSTNode(T data, IBinaryTree left, IBinaryTree right) { + this.data = data; + this.left = left; + this.right = right; + } + @Override + public IBinaryTree getLeft() { + return this.left; + } + @Override + public IBinaryTree getRight() { + return this.right; + } + @Override + public T getData() { + return this.data; + } + + @Override + public IBinaryTree insert(T t, IComparator comp) { + if (comp.compare(this.data, t) > 0) { + return new BSTNode(this.data, this.left.insert(t, comp), this.right); + } else { + return new BSTNode(this.data, this.left, this.right.insert(t, comp)); + } + } + @Override + public boolean present(T t, IComparator comp) { + int r = comp.compare(this.data, t); + if (r == 0) { + return true; + } else if (r > 0) { + return this.left.present(t, comp); + } else { + return this.right.present(t, comp); + } + } + @Override + public T getLeftMost(IComparator comp) { + return this.left.getLeftMostHelper(this.data, comp); + } + @Override + public T getRightMost(IComparator comp) { + return this.right.getRighttMostHelper(this.data, comp); + } + @Override + public T getLeftMostHelper(T rsf, IComparator comp) { + return this.left.getLeftMostHelper(this.data, comp); + } + @Override + public T getRighttMostHelper(T rsf, IComparator comp) { + return this.right.getRighttMostHelper(this.data, comp); + } + @Override + public IBinaryTree removeRightMost(IComparator comp) { + T rightMost = this.getRightMost(comp); + if (comp.compare(this.data, rightMost) == 0) { + return this.left; + } else { + return new BSTNode(this.data, + this.left, + this.right.removeRightMostHelper(rightMost, comp)); + } + } + @Override + public IBinaryTree removeLeftMost(IComparator comp) { + T leftMost = this.getLeftMost(comp); + if (comp.compare(this.data, leftMost) == 0) { + return this.right; + } else { + return new BSTNode(this.data, + this.left.removeLeftMostHelper(leftMost, comp), + this.right); + } + } + @Override + public IBinaryTree removeRightMostHelper(T t, IComparator comp) { + if (comp.compare(this.data, t) == 0) { + return this.left; + } else { + return new BSTNode(this.data, + this.left, + this.right.removeRightMostHelper(t, comp)); + } + } + @Override + public IBinaryTree removeLeftMostHelper(T t, IComparator comp) { + if (comp.compare(this.data, t) == 0) { + return this.right; + } else { + return new BSTNode(this.data, + this.left.removeLeftMostHelper(t, comp), + this.right); + } + } + @Override + public boolean sameTree(IBinaryTree that, IComparator comp) { + return that.sameNode(this.data, this, comp); + } + @Override + public boolean sameNode(T t, IBinaryTree that, IComparator comp) { + return comp.compare(this.data, t) == 0 && + this.left.sameTree(that.getLeft(), comp) && + this.right.sameTree(that.getRight(), comp); + } + @Override + public boolean sameData(IBinaryTree that, IComparator thisComp, IComparator thatComp) { + return this.sameDataHelper(that, thatComp) && + that.sameDataHelper(this, thisComp); + } + @Override + public boolean sameDataHelper(IBinaryTree that, IComparator comp) { + return that.present(this.getData(), comp) && + this.left.sameDataHelper(that, comp) && + this.right.sameDataHelper(that, comp); + } + public IList buildList(IComparator comp) { + return new ConsList(this.getLeftMost(comp), + this.removeLeftMost(comp).buildList(comp)); + } + public boolean isNode() { + return true; + } + public BSTNode getNode() { + return this; + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/IList.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/IList.java new file mode 100644 index 0000000..d091b7e --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/IList.java @@ -0,0 +1,51 @@ +import java.util.Iterator; + +interface IList extends Iterable { + IList map(IFunc func); + U foldr(IFunc2 func, U base); + boolean isCons(); + ConsList asCons(); +} + +class MtList implements IList { + public IList map(IFunc f) { + return new MtList(); + } + public U foldr(IFunc2 func, U base) { + return base; + } + public boolean isCons() { + return false; + } + public ConsList asCons() { + throw new RuntimeException("Cannot return Cons of Empty List"); + } + public Iterator iterator() { + return new IListIterator(this); + } +} + +class ConsList implements IList { + T first; + IList rest; + ConsList(T first, IList rest) { + this.first = first; + this.rest = rest; + } + public IList map(IFunc func) { + return new ConsList(func.apply(this.first), this.rest.map(func)); + } + public U foldr(IFunc2 func, U base) { + return func.apply(this.first, + this.rest.foldr(func, base)); + } + public boolean isCons() { + return true; + } + public ConsList asCons() { + return this; + } + public Iterator iterator() { + return new IListIterator(this); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/Iterators.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/Iterators.java new file mode 100644 index 0000000..2b31603 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/Iterators.java @@ -0,0 +1,409 @@ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import tester.Tester; + +//// Represents the ability to produce a sequence of values +//// of type T, one at a time +//interface Iterator { +// // Does this sequence have at least one more value? +// boolean hasNext(); +// // Get the next value in this sequence +// // EFFECT: Advance the iterator to the subsequent value +// T next(); +// // EFFECT: Remove the item just returned by next() +// // NOTE: This method may not be supported by every iterator; ignore it for now +// void remove(); +//} + +//Represents anything that can be iterated over +interface Iterable { + // Returns an iterator over this collection + Iterator iterator(); +} + +class ArrayListIterator implements Iterator { + // the list of items that this iterator iterates over + ArrayList items; + // the index of the next item to be returned + int nextIdx; + // Construct an iterator for a given ArrayList + ArrayListIterator(ArrayList items) { + this.items = items; + this.nextIdx = 0; + } + //Does this sequence (of items in the array list) have at least one more value? + public boolean hasNext() { + return this.nextIdx < this.items.size(); + } + //Get the next value in this sequence + //EFFECT: Advance the iterator to the subsequent value + public T next() { + T answer = this.items.get(this.nextIdx); + this.nextIdx++; + return answer; + } + public void remove() { + throw new UnsupportedOperationException("Don't do this!"); + } +} + +class IListIterator implements Iterator { + IList items; + IListIterator(IList items) { + this.items = items; + } + public boolean hasNext() { + return this.items.isCons(); + } + public T next() { + ConsList itemsAsCons = this.items.asCons(); + T answer = itemsAsCons.first; + this.items = itemsAsCons.rest; + return answer; + } + public void remove() { + throw new UnsupportedOperationException("Don't do this!"); + } +} + +class DequeForwardIterator implements Iterator { + ANode currentNode; + DequeForwardIterator(Deque deque) { + this.currentNode = deque.header; + } + public boolean hasNext() { + return this.currentNode.next.isNode(); + } + public T next() { + T result = this.currentNode.next.getData(); + this.currentNode = this.currentNode.next; + return result; + } + public void remove() { + throw new UnsupportedOperationException("Don't do this!"); + } +} + +class DequeReverseIterator implements Iterator { + ANode currentNode; + DequeReverseIterator(Deque deque) { + this.currentNode = deque.header; + } + public boolean hasNext() { + return this.currentNode.prev.isNode(); + } + public T next() { + T result = this.currentNode.prev.getData(); + this.currentNode = this.currentNode.prev; + return result; + } + public void remove() { + throw new UnsupportedOperationException("Don't do this!"); + } +} + +class FibonacciIterator implements Iterator { + int prevVal = 0; + int curVal = 1; + // There are always more Fibonacci numbers + public boolean hasNext() { + return true; + } + // Compute the next Fibonacci number + public Integer next() { + int answer = this.prevVal + this.curVal; + this.prevVal = this.curVal; + this.curVal = answer; + return answer; + } + public void remove() { + throw new UnsupportedOperationException("Don't do this!"); + } +} + +class EveryOtherIter implements Iterator { + Iterator source; + EveryOtherIter(Iterator source) { + this.source = source; + } + public boolean hasNext() { + // this sequence has a next item if the source does + return this.source.hasNext(); + } + public T next() { + T answer = this.source.next(); // gets the answer, and advances the source + // We need to have the source "skip" the next value + if (this.source.hasNext()) { + this.source.next(); // get the next value and ignore it + } + return answer; + } + public void remove() { + // We can remove an item if our source can remove the item + this.source.remove(); // so just delegate to the source + } +} + +class TakeN implements Iterator { + Iterator source; + int howMany; + int countSoFar; + TakeN(Iterator source, int n) { + this.source = source; + this.howMany = n; + this.countSoFar = 0; + } + public boolean hasNext() { + return (countSoFar < howMany) && source.hasNext(); + } + public T next() { + countSoFar = countSoFar + 1; + return source.next(); + } + public void remove() { + // We can remove an item if our source can remove the item + this.source.remove(); // so just delegate to the source + } +} + +class AlternateIter implements Iterator { + Iterator iter1; + Iterator iter2; + int currentIter; + AlternateIter(Iterator iter1, Iterator iter2) { + this.iter1 = iter1; + this.iter2 = iter2; + } + public boolean hasNext() { + // this sequence has a next item if the source does + if (currentIter % 2 == 0) { + return iter1.hasNext(); + } else { + return iter2.hasNext(); + } + } + public T next() { + // this sequence has a next item if the source does + if (currentIter % 2 == 0) { + currentIter++; + return iter1.next(); + } else { + currentIter++; + return iter2.next(); + } + } + public void remove() { + // We can remove an item if our source can remove the item + // this sequence has a next item if the source does + if (currentIter % 2 == 0) { + iter1.remove(); + } else { + iter2.remove(); + } + } +} + +class BreadthFirstIterator implements Iterator { + Deque> worklist; + BreadthFirstIterator(IBinaryTree source) { + this.worklist = new Deque>(); + this.addIfNotLeaf(source); + } + // EFFECT: only adds the given binary-tree if it's not a leaf + void addIfNotLeaf(IBinaryTree bt) { + if (bt.isNode()) { + this.worklist.addAtTail(new Node>(bt)); + } + } + public boolean hasNext() { + // we have a next item if the worklist isn't empty + return this.worklist.size() > 0; + } + public T next() { + // Get (and remove) the first item on the worklist -- + // and we know it must be a BTNode + BSTNode node = this.worklist.removeFromHead().getData().getNode(); + // Add the children of the node to the tail of the list + this.addIfNotLeaf(node.left); + this.addIfNotLeaf(node.right); + // return the answer + return node.data; + } + public void remove() { + throw new UnsupportedOperationException("Don't do this!"); + } +} + +class PreOrderIterator implements Iterator { + Deque> worklist; + PreOrderIterator(IBinaryTree source) { + this.worklist = new Deque>(); + this.addIfNotLeaf(source); + } + // EFFECT: only adds the given binary-tree if it's not a leaf + void addIfNotLeaf(IBinaryTree bt) { + if (bt.isNode()) { + this.worklist.addAtHead(new Node>(bt)); + } + } + public boolean hasNext() { + // we have a next item if the worklist isn't empty + return this.worklist.size() > 0; + } + public T next() { + // Get (and remove) the first item on the worklist, + // but we must convert to correct data type -- + // and we know it must be a BTNode + BSTNode node = this.worklist.removeFromHead().getData().getNode(); + // Add the children of the node to the head of the list + this.addIfNotLeaf(node.right); + this.addIfNotLeaf(node.left); + // return the answer + return node.data; + } + public void remove() { + throw new UnsupportedOperationException("Don't do this!"); + } +} + +class PostOrderIterator implements Iterator { + Deque> worklist; + PostOrderIterator(IBinaryTree source) { + this.worklist = new Deque>(); + this.addAllNodes(source); + } + // EFFECT: recursively adds all nodes in tree + void addAllNodes(IBinaryTree bt) { + if (bt.isNode()) { + this.worklist.addAtHead(new Node>(bt)); + this.addAllNodes(bt.getRight()); + this.addAllNodes(bt.getLeft()); + } + } + public boolean hasNext() { + // we have a next item if the worklist isn't empty + return this.worklist.size() > 0; + } + // d + // b f + // a c e g + // acbefgd + public T next() { + // Get (and remove) the first item on the worklist, + // but we must convert to correct data type -- + // and we know it must be a BTNode + BSTNode node = this.worklist.removeFromHead().getData().getNode(); + // return the answer + return node.data; + } + public void remove() { + throw new UnsupportedOperationException("Don't do this!"); + } +} + +class InOrderIterator implements Iterator { + Deque> worklist; + InOrderIterator(IBinaryTree source) { + this.worklist = new Deque>(); + this.addAllNodes(source); + } + // EFFECT: recursively adds all nodes in tree + void addAllNodes(IBinaryTree bt) { + if (bt.isNode()) { + this.addAllNodes(bt.getRight()); + this.worklist.addAtHead(new Node>(bt)); + this.addAllNodes(bt.getLeft()); + } + } + public boolean hasNext() { + // we have a next item if the worklist isn't empty + return this.worklist.size() > 0; + } + // d + // b f + // a c e g + // abcdefg + public T next() { + // Get (and remove) the first item on the worklist, + // but we must convert to correct data type -- + // and we know it must be a BTNode + BSTNode node = this.worklist.removeFromHead().getData().getNode(); + // return the answer + return node.data; + } + public void remove() { + throw new UnsupportedOperationException("Don't do this!"); + } +} + +class Examples { + ArrayList strArray; + IList strList; + Deque deq; + IBinaryTree bst; + IComparator comp; + + // simple testing functions + String concate(Iterator iter) { + String result = ""; + while (iter.hasNext()) { + result = result + iter.next(); + } + return result; + } + String intConcate(Iterator iter) { + String result = ""; + while (iter.hasNext()) { + result = result + iter.next(); + } + return result; + } + + void init() { + strArray = new ArrayList(Arrays.asList( + "a", "b", "c")); + + strList = new ConsList("a", + new ConsList("b", new ConsList("c", + new MtList()))); + + deq = new Deque(); + deq.addAtTail(new Node("a")); + deq.addAtTail(new Node("b")); + deq.addAtTail(new Node("c")); + deq.addAtTail(new Node("d")); + deq.addAtTail(new Node("e")); + + // d + // b f + // a c e g + comp = new StringByAlpha(); + bst = new BSTNode("d", new Leaf(), new Leaf()); + bst = bst.insert("b", comp); + bst = bst.insert("f", comp); + bst = bst.insert("a", comp); + bst = bst.insert("c", comp); + bst = bst.insert("e", comp); + bst = bst.insert("g", comp); + } + + void testNext(Tester t) { + init(); + t.checkExpect(this.concate(new ArrayListIterator(strArray)), "abc"); + t.checkExpect(this.concate(new IListIterator(strList)), "abc"); + t.checkExpect(this.concate(new DequeForwardIterator(deq)), "abcde"); + t.checkExpect(this.concate(new DequeReverseIterator(deq)), "edcba"); + t.checkExpect(this.concate(new EveryOtherIter( + new DequeForwardIterator(deq))), "ace"); + t.checkExpect(this.intConcate(new TakeN(new FibonacciIterator(), 5)), "12358"); + + t.checkExpect(this.concate(new AlternateIter( + new ArrayListIterator(strArray), new IListIterator(strList))), + "aabbcc"); + t.checkExpect(this.concate(new BreadthFirstIterator(bst)), "dbfaceg"); + t.checkExpect(this.concate(new PreOrderIterator(bst)), "dbacfeg"); + t.checkExpect(this.concate(new PostOrderIterator(bst)), "acbegfd"); + t.checkExpect(this.concate(new InOrderIterator(bst)), "abcdefg"); + } +} diff --git a/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/Preds.java b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/Preds.java new file mode 100644 index 0000000..aa95d18 --- /dev/null +++ b/completedwork/core_programming/02_classbased_design/Workspace/Lect25_Iterators/src/Preds.java @@ -0,0 +1,11 @@ +interface IPred { + boolean apply(T t); +} + +interface IFunc { + R apply(A arg); +} + +interface IFunc2 { + R apply(A1 arg1, A2 arg2); +}