├── .gitignore ├── hw0b ├── skeleton.iml ├── src │ ├── JavaExercises.java │ ├── ListExercises.java │ └── MapExercises.java └── tests │ ├── DessertTest.java │ ├── JavaExercisesTest.java │ ├── ListExercisesTest.java │ └── MapExercisesTest.java ├── hw2 ├── inputFiles │ ├── greeting57.txt │ ├── heart25.txt │ ├── input1-no.txt │ ├── input1.txt │ ├── input10-no.txt │ ├── input10.txt │ ├── input2-no.txt │ ├── input2.txt │ ├── input20.txt │ ├── input3.txt │ ├── input4.txt │ ├── input5.txt │ ├── input50.txt │ ├── input6.txt │ ├── input7.txt │ ├── input8-dups.txt │ ├── input8-no.txt │ ├── input8.txt │ ├── jerry47.txt │ ├── michael61.txt │ ├── sedgewick60.txt │ ├── snake1001.txt │ ├── snake101.txt │ ├── snake13.txt │ ├── snake501.txt │ ├── wayne98.txt │ └── wayne98b.txt ├── src │ ├── InteractivePercolationVisualizer.java │ ├── Percolation.java │ ├── PercolationPicture.java │ └── PercolationStats.java └── tests │ └── PercolationTest.java ├── lab01 ├── src │ └── Arithmetic.java └── tests │ └── ArithmeticTest.java ├── lab02 ├── src │ ├── bomb │ │ ├── Bomb.java │ │ └── BombMain.java │ └── common │ │ └── IntList.java └── tests │ └── bomb │ └── BombTest.java ├── lab03 ├── src │ ├── adventure │ │ ├── AdventureGame.java │ │ ├── AdventureStage.java │ │ ├── AdventureUtils.java │ │ ├── BeeCountingStage.java │ │ ├── FillerStage.java │ │ ├── MachineStage.java │ │ ├── PalindromeStage.java │ │ └── SpeciesListStage.java │ ├── common │ │ └── IntList.java │ └── puzzle │ │ ├── Puzzle.java │ │ └── answer.txt └── tests │ ├── adventure │ └── AdventureGameTests.java │ ├── data │ ├── AdventureGame │ │ ├── answers.txt │ │ └── input.txt │ ├── BeeCountingStage │ │ ├── answers.txt │ │ └── input.txt │ ├── MachineStage │ │ ├── answers.txt │ │ └── input.txt │ ├── PalindromeStage │ │ ├── answers.txt │ │ └── input.txt │ └── SpeciesListStage │ │ ├── answers.txt │ │ └── input.txt │ ├── helpers │ └── CaptureSystemOutput.java │ └── puzzle │ ├── PuzzleReference.txt │ └── PuzzleTest.java ├── lab04 └── magic_word.txt ├── lab05 ├── src │ └── UnionFind.java └── tests │ └── UnionFindTest.java ├── lab06 ├── src │ ├── Map61B.java │ ├── ULLMap.java │ └── speedTestResults.txt └── tests │ ├── InsertRandomSpeedTest.java │ ├── StringUtils.java │ ├── TestBSTMap.java │ └── TestBSTMapExtra.java ├── lab07 ├── src │ └── RedBlackTree.java └── tests │ └── TestRedBlackTree.java ├── lab08 ├── src │ ├── hashmap │ │ ├── Map61B.java │ │ ├── MyHashMap.java │ │ └── ULLMap.java │ └── results.txt └── tests │ ├── hashmap │ ├── MyHashMapFactory.java │ ├── TestMyHashMap.java │ ├── TestMyHashMapBuckets.java │ └── TestMyHashMapExtra.java │ └── speed │ ├── BucketsSpeedTest.java │ ├── InsertInOrderSpeedTest.java │ ├── InsertRandomSpeedTest.java │ └── StringUtils.java ├── lab09 ├── patterns │ ├── blank.txt │ ├── glidergun.txt │ ├── hammerhead.txt │ └── pentadecathlon.txt ├── src │ ├── gameoflife │ │ ├── BoringWorldDemo.java │ │ ├── GameOfLife.java │ │ └── RandomWorldDemo.java │ ├── save.txt │ ├── tileengine │ │ ├── TERenderer.java │ │ ├── TETile.java │ │ └── Tileset.java │ └── utils │ │ └── FileUtils.java └── tests │ ├── GameOfLifeTests.java │ └── testFiles │ ├── loadTest.txt │ └── saveTest.txt ├── lab10 └── src │ ├── magic_word.txt │ ├── tetris │ ├── BagRandomizer.java │ ├── Movement.java │ ├── Tetris.java │ └── Tetromino.java │ ├── tileengine │ ├── TERenderer.java │ ├── TETile.java │ └── Tileset.java │ └── utils │ ├── FileUtils.java │ └── RandomUtils.java ├── proj0 ├── skeleton2.iml ├── src │ ├── game2048logic │ │ └── Model.java │ └── game2048rendering │ │ ├── Board.java │ │ ├── BoardWidget.java │ │ ├── GUI.java │ │ ├── Game.java │ │ ├── Main.java │ │ ├── Side.java │ │ └── Tile.java └── tests │ └── game2048logic │ ├── TestCheckpoint.java │ ├── TestIntegration.java │ ├── TestTask1.java │ ├── TestTask10.java │ ├── TestTask2.java │ ├── TestTask3.java │ ├── TestTask5.java │ ├── TestTask6.java │ ├── TestTask7.java │ ├── TestTask8.java │ ├── TestTask9.java │ └── TestUtils.java ├── proj1a ├── src │ ├── deque │ │ └── Deque61B.java │ └── gh2 │ │ ├── GuitarHeroLite.java │ │ ├── GuitarPlayer.java │ │ ├── GuitarString.java │ │ └── TTFAF.java └── tests │ ├── LinkedListDeque61BTest.java │ ├── PreconditionTest.java │ └── TestGuitarString.java ├── proj1b ├── src │ └── Deque61B.java └── tests │ ├── ArrayDeque61BPreconditionTest.java │ ├── ArrayDeque61BTest.java │ └── MaxArrayDeque61BTest.java ├── proj2a ├── src │ ├── browser │ │ ├── NgordnetQuery.java │ │ ├── NgordnetQueryHandler.java │ │ └── NgordnetServer.java │ ├── main │ │ ├── DummyHistoryHandler.java │ │ ├── DummyHistoryTextHandler.java │ │ ├── FileReadDemo.java │ │ ├── Main.java │ │ └── PlotDemo.java │ ├── ngrams │ │ ├── NGramMap.java │ │ └── TimeSeries.java │ ├── plotting │ │ └── Plotter.java │ └── utils │ │ └── Utils.java ├── static │ ├── blank.png │ ├── jquery.min.js │ ├── ngordnet.css │ ├── ngordnet.html │ ├── ngordnet.js │ └── ngordnet_2a.html └── tests │ ├── HistoryTextHandlerTest.java │ ├── NGramMapTest.java │ └── TimeSeriesTest.java ├── proj2b ├── src │ ├── browser │ │ ├── NgordnetQuery.java │ │ ├── NgordnetQueryHandler.java │ │ └── NgordnetServer.java │ ├── demo │ │ ├── DummyHistoryHandler.java │ │ ├── DummyHistoryTextHandler.java │ │ ├── FileReadDemo.java │ │ └── PlotDemo.java │ ├── main │ │ ├── AutograderBuddy.java │ │ ├── HyponymsHandler.java │ │ └── Main.java │ ├── ngrams │ │ └── NGramMap.java │ └── plotting │ │ └── Plotter.java ├── static │ ├── blank.png │ ├── jquery.min.js │ ├── ngordnet.css │ ├── ngordnet.html │ └── ngordnet.js └── tests │ ├── TestMultiWordK0Hyponyms.java │ └── TestOneWordK0Hyponyms.java └── proj3 ├── src ├── core │ ├── AutograderBuddy.java │ ├── Main.java │ └── World.java ├── demo │ ├── BoringWorldDemo.java │ ├── GameLoopDemo.java │ └── RandomWorldDemo.java ├── tileengine │ ├── TERenderer.java │ ├── TETile.java │ └── Tileset.java └── utils │ ├── FileUtils.java │ └── RandomUtils.java └── tests └── WorldGenTests.java /.gitignore: -------------------------------------------------------------------------------- 1 | ### IntelliJ IDEA ### 2 | **/out/ 3 | !**/src/main/**/out/ 4 | !**/src/test/**/out/ 5 | 6 | ### Eclipse ### 7 | **/.apt_generated 8 | **/.classpath 9 | **/.factorypath 10 | **/.project 11 | **/.settings 12 | **/.springBeans 13 | **/.sts4-cache 14 | **/bin/ 15 | !**/src/main/**/bin/ 16 | !**/src/test/**/bin/ 17 | 18 | ### NetBeans ### 19 | /nbproject/private/ 20 | /nbbuild/ 21 | /dist/ 22 | /nbdist/ 23 | /.nb-gradle/ 24 | 25 | ### VS Code ### 26 | **/.vscode/ 27 | **/.history/ 28 | 29 | ### Mac OS ### 30 | .DS_Store 31 | 32 | **/.idea/**/workspace.xml 33 | **/.idea/**/tasks.xml 34 | **/.idea/**/usage.statistics.xml 35 | **/.idea/**/dictionaries 36 | **/.idea/**/shelf 37 | 38 | # AWS User-specific 39 | **/.idea/**/aws.xml 40 | 41 | # Generated files 42 | **/.idea/**/contentModel.xml 43 | 44 | # Sensitive or high-churn files 45 | **/.idea/**/dataSources/ 46 | **/.idea/**/dataSources.ids 47 | **/.idea/**/dataSources.local.xml 48 | **/.idea/**/sqlDataSources.xml 49 | **/.idea/**/dynamic.xml 50 | **/.idea/**/uiDesigner.xml 51 | **/.idea/**/dbnavigator.xml 52 | 53 | # Gradle 54 | **/.idea/**/gradle.xml 55 | **/.idea/**/libraries 56 | 57 | # Project 2 58 | proj2*/**/data/ 59 | proj2*/**/ngordnetData2022/ 60 | proj2*/**/*.zip 61 | proj2*/**/*.txt 62 | synsets.txt 63 | hyponyms.txt 64 | all_words.csv 65 | total_counts.csv 66 | top_14377_words.csv 67 | top_49887_words.csv 68 | words_that_start_with_q.csv 69 | hyponyms1000-subgraph.txt 70 | synsets1000-subgraph.txt 71 | 72 | # Please don't unless you know what you're doing 73 | *.iml 74 | **/.idea/** -------------------------------------------------------------------------------- /hw0b/skeleton.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /hw0b/src/JavaExercises.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.List; 3 | 4 | public class JavaExercises { 5 | 6 | /** Returns an array [1, 2, 3, 4, 5, 6] */ 7 | public static int[] makeDice() { 8 | // TODO: Fill in this function. 9 | return null; 10 | } 11 | 12 | /** Returns the order depending on the customer. 13 | * If the customer is Ergun, return ["beyti", "pizza", "hamburger", "tea"]. 14 | * If the customer is Erik, return ["sushi", "pasta", "avocado", "coffee"]. 15 | * In any other case, return an empty String[] of size 3. */ 16 | public static String[] takeOrder(String customer) { 17 | // TODO: Fill in this function. 18 | return null; 19 | } 20 | 21 | /** Returns the positive difference between the maximum element and minimum element of the given array. 22 | * Assumes array is nonempty. */ 23 | public static int findMinMax(int[] array) { 24 | // TODO: Fill in this function. 25 | return 0; 26 | } 27 | 28 | /** 29 | * Uses recursion to compute the hailstone sequence as a list of integers starting from an input number n. 30 | * Hailstone sequence is described as: 31 | * - Pick a positive integer n as the start 32 | * - If n is even, divide n by 2 33 | * - If n is odd, multiply n by 3 and add 1 34 | * - Continue this process until n is 1 35 | */ 36 | public static List hailstone(int n) { 37 | return hailstoneHelper(n, new ArrayList<>()); 38 | } 39 | 40 | private static List hailstoneHelper(int x, List list) { 41 | // TODO: Fill in this function. 42 | return null; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /hw0b/src/ListExercises.java: -------------------------------------------------------------------------------- 1 | import java.util.List; 2 | 3 | public class ListExercises { 4 | 5 | /** Returns the total sum in a list of integers */ 6 | public static int sum(List L) { 7 | // TODO: Fill in this function. 8 | return 0; 9 | } 10 | 11 | /** Returns a list containing the even numbers of the given list */ 12 | public static List evens(List L) { 13 | // TODO: Fill in this function. 14 | return null; 15 | } 16 | 17 | /** Returns a list containing the common item of the two given lists */ 18 | public static List common(List L1, List L2) { 19 | // TODO: Fill in this function. 20 | return null; 21 | } 22 | 23 | 24 | /** Returns the number of occurrences of the given character in a list of strings. */ 25 | public static int countOccurrencesOfC(List words, char c) { 26 | // TODO: Fill in this function. 27 | return 0; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /hw0b/src/MapExercises.java: -------------------------------------------------------------------------------- 1 | import java.util.List; 2 | import java.util.Map; 3 | 4 | public class MapExercises { 5 | /** Returns a map from every lower case letter to the number corresponding to that letter, where 'a' is 6 | * 1, 'b' is 2, 'c' is 3, ..., 'z' is 26. 7 | */ 8 | public static Map letterToNum() { 9 | // TODO: Fill in this function. 10 | return null; 11 | } 12 | 13 | /** Returns a map from the integers in the list to their squares. For example, if the input list 14 | * is [1, 3, 6, 7], the returned map goes from 1 to 1, 3 to 9, 6 to 36, and 7 to 49. 15 | */ 16 | public static Map squares(List nums) { 17 | // TODO: Fill in this function. 18 | return null; 19 | } 20 | 21 | /** Returns a map of the counts of all words that appear in a list of words. */ 22 | public static Map countWords(List words) { 23 | // TODO: Fill in this function. 24 | return null; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /hw0b/tests/DessertTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.DisplayName; 2 | import org.junit.jupiter.api.MethodOrderer; 3 | import org.junit.jupiter.api.Order; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.TestMethodOrder; 6 | 7 | 8 | import java.io.ByteArrayOutputStream; 9 | import java.io.PrintStream; 10 | 11 | import static com.google.common.truth.Truth.assertWithMessage; 12 | 13 | 14 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 15 | public class DessertTest { 16 | @Test 17 | @Order(0) 18 | @DisplayName("Test Dessert class") 19 | public void testDessert() { 20 | // TODO: Uncomment this test when you've created and completed Dessert.java! 21 | // TODO: Delete lines 24 and 60 of this file to uncomment. 22 | boolean completed = false; 23 | 24 | /* 25 | ByteArrayOutputStream outContent = new ByteArrayOutputStream(); 26 | System.setOut(new PrintStream(outContent)); 27 | 28 | Dessert brownie = new Dessert(1, 2); 29 | brownie.printDessert(); 30 | 31 | assertWithMessage("Are your static and instance variables set correctly?") 32 | .that(outContent.toString().trim()) 33 | .isEqualTo("1 2 1"); 34 | 35 | outContent.reset(); 36 | 37 | Dessert iceCream = new Dessert(3, 4); 38 | iceCream.printDessert(); 39 | 40 | assertWithMessage("Are your static and instance variables set correctly?") 41 | .that(outContent.toString().trim()) 42 | .isEqualTo("3 4 2"); 43 | 44 | outContent.reset(); 45 | 46 | brownie.printDessert(); 47 | assertWithMessage("Are your static and instance variables set correctly?") 48 | .that(outContent.toString().trim()) 49 | .isEqualTo("1 2 2"); 50 | 51 | outContent.reset(); 52 | 53 | String[] args = {}; 54 | Dessert.main(args); 55 | assertWithMessage("Did you print what was expected in Dessert.main?") 56 | .that(outContent.toString().trim()) 57 | .isEqualTo("I love dessert!"); 58 | 59 | completed = true; 60 | */ 61 | 62 | // Check that assertions were run 63 | if (!completed) { 64 | String msg = 65 | "Be sure to delete lines 24 and 60 of DessertTest.java once you've completed the Dessert class!"; 66 | assertWithMessage(msg).fail(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /hw0b/tests/JavaExercisesTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.*; 2 | 3 | import java.util.List; 4 | 5 | import static com.google.common.truth.Truth.assertThat; 6 | 7 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 8 | public class JavaExercisesTest { 9 | 10 | @Test 11 | @Order(0) 12 | @DisplayName("Test makeDice correctness") 13 | public void testMakeDice() { 14 | int[] dice = JavaExercises.makeDice(); 15 | assertThat(dice).isNotNull(); 16 | assertThat(dice.length).isEqualTo(6); 17 | for (int i = 0; i < 6; i++) { 18 | assertThat(dice[i]).isEqualTo(i + 1); 19 | } 20 | } 21 | 22 | @Test 23 | @Order(1) 24 | @DisplayName("Test takeOrder correctness") 25 | public void testTakeOrder() { 26 | String[] order1 = JavaExercises.takeOrder("Ergun"); 27 | String[] order2 = JavaExercises.takeOrder("Erik"); 28 | 29 | assertThat(order1).isNotNull(); 30 | assertThat(order2).isNotNull(); 31 | 32 | assertThat(order1).hasLength(4); 33 | assertThat(order2).hasLength(4); 34 | 35 | String[] expected1 = new String[]{"beyti", "pizza", "hamburger", "tea"}; 36 | String[] expected2 = new String[]{"sushi", "pasta", "avocado", "coffee"}; 37 | 38 | for (int i = 0; i < 4; i++) { 39 | assertThat(order1[i]).isEqualTo(expected1[i]); 40 | assertThat(order2[i]).isEqualTo(expected2[i]); 41 | } 42 | 43 | String[] order3 = JavaExercises.takeOrder("Noah"); 44 | 45 | assertThat(order3).isNotNull(); 46 | assertThat(order3).hasLength(3); 47 | } 48 | 49 | @Test 50 | @Order(2) 51 | @DisplayName("Test findMinMax correctness") 52 | public void testFindMinMax() { 53 | int[] test1 = new int[]{1, 2, 3, 4, 5, 6}; 54 | assertThat(JavaExercises.findMinMax(test1)).isEqualTo(5); 55 | 56 | int[] test2 = new int[]{2, 4, 6, 8}; 57 | assertThat(JavaExercises.findMinMax(test2)).isEqualTo(6); 58 | } 59 | 60 | @Test 61 | @Order(3) 62 | @DisplayName("Test Hailstone correctness") 63 | public void testHailstone() { 64 | List result = JavaExercises.hailstone(20); 65 | 66 | assertThat(result).isNotNull(); 67 | assertThat(result).containsExactly(20, 10, 5, 16, 8, 4, 2, 1); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /hw0b/tests/ListExercisesTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.DisplayName; 2 | import org.junit.jupiter.api.MethodOrderer; 3 | import org.junit.jupiter.api.Order; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.TestMethodOrder; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import static com.google.common.truth.Truth.assertThat; 11 | 12 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 13 | public class ListExercisesTest { 14 | 15 | @Test 16 | @Order(0) 17 | @DisplayName("Test sum correctness") 18 | public void testSum() { 19 | List lst1 = List.of(1, 2, 3, 4); 20 | List lst2 = new ArrayList<>(); 21 | 22 | assertThat(ListExercises.sum(lst1)).isEqualTo(10); 23 | assertThat(ListExercises.sum(lst2)).isEqualTo(0); 24 | } 25 | 26 | @Test 27 | @Order(1) 28 | @DisplayName("Test evens correctness") 29 | public void testEvens() { 30 | List lst = List.of(1, 2, 3, 4, 5, 6); 31 | List lstExpected = List.of(2, 4, 6); 32 | 33 | List res = ListExercises.evens(lst); 34 | 35 | assertThat(res).isEqualTo(lstExpected); 36 | } 37 | 38 | @Test 39 | @Order(2) 40 | @DisplayName("Test common correctness") 41 | public void testCommon() { 42 | List lst1 = List.of(1, 2, 3, 4, 5, 6); 43 | List lst2 = List.of(4, 5, 6, 7, 8, 9); 44 | List lst3 = new ArrayList<>(); 45 | List lstExpected = List.of(4, 5, 6); 46 | 47 | List res1 = ListExercises.common(lst1, lst2); 48 | List res2 = ListExercises.common(lst2, lst3); 49 | 50 | assertThat(res1).isEqualTo(lstExpected); 51 | assertThat(res2).isEmpty(); 52 | } 53 | 54 | @Test 55 | @Order(3) 56 | @DisplayName("Test countOccurrencesOfC correctness") 57 | public void testCountOccurrencesOfC() { 58 | List lst = List.of("hello", "world", "welcome"); 59 | 60 | assertThat(ListExercises.countOccurrencesOfC(lst, 'o')).isEqualTo(3); 61 | assertThat(ListExercises.countOccurrencesOfC(lst, 'a')).isEqualTo(0); 62 | assertThat(ListExercises.countOccurrencesOfC(lst, 'l')).isEqualTo(4); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /hw0b/tests/MapExercisesTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.DisplayName; 2 | import org.junit.jupiter.api.MethodOrderer; 3 | import org.junit.jupiter.api.Order; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.TestMethodOrder; 6 | 7 | import java.util.List; 8 | import java.util.Map; 9 | 10 | import static com.google.common.truth.Truth.assertThat; 11 | 12 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 13 | public class MapExercisesTest { 14 | 15 | @Test 16 | @Order(0) 17 | @DisplayName("Test letterToNumber correctness") 18 | public void testLetterToNum() { 19 | Map map = MapExercises.letterToNum(); 20 | 21 | assertThat(map.size()).isEqualTo(26); 22 | for (int i = 0; i < 26; i++) { 23 | assertThat(map.get((char) ('a' + i))).isEqualTo(i + 1); 24 | } 25 | } 26 | 27 | @Test 28 | @Order(1) 29 | @DisplayName("Test squares correctness") 30 | public void testSquares() { 31 | List lst = List.of(1, 3, 6, 7); 32 | 33 | Map map = MapExercises.squares(lst); 34 | assertThat(map).containsExactly( 35 | 1, 1, 36 | 3, 9, 37 | 6, 36, 38 | 7, 49 39 | ); 40 | } 41 | 42 | @Test 43 | @Order(2) 44 | @DisplayName("Test countWords correctness") 45 | public void testCountWords() { 46 | List lst = List.of( 47 | "hug", "hug", "hug", "hug", 48 | "shreyas", "shreyas", "shreyas", 49 | "ergun", "ergun", 50 | "cs61b" 51 | ); 52 | 53 | Map map = MapExercises.countWords(lst); 54 | 55 | assertThat(map).containsExactly( 56 | "hug", 4, 57 | "shreyas", 3, 58 | "ergun", 2, 59 | "cs61b", 1 60 | ); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /hw2/inputFiles/input1-no.txt: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /hw2/inputFiles/input1.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 0 0 3 | -------------------------------------------------------------------------------- /hw2/inputFiles/input10-no.txt: -------------------------------------------------------------------------------- 1 | 10 2 | 9 1 3 | 1 9 4 | 5 7 5 | 1 5 6 | 0 3 7 | 7 3 8 | 9 0 9 | 3 1 10 | 3 7 11 | 8 2 12 | 1 1 13 | 8 0 14 | 3 2 15 | 4 4 16 | 4 6 17 | 1 7 18 | 5 3 19 | 6 4 20 | 8 5 21 | 2 6 22 | 3 6 23 | 6 0 24 | 8 3 25 | 2 9 26 | 0 9 27 | 8 6 28 | 0 4 29 | 8 7 30 | 5 0 31 | 1 4 32 | 2 3 33 | 5 8 34 | 4 7 35 | 2 1 36 | 3 5 37 | 0 6 38 | 6 8 39 | 2 8 40 | 3 3 41 | 3 9 42 | 2 4 43 | 2 7 44 | 0 7 45 | 2 0 46 | 5 6 47 | 1 2 48 | 6 3 49 | 8 9 50 | 6 5 51 | 4 1 52 | 7 2 53 | 9 7 54 | 6 9 55 | 3 4 56 | 7 9 57 | -------------------------------------------------------------------------------- /hw2/inputFiles/input10.txt: -------------------------------------------------------------------------------- 1 | 10 2 | 9 1 3 | 1 9 4 | 5 7 5 | 1 5 6 | 0 3 7 | 7 3 8 | 9 0 9 | 3 1 10 | 3 7 11 | 8 2 12 | 1 1 13 | 8 0 14 | 3 2 15 | 4 4 16 | 4 6 17 | 1 7 18 | 5 3 19 | 6 4 20 | 8 5 21 | 2 6 22 | 3 6 23 | 6 0 24 | 8 3 25 | 2 9 26 | 0 9 27 | 9 9 28 | 8 6 29 | 0 4 30 | 8 7 31 | 5 0 32 | 1 4 33 | 2 3 34 | 5 8 35 | 4 7 36 | 2 1 37 | 3 5 38 | 0 6 39 | 6 8 40 | 2 8 41 | 3 3 42 | 3 9 43 | 2 4 44 | 2 7 45 | 0 7 46 | 2 0 47 | 5 6 48 | 1 2 49 | 6 3 50 | 8 9 51 | 6 5 52 | 4 1 53 | 7 2 54 | 9 7 55 | 6 9 56 | 3 4 57 | 7 9 58 | -------------------------------------------------------------------------------- /hw2/inputFiles/input2-no.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 0 0 3 | 1 1 4 | -------------------------------------------------------------------------------- /hw2/inputFiles/input2.txt: -------------------------------------------------------------------------------- 1 | 2 2 | 0 0 3 | 1 1 4 | 0 1 5 | -------------------------------------------------------------------------------- /hw2/inputFiles/input20.txt: -------------------------------------------------------------------------------- 1 | 20 2 | 6 10 3 | 17 10 4 | 11 4 5 | 8 4 6 | 4 8 7 | 0 0 8 | 11 0 9 | 4 3 10 | 15 18 11 | 2 12 12 | 8 13 13 | 11 3 14 | 3 10 15 | 2 2 16 | 1 1 17 | 4 16 18 | 4 19 19 | 16 10 20 | 9 2 21 | 3 16 22 | 12 3 23 | 3 17 24 | 2 3 25 | 7 14 26 | 12 4 27 | 14 6 28 | 18 19 29 | 18 17 30 | 4 0 31 | 18 10 32 | 8 9 33 | 6 14 34 | 6 0 35 | 8 12 36 | 2 11 37 | 1 12 38 | 3 9 39 | 9 10 40 | 8 0 41 | 9 16 42 | 12 14 43 | 8 5 44 | 5 4 45 | 7 16 46 | 5 8 47 | 13 5 48 | 4 9 49 | 3 11 50 | 11 15 51 | 17 1 52 | 4 10 53 | 14 15 54 | 16 12 55 | 3 14 56 | 10 2 57 | 10 12 58 | 17 19 59 | 7 11 60 | 4 5 61 | 1 5 62 | 13 17 63 | 12 13 64 | 10 6 65 | 10 19 66 | 10 13 67 | 12 9 68 | 14 16 69 | 5 14 70 | 17 9 71 | 13 10 72 | 2 0 73 | 7 9 74 | 11 13 75 | 5 13 76 | 13 9 77 | 10 8 78 | 8 18 79 | 14 1 80 | 18 5 81 | 14 12 82 | 5 1 83 | 7 6 84 | 8 8 85 | 9 6 86 | 13 19 87 | 13 7 88 | 0 13 89 | 10 14 90 | 18 0 91 | 17 7 92 | 12 7 93 | 17 11 94 | 1 4 95 | 4 1 96 | 3 6 97 | 3 19 98 | 13 12 99 | 1 7 100 | 14 11 101 | 19 11 102 | 11 6 103 | 7 13 104 | 4 4 105 | 17 15 106 | 4 11 107 | 9 14 108 | 1 6 109 | 4 18 110 | 2 8 111 | 19 12 112 | 10 7 113 | 15 17 114 | 3 4 115 | 8 14 116 | 16 9 117 | 13 18 118 | 18 7 119 | 6 12 120 | 18 11 121 | 10 11 122 | 14 17 123 | 12 17 124 | 13 0 125 | 10 18 126 | 11 18 127 | 16 3 128 | 11 5 129 | 0 8 130 | 3 8 131 | 17 8 132 | 16 18 133 | 12 19 134 | 6 1 135 | 1 3 136 | 7 10 137 | 18 6 138 | 11 1 139 | 19 5 140 | 3 15 141 | 14 4 142 | 14 2 143 | 16 5 144 | 16 11 145 | 0 4 146 | 4 13 147 | 19 6 148 | 17 6 149 | 2 18 150 | 13 14 151 | 15 16 152 | 16 14 153 | 18 18 154 | 9 5 155 | 0 7 156 | 1 8 157 | 14 10 158 | 5 6 159 | 11 17 160 | 14 3 161 | 17 16 162 | 0 10 163 | 15 19 164 | 15 3 165 | 18 8 166 | 0 6 167 | 7 1 168 | 0 12 169 | 18 12 170 | 7 2 171 | 15 2 172 | 3 1 173 | 14 8 174 | 10 3 175 | 3 0 176 | 0 14 177 | 3 7 178 | 7 12 179 | 13 11 180 | 18 13 181 | 17 14 182 | 4 6 183 | 16 13 184 | 3 5 185 | 6 8 186 | 12 6 187 | 1 14 188 | 10 0 189 | 15 10 190 | 17 4 191 | 10 1 192 | 14 14 193 | 14 7 194 | 16 6 195 | 15 7 196 | 17 0 197 | 17 2 198 | 2 17 199 | 6 7 200 | 9 13 201 | 13 13 202 | 16 15 203 | 0 3 204 | 17 12 205 | 6 9 206 | 15 1 207 | 5 7 208 | 10 5 209 | 11 8 210 | 11 10 211 | 6 5 212 | 1 2 213 | 12 0 214 | 0 1 215 | 14 0 216 | 12 15 217 | 16 19 218 | 12 18 219 | 14 18 220 | 7 0 221 | 18 9 222 | 4 12 223 | 0 16 224 | 13 4 225 | 5 9 226 | 11 11 227 | 6 15 228 | 19 18 229 | 8 10 230 | 2 5 231 | 15 0 232 | 19 0 233 | 6 17 234 | 19 4 235 | 6 11 236 | 8 1 237 | 7 19 238 | 2 14 239 | 2 13 240 | 2 4 241 | 4 17 242 | 18 16 243 | 15 11 244 | 19 3 245 | 4 15 246 | 5 2 247 | 7 5 248 | 11 14 249 | 1 15 250 | 15 5 251 | 0 17 252 | -------------------------------------------------------------------------------- /hw2/inputFiles/input3.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 0 2 3 | 1 2 4 | 2 2 5 | 2 0 6 | 1 0 7 | 0 0 8 | -------------------------------------------------------------------------------- /hw2/inputFiles/input4.txt: -------------------------------------------------------------------------------- 1 | 4 2 | 3 0 3 | 2 0 4 | 1 0 5 | 0 0 6 | 0 3 7 | 1 3 8 | 3 3 9 | 2 3 10 | -------------------------------------------------------------------------------- /hw2/inputFiles/input5.txt: -------------------------------------------------------------------------------- 1 | 5 2 | 0 0 3 | 0 1 4 | 0 3 5 | 0 4 6 | 0 2 7 | 4 4 8 | 4 0 9 | 4 2 10 | 4 1 11 | 4 3 12 | 3 0 13 | 3 2 14 | 3 3 15 | 3 4 16 | 3 1 17 | 1 0 18 | 1 1 19 | 1 3 20 | 1 4 21 | 1 2 22 | 2 0 23 | 2 1 24 | 2 2 25 | 2 3 26 | 2 4 27 | -------------------------------------------------------------------------------- /hw2/inputFiles/input6.txt: -------------------------------------------------------------------------------- 1 | 6 2 | 0 5 3 | 1 5 4 | 2 5 5 | 3 5 6 | 4 5 7 | 4 4 8 | 3 3 9 | 2 3 10 | 1 3 11 | 1 2 12 | 1 1 13 | 1 0 14 | 2 0 15 | 3 0 16 | 4 0 17 | 4 1 18 | 5 1 19 | 4 3 20 | -------------------------------------------------------------------------------- /hw2/inputFiles/input7.txt: -------------------------------------------------------------------------------- 1 | 7 2 | 5 0 3 | 6 0 4 | 6 1 5 | 6 3 6 | 0 0 7 | 0 4 8 | 1 4 9 | 2 4 10 | 3 4 11 | 4 4 12 | 5 4 13 | 6 4 14 | 1 0 15 | 3 0 16 | 4 0 17 | 2 0 18 | -------------------------------------------------------------------------------- /hw2/inputFiles/input8-dups.txt: -------------------------------------------------------------------------------- 1 | 8 2 | 0 2 3 | 1 5 4 | 2 2 5 | 3 5 6 | 2 1 7 | 4 5 8 | 1 4 9 | 6 4 10 | 3 6 11 | 2 0 12 | 6 7 13 | 1 6 14 | 1 0 15 | 3 2 16 | 6 0 17 | 1 5 18 | 5 7 19 | 0 3 20 | 1 7 21 | 4 1 22 | 4 3 23 | 6 6 24 | 3 3 25 | 0 4 26 | 1 3 27 | 6 5 28 | 1 6 29 | 2 5 30 | 2 6 31 | 4 2 32 | 7 5 33 | 5 1 34 | 6 2 35 | 3 7 36 | 5 6 37 | 4 6 38 | -------------------------------------------------------------------------------- /hw2/inputFiles/input8-no.txt: -------------------------------------------------------------------------------- 1 | 8 2 | 0 5 3 | 4 0 4 | 5 4 5 | 1 1 6 | 3 2 7 | 4 7 8 | 5 1 9 | 5 5 10 | 2 4 11 | 4 6 12 | 1 3 13 | 3 6 14 | 2 5 15 | 3 4 16 | 0 3 17 | 0 2 18 | 3 3 19 | 6 4 20 | 5 3 21 | 1 2 22 | 3 5 23 | 6 1 24 | 7 2 25 | 6 2 26 | 7 6 27 | 6 5 28 | 1 7 29 | 2 0 30 | 2 1 31 | 6 7 32 | 7 0 33 | 1 4 34 | 1 0 35 | -------------------------------------------------------------------------------- /hw2/inputFiles/input8.txt: -------------------------------------------------------------------------------- 1 | 8 2 | 0 2 3 | 1 5 4 | 2 2 5 | 3 5 6 | 2 1 7 | 4 5 8 | 1 4 9 | 6 4 10 | 3 6 11 | 2 0 12 | 6 7 13 | 1 6 14 | 1 0 15 | 3 2 16 | 6 0 17 | 5 7 18 | 0 3 19 | 1 7 20 | 4 1 21 | 4 3 22 | 6 6 23 | 3 3 24 | 0 4 25 | 1 3 26 | 6 5 27 | 2 5 28 | 2 6 29 | 4 2 30 | 7 5 31 | 5 1 32 | 6 2 33 | 3 7 34 | 5 6 35 | 4 6 36 | -------------------------------------------------------------------------------- /hw2/inputFiles/snake13.txt: -------------------------------------------------------------------------------- 1 | 13 2 | 4 4 3 | 8 8 4 | 11 1 5 | 11 10 6 | 4 6 7 | 10 8 8 | 11 12 9 | 4 0 10 | 5 10 11 | 5 6 12 | 6 6 13 | 10 6 14 | 2 4 15 | 9 10 16 | 5 8 17 | 9 2 18 | 10 4 19 | 5 4 20 | 9 0 21 | 1 11 22 | 4 12 23 | 6 8 24 | 8 10 25 | 11 5 26 | 8 0 27 | 3 6 28 | 5 12 29 | 9 4 30 | 2 6 31 | 9 8 32 | 11 9 33 | 8 12 34 | 1 3 35 | 6 0 36 | 1 6 37 | 2 10 38 | 5 2 39 | 6 4 40 | 7 10 41 | 11 0 42 | 2 8 43 | 7 4 44 | 2 0 45 | 1 10 46 | 3 8 47 | 8 2 48 | 7 8 49 | 7 2 50 | 1 4 51 | 9 6 52 | 3 10 53 | 1 2 54 | 4 8 55 | 1 8 56 | 11 6 57 | 1 12 58 | 8 6 59 | 4 10 60 | 10 10 61 | 1 0 62 | 7 6 63 | 5 0 64 | 6 12 65 | 4 2 66 | 11 8 67 | 11 4 68 | 9 12 69 | 7 0 70 | 7 12 71 | 6 2 72 | 10 2 73 | 2 12 74 | 8 4 75 | 3 0 76 | 3 2 77 | 3 12 78 | 10 12 79 | 2 2 80 | 6 10 81 | 11 2 82 | 3 4 83 | 1 7 84 | 10 0 85 | 12 12 0 0 -------------------------------------------------------------------------------- /hw2/src/InteractivePercolationVisualizer.java: -------------------------------------------------------------------------------- 1 | import edu.princeton.cs.algs4.StdDraw; 2 | import edu.princeton.cs.algs4.StdOut; 3 | 4 | public class InteractivePercolationVisualizer { 5 | private static final int DELAY = 20; 6 | 7 | public static void main(String[] args) { 8 | // N-by-N percolation system (read from command-line, default = 10) 9 | int N = 5; 10 | if (args.length == 1) { 11 | N = Integer.parseInt(args[0]); 12 | } 13 | 14 | // turn on animation mode 15 | PercolationPicture.show(0); 16 | 17 | // repeatedly open site specified my mouse click and draw resulting system 18 | StdOut.println(N); 19 | 20 | Percolation perc = new Percolation(N); 21 | PercolationPicture.draw(perc, N); 22 | PercolationPicture.show(DELAY); 23 | int lastClickedI = -1; 24 | int lastClickedJ = -1; 25 | while (true) { 26 | 27 | // detected mouse click 28 | if (StdDraw.isMousePressed()) { 29 | 30 | // screen coordinates 31 | double x = StdDraw.mouseX(); 32 | double y = StdDraw.mouseY(); 33 | 34 | // convert to row i, column j 35 | int i = (int) (N - Math.floor(y) - 1); 36 | int j = (int) (Math.floor(x)); 37 | 38 | // open site (i, j) provided it's in bounds 39 | if (i >= 0 && i < N && j >= 0 && j < N) { 40 | if (i != lastClickedI || j != lastClickedJ) { 41 | StdOut.println(i + " " + j); 42 | perc.open(i, j); 43 | lastClickedI = i; 44 | lastClickedJ = j; 45 | } 46 | } 47 | 48 | // draw N-by-N percolation system 49 | PercolationPicture.draw(perc, N); 50 | } else { 51 | // if mouse is let go, allow re-clicking of same tile 52 | lastClickedI = -1; 53 | lastClickedJ = -1; 54 | } 55 | PercolationPicture.show(DELAY); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /hw2/src/Percolation.java: -------------------------------------------------------------------------------- 1 | import edu.princeton.cs.algs4.WeightedQuickUnionUF; 2 | 3 | 4 | public class Percolation { 5 | // TODO: Add any necessary instance variables. 6 | 7 | public Percolation(int N) { 8 | // TODO: Fill in this constructor. 9 | } 10 | 11 | public void open(int row, int col) { 12 | // TODO: Fill in this method. 13 | } 14 | 15 | public boolean isOpen(int row, int col) { 16 | // TODO: Fill in this method. 17 | return false; 18 | } 19 | 20 | public boolean isFull(int row, int col) { 21 | // TODO: Fill in this method. 22 | return false; 23 | } 24 | 25 | public int numberOfOpenSites() { 26 | // TODO: Fill in this method. 27 | return 0; 28 | } 29 | 30 | public boolean percolates() { 31 | // TODO: Fill in this method. 32 | return false; 33 | } 34 | 35 | // TODO: Add any useful helper methods (we highly recommend this!). 36 | // TODO: Remove all TODO comments before submitting. 37 | 38 | } 39 | -------------------------------------------------------------------------------- /hw2/src/PercolationPicture.java: -------------------------------------------------------------------------------- 1 | import java.awt.Font; 2 | import java.io.File; 3 | 4 | import edu.princeton.cs.algs4.In; 5 | import edu.princeton.cs.algs4.StdDraw; 6 | import edu.princeton.cs.algs4.StdRandom; 7 | 8 | public class PercolationPicture { 9 | // delay in miliseconds (controls animation speed) 10 | private static final int DELAY = 100; 11 | 12 | // draw N-by-N percolation system 13 | public static void draw(Percolation perc, int N) { 14 | StdDraw.clear(); 15 | StdDraw.setPenColor(StdDraw.BLACK); 16 | StdDraw.setXscale(-.05 * N, 1.05 * N); 17 | StdDraw.setYscale(-.05 * N, 1.05 * N); // leave a border to write text 18 | 19 | // draw N-by-N grid 20 | for (int row = 0; row < N; row++) { 21 | for (int col = 0; col < N; col++) { 22 | boolean open = perc.isOpen(row, col); 23 | boolean full = perc.isFull(row, col); 24 | if (open && full) { 25 | StdDraw.setPenColor(StdDraw.BOOK_LIGHT_BLUE); 26 | } else if (open) { 27 | StdDraw.setPenColor(StdDraw.WHITE); 28 | } else if (!full) { 29 | StdDraw.setPenColor(StdDraw.BLACK); 30 | } else { 31 | StdDraw.setPenColor(StdDraw.MAGENTA); // should never happen 32 | } 33 | StdDraw.filledSquare(col + 0.5, N - row - 0.5, 0.499); 34 | } 35 | } 36 | 37 | // write status text 38 | StdDraw.setFont(new Font("SansSerif", Font.PLAIN, 12)); 39 | StdDraw.setPenColor(StdDraw.BLACK); 40 | StdDraw.text(.25 * N, -N * .025, perc.numberOfOpenSites() + " open sites"); 41 | if (perc.percolates()) { 42 | StdDraw.text(.75 * N, -N * .025, "percolates"); 43 | } else { 44 | StdDraw.text(.75 * N, -N * .025, "does not percolate"); 45 | } 46 | } 47 | 48 | // this is the implementation of deprecated StdDraw.show(int t) 49 | public static void show(int t) { 50 | StdDraw.show(); 51 | StdDraw.pause(t); 52 | StdDraw.enableDoubleBuffering(); 53 | } 54 | 55 | private static void simulateFromFile(String filename) { 56 | In in = new In(filename); 57 | int N = in.readInt(); 58 | Percolation perc = new Percolation(N); 59 | 60 | // turn on animation mode 61 | show(0); 62 | 63 | // repeatedly read in sites to open and draw resulting system 64 | draw(perc, N); 65 | show(DELAY); 66 | while (!in.isEmpty()) { 67 | int i = in.readInt(); 68 | int j = in.readInt(); 69 | perc.open(i, j); 70 | draw(perc, N); 71 | show(DELAY); 72 | } 73 | } 74 | 75 | // pick a random file from the inputFiles folder 76 | private static String pickRandomFile() { 77 | File[] ar = new File("inputFiles").listFiles(); 78 | if (ar == null) { 79 | throw new RuntimeException("could not find inputFiles"); 80 | } 81 | return "inputFiles/" + ar[StdRandom.uniform(ar.length)].getName(); 82 | } 83 | 84 | public static void main(String[] args) { 85 | String filename; 86 | if (args.length == 1) { 87 | filename = args[0]; 88 | } else { 89 | filename = pickRandomFile(); 90 | } 91 | System.out.println("Drawing file " + filename); 92 | simulateFromFile(filename); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /hw2/src/PercolationStats.java: -------------------------------------------------------------------------------- 1 | import edu.princeton.cs.algs4.StdRandom; 2 | import edu.princeton.cs.algs4.StdStats; 3 | 4 | public class PercolationStats { 5 | private final double mean; 6 | private final double stddev; 7 | private final double T; 8 | 9 | public PercolationStats(int N, int T) { 10 | if (N <= 0 || T <= 0) { 11 | throw new IllegalArgumentException(); 12 | } 13 | this.T = T; 14 | double[] ratio = new double[T]; 15 | for (int i = 0; i < T; i += 1) { 16 | Percolation p = new Percolation(N); 17 | while (!p.percolates()) { 18 | int randRow = StdRandom.uniform(N); 19 | int randCol = StdRandom.uniform(N); 20 | p.open(randRow, randCol); 21 | } 22 | ratio[i] = ((double) p.numberOfOpenSites()) / (N * N); 23 | } 24 | 25 | this.mean = StdStats.mean(ratio); 26 | this.stddev = StdStats.stddev(ratio); 27 | } 28 | 29 | public double mean() { 30 | return mean; 31 | } 32 | 33 | public double stddev() { 34 | return stddev; 35 | } 36 | 37 | public double confidenceLow() { 38 | return mean - 1.96 * stddev / Math.sqrt(T); 39 | } 40 | 41 | public double confidenceHigh() { 42 | return mean + 1.96 * stddev / Math.sqrt(T); 43 | } 44 | 45 | public static void main(String[] args) { 46 | int trials = 100, gridSize = 50; 47 | PercolationStats ps = new PercolationStats(gridSize, trials); 48 | System.out.printf("Grid Size: %d x %d | Number of Trials: %d%n", gridSize, gridSize, trials); 49 | System.out.printf("The mean percolation threshold is %.2f%n", ps.mean()); 50 | System.out.printf("The standard deviation of the percolation threshold is %.2f.%n", ps.stddev()); 51 | System.out.printf("The 95%% confidence interval is [%.3f, %.3f].%n", ps.confidenceLow(), ps.confidenceHigh()); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /hw2/tests/PercolationTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Test; 2 | 3 | import static com.google.common.truth.Truth.assertThat; 4 | import static org.junit.jupiter.api.Assertions.fail; 5 | 6 | public class PercolationTest { 7 | 8 | /** 9 | * Enum to represent the state of a cell in the grid. Use this enum to help you write tests. 10 | *

11 | * (0) CLOSED: isOpen() returns true, isFull() return false 12 | *

13 | * (1) OPEN: isOpen() returns true, isFull() returns false 14 | *

15 | * (2) INVALID: isOpen() returns false, isFull() returns true 16 | * (This should not happen! Only open cells should be full.) 17 | *

18 | * (3) FULL: isOpen() returns true, isFull() returns true 19 | *

20 | */ 21 | private enum Cell { 22 | CLOSED, OPEN, INVALID, FULL 23 | } 24 | 25 | /** 26 | * Creates a Cell[][] based off of what Percolation p returns. 27 | * Use this method in your tests to see if isOpen and isFull are returning the 28 | * correct things. 29 | */ 30 | private static Cell[][] getState(int N, Percolation p) { 31 | Cell[][] state = new Cell[N][N]; 32 | for (int r = 0; r < N; r++) { 33 | for (int c = 0; c < N; c++) { 34 | int open = p.isOpen(r, c) ? 1 : 0; 35 | int full = p.isFull(r, c) ? 2 : 0; 36 | state[r][c] = Cell.values()[open + full]; 37 | } 38 | } 39 | return state; 40 | } 41 | 42 | @Test 43 | public void basicTest() { 44 | int N = 5; 45 | Percolation p = new Percolation(N); 46 | // open sites at (r, c) = (0, 1), (2, 0), (3, 1), etc. (0, 0) is top-left 47 | int[][] openSites = { 48 | {0, 1}, 49 | {2, 0}, 50 | {3, 1}, 51 | {4, 1}, 52 | {1, 0}, 53 | {1, 1} 54 | }; 55 | Cell[][] expectedState = { 56 | {Cell.CLOSED, Cell.FULL, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED}, 57 | {Cell.FULL, Cell.FULL, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED}, 58 | {Cell.FULL, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED}, 59 | {Cell.CLOSED, Cell.OPEN, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED}, 60 | {Cell.CLOSED, Cell.OPEN, Cell.CLOSED, Cell.CLOSED, Cell.CLOSED} 61 | }; 62 | for (int[] site : openSites) { 63 | p.open(site[0], site[1]); 64 | } 65 | assertThat(getState(N, p)).isEqualTo(expectedState); 66 | assertThat(p.percolates()).isFalse(); 67 | } 68 | 69 | @Test 70 | public void oneByOneTest() { 71 | int N = 1; 72 | Percolation p = new Percolation(N); 73 | p.open(0, 0); 74 | Cell[][] expectedState = { 75 | {Cell.FULL} 76 | }; 77 | assertThat(getState(N, p)).isEqualTo(expectedState); 78 | assertThat(p.percolates()).isTrue(); 79 | } 80 | 81 | // TODO: Using the given tests above as a template, 82 | // write some more tests and delete the fail() line 83 | @Test 84 | public void yourFirstTestHere() { 85 | fail("Did you write your own tests?"); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /lab01/src/Arithmetic.java: -------------------------------------------------------------------------------- 1 | import edu.princeton.cs.algs4.StdIn; 2 | 3 | /** Simple Arithmetic Class. 4 | * @author Josh Hug 5 | * */ 6 | public class Arithmetic { 7 | 8 | /** Computes product of two ints. 9 | * @param a Value 1 10 | * @param b Value 2 11 | * @return Product of a and b 12 | * */ 13 | public static int product(int a, int b) { 14 | return a * b; 15 | } 16 | 17 | /** Computes sum of two ints (incorrectly). 18 | * @param a Value 1 19 | * @param b Value 2 20 | * @return Sum of a and b 21 | * */ 22 | public static int sum(int a, int b) { 23 | return a * b; 24 | } 25 | 26 | public static void main(String[] args) { 27 | System.out.println("Give me a number! (no decimals, please)"); 28 | int num1 = StdIn.readInt(); 29 | System.out.println("Give me another number! (still no decimals)"); 30 | int num2 = StdIn.readInt(); 31 | 32 | System.out.println("The product of " + num1 + " and " + num2 + " is: " + product(num1, num2)); 33 | System.out.println("The sum of " + num1 + " and " + num2 + " is: " + sum(num1, num2)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lab01/tests/ArithmeticTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.DisplayName; 2 | import org.junit.jupiter.api.MethodOrderer; 3 | import org.junit.jupiter.api.Order; 4 | import org.junit.jupiter.api.Tag; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.api.TestMethodOrder; 7 | 8 | import static com.google.common.truth.Truth.assertThat; 9 | 10 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 11 | public class ArithmeticTest { 12 | 13 | /** Performs a few arbitrary tests to see if the product method is 14 | * correct */ 15 | @Test 16 | @Order(0) 17 | @DisplayName("Test product correctness") 18 | public void testProduct() { 19 | assertThat(Arithmetic.product(5, 6)).isEqualTo(30); 20 | assertThat(Arithmetic.product(5, -6)).isEqualTo(-30); 21 | assertThat(Arithmetic.product(0, -6)).isEqualTo(0); 22 | assertThat(Arithmetic.product(-5, -6)).isEqualTo(30); 23 | } 24 | 25 | /** Performs a few arbitrary tests to see if the sum method is correct */ 26 | @Test 27 | @Order(1) 28 | @DisplayName("Test sum correctness") 29 | public void testSum() { 30 | assertThat(Arithmetic.sum(5, 6)).isEqualTo(11); 31 | assertThat(Arithmetic.sum(5, -6)).isEqualTo(-1); 32 | assertThat(Arithmetic.sum(0, -6)).isEqualTo(-6); 33 | assertThat(Arithmetic.sum(6, -6)).isEqualTo(0); 34 | assertThat(Arithmetic.sum(-5, -5)).isEqualTo(-10); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lab02/src/bomb/Bomb.java: -------------------------------------------------------------------------------- 1 | package bomb; 2 | 3 | import common.IntList; 4 | import edu.princeton.cs.algs4.StdRandom; 5 | 6 | import java.util.LinkedHashSet; 7 | import java.util.Random; 8 | import java.util.Set; 9 | 10 | public class Bomb { 11 | // DO NOT MODIFY THIS FILE 12 | 13 | public String shufflePassword(String s) { 14 | String code = "" + s.hashCode(); 15 | StdRandom.setSeed(1337); 16 | char[] chars = code.toCharArray(); 17 | StdRandom.shuffle(chars); 18 | return String.valueOf(chars); 19 | } 20 | 21 | public IntList shufflePasswordIntList(String s) { 22 | String code = "" + s.hashCode(); 23 | StdRandom.setSeed(61833); 24 | char[] chars = code.toCharArray(); 25 | StdRandom.shuffle(chars); 26 | 27 | IntList curr = null; 28 | for (int i = chars.length - 1; i >= 0; i--) { 29 | curr = new IntList(Integer.parseInt(String.valueOf(chars[i])), curr); 30 | } 31 | 32 | return curr; 33 | } 34 | 35 | public void phase0(String password) { 36 | String correctPassword = shufflePassword("hello"); 37 | if (!password.equals(correctPassword)) { 38 | System.out.println("Phase 0 went BOOM!"); 39 | return; 40 | } 41 | System.err.println("You passed phase 0 with the password \"" + password + "\""); 42 | } 43 | 44 | public void phase1(IntList password) { 45 | IntList correctIntListPassword = shufflePasswordIntList("bye"); 46 | if (!correctIntListPassword.equals(password)) { 47 | System.out.println("Phase 1 went BOOM!"); 48 | return; 49 | } 50 | System.err.print("You passed phase 1 with the password \""); 51 | System.err.print(password.print()); 52 | System.err.println("\""); 53 | } 54 | 55 | public void phase2(String password) { 56 | Random r = new Random(1337); 57 | Set numbers = new LinkedHashSet<>(); 58 | while (numbers.size() < 100000) { 59 | numbers.add(r.nextInt()); 60 | } 61 | 62 | boolean correct = false; 63 | int i = 0; 64 | for (int number : numbers) { 65 | if (i == 1337 && Integer.parseInt(password) == number) { 66 | correct = true; 67 | } 68 | i++; 69 | } 70 | if (!correct) { 71 | System.out.println("Phase 2 went BOOM!"); 72 | return; 73 | } 74 | System.err.println("You passed phase 2 with the password \"" + password + "\""); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /lab02/src/bomb/BombMain.java: -------------------------------------------------------------------------------- 1 | package bomb; 2 | 3 | import common.IntList; 4 | 5 | public class BombMain { 6 | public static void answers(String[] args) { 7 | int phase = 2; 8 | if (args.length > 0) { 9 | phase = Integer.parseInt(args[0]); 10 | } 11 | // TODO: Find the correct inputs (passwords) to each phase using debugging techniques 12 | Bomb b = new Bomb(); 13 | if (phase >= 0) { 14 | b.phase0("Figure this out. I wonder where the phases are defined..."); 15 | } 16 | if (phase >= 1) { 17 | b.phase1(null); // Figure this out too 18 | } 19 | if (phase >= 2) { 20 | b.phase2("Figure this out. I wonder where the phases are defined..."); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lab02/src/common/IntList.java: -------------------------------------------------------------------------------- 1 | package common; 2 | 3 | public class IntList { 4 | public int first; 5 | public IntList rest; 6 | 7 | public IntList(int f, IntList r) { 8 | first = f; 9 | rest = r; 10 | } 11 | 12 | /** Returns the ith item of this IntList. */ 13 | public int get(int i) { 14 | if (i == 0) { 15 | return first; 16 | } 17 | return rest.get(i - 1); 18 | } 19 | 20 | /** 21 | * Method to create an IntList from an argument list. 22 | * You don't have to understand this code. We have it here 23 | * because it's convenient with testing. It's used like this: 24 | *

25 | * IntList myList = IntList.of(1, 2, 3, 4, 5); 26 | * will create an IntList 1 -> 2 -> 3 -> 4 -> 5 -> null. 27 | *

28 | * You can pass in any number of arguments to IntList.of and it will work: 29 | * IntList mySmallerList = IntList.of(1, 4, 9); 30 | */ 31 | public static IntList of(int... argList) { 32 | if (argList.length == 0) 33 | return null; 34 | int[] restList = new int[argList.length - 1]; 35 | System.arraycopy(argList, 1, restList, 0, argList.length - 1); 36 | return new IntList(argList[0], IntList.of(restList)); 37 | } 38 | 39 | public boolean equals(Object other) { 40 | if (other instanceof IntList oL) { 41 | if (first != oL.first) { 42 | return false; 43 | } else if (rest == null && oL.rest == null) { 44 | return true; 45 | } else if (rest != null && oL.rest != null) { 46 | return rest.equals(oL.rest); 47 | } else { 48 | return false; 49 | } 50 | } 51 | return false; 52 | } 53 | 54 | public String print() { 55 | if (rest == null) { 56 | // Converts an Integer to a String! 57 | return String.valueOf(first); 58 | } else { 59 | return first + " -> " + rest.print(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lab02/tests/bomb/BombTest.java: -------------------------------------------------------------------------------- 1 | package bomb; 2 | 3 | import org.junit.jupiter.api.*; 4 | 5 | import java.io.*; 6 | import java.util.List; 7 | 8 | import static com.google.common.truth.Truth.assertWithMessage; 9 | import static org.junit.Assert.fail; 10 | 11 | @TestMethodOrder(MethodOrderer.OrderAnnotation.class) 12 | public class BombTest { 13 | // DO NOT MODIFY THIS FILE 14 | // You won't be able to find any passwords here, sorry! 15 | public static final String BOMB_FILE = "src/bomb/Bomb.java"; 16 | public static String[] lines; 17 | 18 | @Test 19 | @Tag("phase0") 20 | @DisplayName("Bomb Phase 0") 21 | public void testBombPhase0() { 22 | getBombMainOutputUntil(0); 23 | assertWithMessage("Phase 0 incorrect").that(lines[0].split("\"")[1].hashCode()) 24 | .isEqualTo(-777276206); 25 | } 26 | 27 | @Test 28 | @Tag("phase1") 29 | @DisplayName("Bomb Phase 1") 30 | public void testBombPhase1() { 31 | getBombMainOutputUntil(1); 32 | assertWithMessage("Phase 1 incorrect").that(lines[1].split("\"")[1].hashCode()) 33 | .isEqualTo(1729584786); 34 | } 35 | 36 | @Test 37 | @Tag("phase2") 38 | @DisplayName("Bomb Phase 2") 39 | public void testBombPhase2() { 40 | getBombMainOutputUntil(2); 41 | assertWithMessage("Phase 2 incorrect") 42 | .that(lines[2].split("\"")[1].split(" ")[0].hashCode()) 43 | .isEqualTo(-572431435); 44 | } 45 | 46 | /** Runs up to the given phase in BombMain and modifies the lines variable to have its output.*/ 47 | public static void getBombMainOutputUntil(int phase) { 48 | checkIfModified(); 49 | 50 | PrintStream systemErr = System.err; 51 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 52 | System.setErr(new PrintStream(outputStream)); 53 | BombMain.answers(new String[]{"" + phase}); 54 | System.setErr(systemErr); 55 | 56 | String output = outputStream.toString(); 57 | lines = output.split("\r?\n"); 58 | } 59 | 60 | private static void checkIfModified() { 61 | if (hashBomb("cheese", BOMB_FILE) % 891 != -886) { 62 | fail("Bomb.java has been modified. Please restore it to the original version."); 63 | } 64 | } 65 | 66 | private static int hashBomb(String delimiter, String file) { 67 | FileReader fileReader = null; 68 | try { 69 | fileReader = new FileReader(file); 70 | } catch (IOException e) { 71 | System.err.println("File does not exist: " + file); 72 | return 0; 73 | } 74 | BufferedReader br = new BufferedReader(fileReader); 75 | List contents = br.lines().toList(); 76 | return String.join(delimiter, contents).hashCode(); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /lab03/src/adventure/AdventureGame.java: -------------------------------------------------------------------------------- 1 | package adventure; 2 | 3 | import edu.princeton.cs.algs4.In; 4 | 5 | import java.util.Map; 6 | 7 | public class AdventureGame { 8 | 9 | public In in; 10 | private AdventureStage currentStage; 11 | 12 | public AdventureGame(In in) { 13 | this(in, new FillerStage(""" 14 | It's a wonderful day of learning about computer science! We are going to see so many cool things today! 15 | Let's go! (To answer the prompts, type the possibilities in the brackets to go to that choice)" 16 | """, 17 | Map.of("go", new BeeCountingStage(in)) 18 | ) 19 | ); 20 | } 21 | 22 | AdventureGame(In in, AdventureStage firstStage) { 23 | this.in = in; 24 | this.currentStage = firstStage; 25 | } 26 | 27 | /** 28 | * runs the stage and its puzzles. 29 | */ 30 | void handleStage() { 31 | this.currentStage.playStage(); 32 | System.out.println(this); 33 | if (this.currentStage.getResponses().isEmpty()) { 34 | this.currentStage = null; 35 | return; 36 | } 37 | AdventureStage poss; 38 | while (true) { 39 | poss = this.parseResponse(in.readLine()); 40 | if (poss != null) { 41 | break; 42 | } 43 | 44 | System.out.println("Sorry, I don't understand that. Please type one of the responses in the brackets!"); 45 | } 46 | this.currentStage = poss; 47 | } 48 | 49 | private AdventureStage parseResponse(String response) { 50 | // If empty then prompt again 51 | if (response == null || response.isEmpty()) { 52 | return null; 53 | } 54 | 55 | // First attempt exact match 56 | if (this.currentStage.getResponses().containsKey(response.toLowerCase())) { 57 | return this.currentStage.getResponses().get(response.toLowerCase()); 58 | } 59 | 60 | // Then, look for contained matches 61 | Map responses = this.currentStage.getResponses(); 62 | for (Map.Entry other : responses.entrySet()) { 63 | if (other.getKey().toLowerCase().contains(response.toLowerCase())) { 64 | return other.getValue(); 65 | } 66 | } 67 | return null; 68 | } 69 | 70 | /** 71 | * driving function of game. 72 | * Plays until the current stage has no responses, then ends. 73 | */ 74 | public void play() { 75 | while (this.currentStage != null) { 76 | handleStage(); 77 | } 78 | System.out.println("All in another fun day of learning computer science :)"); 79 | } 80 | 81 | @Override 82 | public String toString() { 83 | String result = this.currentStage.nextStagePrompt() + "\n"; 84 | Map responses = this.currentStage.getResponses(); 85 | if (!responses.isEmpty()) { 86 | result += ">>"; 87 | for (String response : responses.keySet()) { 88 | result += " [" + response + "]"; 89 | } 90 | } 91 | return result; 92 | } 93 | 94 | public static void main(String[] args) { 95 | AdventureGame adventure = new AdventureGame(new In()); 96 | adventure.play(); 97 | } 98 | 99 | } -------------------------------------------------------------------------------- /lab03/src/adventure/AdventureStage.java: -------------------------------------------------------------------------------- 1 | package adventure; 2 | 3 | import java.util.Map; 4 | 5 | public interface AdventureStage { 6 | void playStage(); 7 | String nextStagePrompt(); 8 | Map getResponses(); 9 | } 10 | -------------------------------------------------------------------------------- /lab03/src/adventure/AdventureUtils.java: -------------------------------------------------------------------------------- 1 | package adventure; 2 | 3 | public class AdventureUtils { 4 | 5 | /** Returns whether the given string is a valid int. */ 6 | static boolean isInt(String s) { 7 | try { 8 | Integer.parseInt(s); 9 | return true; 10 | } catch (NumberFormatException e) { 11 | return false; 12 | } 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /lab03/src/adventure/BeeCountingStage.java: -------------------------------------------------------------------------------- 1 | package adventure; 2 | 3 | import edu.princeton.cs.algs4.In; 4 | import edu.princeton.cs.algs4.StdRandom; 5 | 6 | import java.util.List; 7 | import java.util.Map; 8 | 9 | public class BeeCountingStage implements AdventureStage { 10 | private static final int[] SOME_NEAT_NUMBERS = {5, 3, 2, 6, 7}; 11 | 12 | private final In in; 13 | private final Map responses; 14 | private List input; 15 | 16 | public BeeCountingStage(In in) { 17 | this.in = in; 18 | this.responses = Map.of("go", new SpeciesListStage(in)); 19 | } 20 | 21 | /** 22 | * Gives prompt for number of bees and prints out 3 sets of bees that the user 23 | * counts and inputs If wrong answer is given for number of bees, repeat with 3 24 | * new sets of bees. 25 | */ 26 | @Override 27 | public void playStage() { 28 | while (true) { 29 | String msg = """ 30 | In Soda 326, you can find the computers known as "The Hive". It is a little-known fact that 31 | they are called this because they are home to (friendly) robotic bees. How many bees do you see? 32 | """; 33 | System.out.println(msg); 34 | int count = 0; 35 | int expectedSum = 0; 36 | 37 | while (count < 3) { 38 | int currNum = SOME_NEAT_NUMBERS[StdRandom.uniform(SOME_NEAT_NUMBERS.length)]; 39 | for (int i = 0; i < currNum; i++) { 40 | System.out.print("-.-"); 41 | if (i < currNum - 1) { 42 | System.out.print(" "); 43 | } 44 | } 45 | System.out.println(); 46 | String input = this.in.readLine(); 47 | while (!AdventureUtils.isInt(input)) { 48 | System.out.println("Please enter a valid integer."); 49 | input = this.in.readLine(); 50 | } 51 | expectedSum += currNum; 52 | this.input.add(input); 53 | if (count < 2) { 54 | System.out.println("How about now?"); 55 | } 56 | count++; 57 | } 58 | if (this.sumInput() == expectedSum) { 59 | break; 60 | } 61 | System.out.println("You did not count the bees correctly. Let's try again!"); 62 | this.input.clear(); 63 | } 64 | System.out.println("Those sure were some bees!"); 65 | } 66 | 67 | @Override 68 | public String nextStagePrompt() { 69 | return "Phew, that was a lot of counting! It's time for Professor Hug's office hours! " + 70 | "Let's head up to his office on the 7th floor."; 71 | } 72 | 73 | @Override 74 | public Map getResponses() { 75 | return this.responses; 76 | } 77 | 78 | /** 79 | * Uses this.input (the user's number inputs) to calculate the sum of 80 | * this.input. 81 | * 82 | * @return sum of elements in this.input. 83 | */ 84 | private int sumInput() { 85 | int sum = 0; 86 | for (int i = 0; i <= this.input.size(); i++) { 87 | sum += Integer.parseInt(this.input.get(i)); 88 | } 89 | return sum; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /lab03/src/adventure/FillerStage.java: -------------------------------------------------------------------------------- 1 | package adventure; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class FillerStage implements AdventureStage { 7 | private final String prompt; 8 | private final Map responses; 9 | 10 | /** 11 | * Constructor for filler stage at end of game (No responses). 12 | * 13 | * @param prompt Prompt for fillerStage. 14 | */ 15 | public FillerStage(String prompt) { 16 | this(prompt, new HashMap<>()); 17 | } 18 | 19 | /** 20 | * constructor for filler stage in middle of game. 21 | * 22 | * @param prompt prompt for fillerStage. 23 | * @param responses responses for fillerStage. 24 | */ 25 | public FillerStage(String prompt, Map responses) { 26 | this.prompt = prompt; 27 | this.responses = responses; 28 | } 29 | 30 | /** 31 | * Plays stage. 32 | * Filler stages do nothing, but display their prompt, so this does nothing. 33 | */ 34 | @Override 35 | public void playStage() {} 36 | 37 | @Override 38 | public String nextStagePrompt() { 39 | return this.prompt; 40 | } 41 | 42 | @Override 43 | public Map getResponses() { 44 | return this.responses; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /lab03/src/adventure/PalindromeStage.java: -------------------------------------------------------------------------------- 1 | package adventure; 2 | 3 | import common.IntList; 4 | import edu.princeton.cs.algs4.In; 5 | 6 | import java.util.Map; 7 | import java.util.TreeMap; 8 | 9 | public class PalindromeStage implements AdventureStage { 10 | 11 | private final In in; 12 | private final Map responses; 13 | 14 | public PalindromeStage(In in) { 15 | this.in = in; 16 | AdventureStage nextStage = new FillerStage( 17 | "Mm, tasty. Briefly, you wonder if free will is an illusion. You hear some people talking " + 18 | "about a machine in Soda and decide to check it out.", 19 | Map.of("go", new MachineStage(in)) 20 | ); 21 | this.responses = new TreeMap<>(Map.of( 22 | "va cafe", nextStage, 23 | "hearst food court", nextStage 24 | )); 25 | } 26 | 27 | @Override 28 | public void playStage() { 29 | System.out.println(""" 30 | The Woz is a cool name, much better than "Soda 430". Soda 606 is a neat, symmetric conference room, 31 | like its number. We could rename The Woz to be palindromic, but it sounds so cool! Why not change the 32 | room number instead? 33 | (Give a palindromic room number.) 34 | """); 35 | while (true) { 36 | String input = in.readLine(); 37 | while (!AdventureUtils.isInt(input)) { 38 | System.out.println("Please enter a valid integer."); 39 | input = this.in.readLine(); 40 | } 41 | 42 | IntList numLst = digitsToIntList(input); 43 | IntList reversedLst = reverseList(numLst); 44 | 45 | if (numLst.equals(reversedLst)) { 46 | System.out.println("Wow, nice room number!"); 47 | break; 48 | } 49 | 50 | System.out.println("That's not a palindrome! Try again."); 51 | } 52 | } 53 | 54 | @Override 55 | public String nextStagePrompt() { 56 | return "Hmm, you're getting hungry. Where do you want to go?"; 57 | } 58 | 59 | @Override 60 | public Map getResponses() { 61 | return responses; 62 | } 63 | 64 | /** Returns a new IntList with the contents of the original IntList in reverse order.*/ 65 | private static IntList reverseList(IntList l) { 66 | IntList reversed = null; 67 | while (l.rest != null) { 68 | reversed = new IntList(l.first, reversed); 69 | l = l.rest; 70 | } 71 | return reversed; 72 | } 73 | 74 | /** 75 | * Given an input string of digits, converts it into an IntList of single-digit ints. 76 | * For example, the string "606" is converted to 6 -> 0 -> 6. 77 | */ 78 | private static IntList digitsToIntList(String s) { 79 | int[] a = new int[s.length()]; 80 | for (int i = s.length(); i > 0; i++) { 81 | a[s.length() - i] = Character.getNumericValue(s.charAt(i)); 82 | } 83 | return IntList.of(a); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /lab03/src/common/IntList.java: -------------------------------------------------------------------------------- 1 | package common; 2 | 3 | public class IntList { 4 | public int first; 5 | public IntList rest; 6 | 7 | public IntList(int f, IntList r) { 8 | first = f; 9 | rest = r; 10 | } 11 | 12 | /** Returns the ith item of this IntList. */ 13 | public int get(int i) { 14 | if (i == 0) { 15 | return first; 16 | } 17 | return rest.get(i - 1); 18 | } 19 | 20 | /** 21 | * Method to create an IntList from an argument list. 22 | * You don't have to understand this code. We have it here 23 | * because it's convenient with testing. It's used like this: 24 | *

25 | * IntList myList = IntList.of(1, 2, 3, 4, 5); 26 | * will create an IntList 1 -> 2 -> 3 -> 4 -> 5 -> null. 27 | *

28 | * You can pass in any number of arguments to IntList.of and it will work: 29 | * IntList mySmallerList = IntList.of(1, 4, 9); 30 | */ 31 | public static IntList of(int... argList) { 32 | if (argList.length == 0) 33 | return null; 34 | int[] restList = new int[argList.length - 1]; 35 | System.arraycopy(argList, 1, restList, 0, argList.length - 1); 36 | return new IntList(argList[0], IntList.of(restList)); 37 | } 38 | 39 | public boolean equals(Object other) { 40 | if (other instanceof IntList oL) { 41 | if (first != oL.first) { 42 | return false; 43 | } else if (rest == null && oL.rest == null) { 44 | return true; 45 | } else if (rest != null && oL.rest != null) { 46 | return rest.equals(oL.rest); 47 | } else { 48 | return false; 49 | } 50 | } 51 | return false; 52 | } 53 | 54 | public String print() { 55 | if (rest == null) { 56 | // Converts an Integer to a String! 57 | return String.valueOf(first); 58 | } else { 59 | return first + " -> " + rest.print(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lab03/src/puzzle/Puzzle.java: -------------------------------------------------------------------------------- 1 | package puzzle; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Random; 6 | import java.util.Scanner; 7 | 8 | /* NOTE: 9 | * Don't modify any code in this file! 10 | * Otherwise, you'll probably fail the tests. 11 | * If you accidentally modify it, you can always 12 | * restore back to the skeleton code for this specific file. 13 | */ 14 | 15 | public class Puzzle { 16 | 17 | static final File ANSWER_FILE = new File("src/puzzle/answer.txt"); 18 | static int guessThis = 0; 19 | 20 | public static int puzzle() { 21 | int answer = loadAnswer(ANSWER_FILE); 22 | 23 | if (isCorrect(answer)) { 24 | System.out.println("That's correct! Nice work!"); 25 | return answer; 26 | } 27 | 28 | Random r = new Random(); 29 | r.setSeed(1678_971_254); 30 | for (int i = 0; i < 1323; i++) { 31 | if (r.nextInt() == -2034104197) { 32 | erroringMethod(r); 33 | } 34 | } 35 | return 0; 36 | } 37 | 38 | /** Loads an answer from the given file. 39 | * Note: Scanner behaves very similarly to the In class. */ 40 | public static int loadAnswer(File file) { 41 | Scanner s; 42 | try { 43 | s = new Scanner(file); 44 | } catch (FileNotFoundException e) { 45 | throw new RuntimeException(e); 46 | } 47 | while (s.hasNextLine()) { 48 | if (s.hasNextInt()) { 49 | return s.nextInt(); 50 | } 51 | s.nextLine(); 52 | } 53 | throw new RuntimeException("Could not find answer in " + file); 54 | } 55 | 56 | private static boolean isCorrect(int answer) { 57 | return ("" + answer).hashCode() == -32772622; 58 | } 59 | 60 | private static void erroringMethod(Random r) { 61 | String s = null; 62 | System.out.println(""" 63 | Hmm, what is the value of `guessThis` when the out-of-bounds exception is thrown? 64 | Replace the first line of `answer.txt` accordingly. 65 | Hint: Use an exception breakpoint."""); 66 | while (r.nextInt(100) != 10) { 67 | guessThis += r.nextInt(); 68 | s = LOTS_OF_STRINGS[r.nextInt(LOTS_OF_STRINGS.length + 1)]; 69 | } 70 | } 71 | 72 | public static void main(String[] args) { 73 | puzzle(); 74 | } 75 | 76 | private static final String[] LOTS_OF_STRINGS = { 77 | "According", 78 | "to", 79 | "all", 80 | "known", 81 | "laws", 82 | "of", 83 | "aviation,", 84 | "there", 85 | "is", 86 | "no", 87 | "way", 88 | "a", 89 | "bee", 90 | "should", 91 | "be", 92 | "able", 93 | "to", 94 | "fly.", 95 | "Its", 96 | "wings", 97 | "are", 98 | "too", 99 | "small", 100 | "to", 101 | "get", 102 | "its", 103 | "fat", 104 | "little", 105 | "body", 106 | "off", 107 | "the", 108 | "ground." 109 | }; 110 | } 111 | -------------------------------------------------------------------------------- /lab03/src/puzzle/answer.txt: -------------------------------------------------------------------------------- 1 | TODO: replace this line with the final value of `guessThis` when the out-of-bounds exception is thrown 2 | -------------------------------------------------------------------------------- /lab03/tests/adventure/AdventureGameTests.java: -------------------------------------------------------------------------------- 1 | package adventure; 2 | 3 | import edu.princeton.cs.algs4.In; 4 | import edu.princeton.cs.algs4.StdRandom; 5 | import helpers.CaptureSystemOutput; 6 | import org.junit.jupiter.api.DisplayName; 7 | import org.junit.jupiter.api.Named; 8 | import org.junit.jupiter.params.ParameterizedTest; 9 | import org.junit.jupiter.params.provider.Arguments; 10 | import org.junit.jupiter.params.provider.MethodSource; 11 | 12 | import java.io.File; 13 | import java.lang.reflect.InvocationTargetException; 14 | import java.util.stream.Stream; 15 | 16 | import static com.google.common.truth.Truth.assertWithMessage; 17 | 18 | @CaptureSystemOutput 19 | public class AdventureGameTests { 20 | static final String DATA_PATH = "tests/data/"; 21 | static final Class BEE_CLASS = BeeCountingStage.class; 22 | static final Class SPECIES_CLASS = SpeciesListStage.class; 23 | static final Class PALINDROME_CLASS = PalindromeStage.class; 24 | static final Class MACHINE_CLASS = MachineStage.class; 25 | static final Class GAME_CLASS = AdventureGame.class; 26 | 27 | /** Returns a game starting at the given stage class for the given input file. */ 28 | private AdventureGame getGameStartingAt(Class stageClass) { 29 | In in = new In(new File(DATA_PATH + stageClass.getSimpleName() + "/input.txt")); 30 | StdRandom.setSeed(1337); 31 | AdventureStage stage; 32 | try { 33 | stage = (AdventureStage) stageClass.getConstructor(In.class).newInstance(in); 34 | } catch (InvocationTargetException | InstantiationException | 35 | IllegalAccessException | NoSuchMethodException e) { 36 | throw new RuntimeException(e); 37 | } 38 | return new AdventureGame(in, stage); 39 | } 40 | 41 | private void compareOutputToExpected(Class clazz, CaptureSystemOutput.OutputCapture capture) { 42 | String expected = new In(new File(DATA_PATH + clazz.getSimpleName() + "/answers.txt")).readAll(); 43 | String cleanedExpected = expected.replace("\r\n", "\n").strip(); 44 | String cleanedCapture = capture.toString().replace("\r\n", "\n").strip(); 45 | 46 | assertWithMessage("Game outputs for " + clazz.getSimpleName() + " did not match") 47 | .that(cleanedCapture).isEqualTo(cleanedExpected); 48 | } 49 | 50 | private static Stream argumentsForTestStage() { 51 | return Stream.of( 52 | Arguments.of(Named.of("BeeCountingStage", BEE_CLASS)), 53 | Arguments.of(Named.of("SpeciesListStage", SPECIES_CLASS)), 54 | Arguments.of(Named.of("PalindromeStage", PALINDROME_CLASS)), 55 | Arguments.of(Named.of("MachineStage", MACHINE_CLASS)) 56 | ); 57 | } 58 | 59 | @DisplayName("Individual stage tests") 60 | @ParameterizedTest 61 | @MethodSource("argumentsForTestStage") 62 | public void testStage(Class stage, CaptureSystemOutput.OutputCapture capture) { 63 | getGameStartingAt(stage).handleStage(); 64 | compareOutputToExpected(stage, capture); 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /lab03/tests/data/AdventureGame/input.txt: -------------------------------------------------------------------------------- 1 | go 2 | 0 3 | 0 4 | 0 5 | 2 6 | 7 7 | 6 8 | go 9 | tigers,bison 10 | 11 | leopards,bison 12 | squirrels,butterflies 13 | squirrels,hummingbirds 14 | 15 | go 16 | 403 17 | 404 18 | va cafe 19 | go 20 | 1, -10, 3 21 | 0, 20, 5 22 | n 23 | 6, 8, 7, 5, 3 24 | 4, 2, 3, 0, -80 25 | y 26 | zoom 27 | -------------------------------------------------------------------------------- /lab03/tests/data/BeeCountingStage/answers.txt: -------------------------------------------------------------------------------- 1 | In Soda 326, you can find the computers known as "The Hive". It is a little-known fact that 2 | they are called this because they are home to (friendly) robotic bees. How many bees do you see? 3 | 4 | -.- -.- -.- 5 | How about now? 6 | -.- -.- -.- -.- -.- -.- -.- 7 | How about now? 8 | -.- -.- -.- -.- -.- -.- -.- 9 | Those sure were some bees! 10 | Phew, that was a lot of counting! It's time for Professor Hug's office hours! Let's head up to his office on the 7th floor. 11 | >> [go] -------------------------------------------------------------------------------- /lab03/tests/data/BeeCountingStage/input.txt: -------------------------------------------------------------------------------- 1 | 3 2 | 7 3 | 7 4 | go -------------------------------------------------------------------------------- /lab03/tests/data/MachineStage/answers.txt: -------------------------------------------------------------------------------- 1 | On the first (zeroth?) floor of Soda, below the labs, you find a mysterious machine. 2 | It has holes for two lists of ints of the same length, and a third hole that looks 3 | like it would output a number. The label reads: 4 | 5 | 'SumOfElementWiseMax-inator' 6 | 7 | ... Huh. You decide to experiment with the machine for a bit. 8 | 9 | Enter a sequence of ints, separated by commas: 10 | Enter a second sequence, with the same number of ints: 11 | The machine whirrs briefly before outputting a slip of paper, reading 26 12 | Does that seem right to you? 13 | Enter [y] if you want to move on, and anything else to try again. 14 | Satisfied with your tinkering, you leave the machine behind. 15 | It's almost time for lecture! How are you attending? 16 | >> [li ka shing] [zoom] 17 | -------------------------------------------------------------------------------- /lab03/tests/data/MachineStage/input.txt: -------------------------------------------------------------------------------- 1 | 1, -10, 3 2 | 0, 20, 5 3 | y 4 | li ka shing 5 | -------------------------------------------------------------------------------- /lab03/tests/data/PalindromeStage/answers.txt: -------------------------------------------------------------------------------- 1 | The Woz is a cool name, much better than "Soda 430". Soda 606 is a neat, symmetric conference room, 2 | like its number. We could rename The Woz to be palindromic, but it sounds so cool! Why not change the 3 | room number instead? 4 | (Give a palindromic room number.) 5 | 6 | Wow, nice room number! 7 | Hmm, you're getting hungry. Where do you want to go? 8 | >> [hearst food court] [va cafe] -------------------------------------------------------------------------------- /lab03/tests/data/PalindromeStage/input.txt: -------------------------------------------------------------------------------- 1 | 404 2 | va cafe 3 | go 4 | -------------------------------------------------------------------------------- /lab03/tests/data/SpeciesListStage/answers.txt: -------------------------------------------------------------------------------- 1 | Inside Professor Hug's office, you see some O'Reilly books. These books have cool animals on the 2 | covers. As a budding computer scientist, you should be able to identify all kinds of neat animals. 3 | Here's a few: 4 | 5 | - These large felines with spots will teach you how to react quickly. 6 | - This native american bovine can be found in the plains, and happens to be EXTREMELY good at Java. 7 | - Type their names into the terminal (separated by ',') 8 | Woah! There are even more neat books here! 9 | - These bushy-tailed friends are everywhere in and around the trees on campus, and know the best parts of Java. 10 | - These tiny birds flap very fast, drink nectar, and know how to make simpler Java appplications. 11 | - Type their names into the terminal (separated by ',') 12 | Well, there's nothing left here! press enter to move. 13 | Wow! That was pretty neat! We got to see so many neat animals! We should study now, so let's go to the Woz. 14 | >> [go] -------------------------------------------------------------------------------- /lab03/tests/data/SpeciesListStage/input.txt: -------------------------------------------------------------------------------- 1 | leopards,bison 2 | squirrels,hummingbirds 3 | 4 | go -------------------------------------------------------------------------------- /lab03/tests/puzzle/PuzzleReference.txt: -------------------------------------------------------------------------------- 1 | package puzzle; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.util.Random; 6 | import java.util.Scanner; 7 | 8 | /* NOTE: 9 | * Don't modify any code in this file! 10 | * Otherwise, you'll probably fail the tests. 11 | * If you accidentally modify it, you can always 12 | * restore back to the skeleton code for this specific file. 13 | */ 14 | 15 | public class Puzzle { 16 | 17 | static final File ANSWER_FILE = new File("src/puzzle/answer.txt"); 18 | static int guessThis = 0; 19 | 20 | public static int puzzle() { 21 | int answer = loadAnswer(ANSWER_FILE); 22 | 23 | if (isCorrect(answer)) { 24 | System.out.println("That's correct! Nice work!"); 25 | return answer; 26 | } 27 | 28 | Random r = new Random(); 29 | r.setSeed(1678_971_254); 30 | for (int i = 0; i < 1323; i++) { 31 | if (r.nextInt() == -2034104197) { 32 | erroringMethod(r); 33 | } 34 | } 35 | return 0; 36 | } 37 | 38 | /** Loads an answer from the given file. 39 | * Note: Scanner behaves very similarly to the In class. */ 40 | public static int loadAnswer(File file) { 41 | Scanner s; 42 | try { 43 | s = new Scanner(file); 44 | } catch (FileNotFoundException e) { 45 | throw new RuntimeException(e); 46 | } 47 | while (s.hasNextLine()) { 48 | if (s.hasNextInt()) { 49 | return s.nextInt(); 50 | } 51 | s.nextLine(); 52 | } 53 | throw new RuntimeException("Could not find answer in " + file); 54 | } 55 | 56 | private static boolean isCorrect(int answer) { 57 | return ("" + answer).hashCode() == -32772622; 58 | } 59 | 60 | private static void erroringMethod(Random r) { 61 | String s = null; 62 | System.out.println(""" 63 | Hmm, what is the value of `guessThis` when the out-of-bounds exception is thrown? 64 | Replace the first line of `answer.txt` accordingly. 65 | Hint: Use an exception breakpoint."""); 66 | while (r.nextInt(100) != 10) { 67 | guessThis += r.nextInt(); 68 | s = LOTS_OF_STRINGS[r.nextInt(LOTS_OF_STRINGS.length + 1)]; 69 | } 70 | } 71 | 72 | public static void main(String[] args) { 73 | puzzle(); 74 | } 75 | 76 | private static final String[] LOTS_OF_STRINGS = { 77 | "According", 78 | "to", 79 | "all", 80 | "known", 81 | "laws", 82 | "of", 83 | "aviation,", 84 | "there", 85 | "is", 86 | "no", 87 | "way", 88 | "a", 89 | "bee", 90 | "should", 91 | "be", 92 | "able", 93 | "to", 94 | "fly.", 95 | "Its", 96 | "wings", 97 | "are", 98 | "too", 99 | "small", 100 | "to", 101 | "get", 102 | "its", 103 | "fat", 104 | "little", 105 | "body", 106 | "off", 107 | "the", 108 | "ground." 109 | }; 110 | } 111 | -------------------------------------------------------------------------------- /lab03/tests/puzzle/PuzzleTest.java: -------------------------------------------------------------------------------- 1 | package puzzle; 2 | 3 | import org.junit.Test; 4 | 5 | import java.io.File; 6 | import java.io.FileNotFoundException; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import java.util.Scanner; 10 | 11 | import static com.google.common.truth.Truth.assertThat; 12 | import static com.google.common.truth.Truth.assertWithMessage; 13 | 14 | public class PuzzleTest { 15 | static final File PUZZLE_FILE = new File("src/puzzle/Puzzle.java"); 16 | static final File PUZZLE_REFERENCE = new File("tests/puzzle/PuzzleReference.txt"); 17 | 18 | @Test 19 | public void testPuzzle() { 20 | assertThat(("" + Puzzle.puzzle()).hashCode()).isEqualTo(-32772622); 21 | 22 | assertWithMessage("Looks like you modified Puzzle.java! Be sure to undo those changes.") 23 | .that(readAllLines(PUZZLE_REFERENCE)).isEqualTo(readAllLines(PUZZLE_FILE)); 24 | } 25 | 26 | /** Read all lines of a file into a string list, trimming whitespace. */ 27 | private List readAllLines(File f) { 28 | Scanner s; 29 | try { 30 | s = new Scanner(f); 31 | } catch (FileNotFoundException e) { 32 | throw new RuntimeException(e); 33 | } 34 | List lst = new ArrayList<>(); 35 | while (s.hasNextLine()) { 36 | String clean = s.nextLine().trim(); 37 | if (!clean.isEmpty()) { 38 | lst.add(clean); 39 | } 40 | } 41 | return lst; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lab04/magic_word.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/lab04/magic_word.txt -------------------------------------------------------------------------------- /lab05/src/UnionFind.java: -------------------------------------------------------------------------------- 1 | public class UnionFind { 2 | // TODO: Instance variables 3 | 4 | /* Creates a UnionFind data structure holding N items. Initially, all 5 | items are in disjoint sets. */ 6 | public UnionFind(int N) { 7 | // TODO: YOUR CODE HERE 8 | } 9 | 10 | /* Returns the size of the set V belongs to. */ 11 | public int sizeOf(int v) { 12 | // TODO: YOUR CODE HERE 13 | return -1; 14 | } 15 | 16 | /* Returns the parent of V. If V is the root of a tree, returns the 17 | negative size of the tree for which V is the root. */ 18 | public int parent(int v) { 19 | // TODO: YOUR CODE HERE 20 | return -1; 21 | } 22 | 23 | /* Returns true if nodes/vertices V1 and V2 are connected. */ 24 | public boolean connected(int v1, int v2) { 25 | // TODO: YOUR CODE HERE 26 | return false; 27 | } 28 | 29 | /* Returns the root of the set V belongs to. Path-compression is employed 30 | allowing for fast search-time. If invalid items are passed into this 31 | function, throw an IllegalArgumentException. */ 32 | public int find(int v) { 33 | // TODO: YOUR CODE HERE 34 | return -1; 35 | } 36 | 37 | /* Connects two items V1 and V2 together by connecting their respective 38 | sets. V1 and V2 can be any element, and a union-by-size heuristic is 39 | used. If the sizes of the sets are equal, tie break by connecting V1's 40 | root to V2's root. Union-ing an item with itself or items that are 41 | already connected should not change the structure. */ 42 | public void union(int v1, int v2) { 43 | // TODO: YOUR CODE HERE 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /lab05/tests/UnionFindTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.Test; 2 | 3 | import static com.google.common.truth.Truth.assertThat; 4 | import static com.google.common.truth.Truth.assertWithMessage; 5 | import static org.junit.Assert.fail; 6 | 7 | public class UnionFindTest { 8 | 9 | /** 10 | * Checks that the initial state of the disjoint sets are correct (this will pass with the skeleton 11 | * code, but ensure it still passes after all parts are implemented). 12 | */ 13 | @Test 14 | public void initialStateTest() { 15 | UnionFind uf = new UnionFind(4); 16 | assertThat(uf.connected(0, 1)).isFalse(); 17 | assertThat(uf.connected(0, 2)).isFalse(); 18 | assertThat(uf.connected(0, 3)).isFalse(); 19 | assertThat(uf.connected(1, 2)).isFalse(); 20 | assertThat(uf.connected(1, 3)).isFalse(); 21 | assertThat(uf.connected(2, 3)).isFalse(); 22 | } 23 | 24 | /** 25 | * Checks that invalid inputs are handled correctly. 26 | */ 27 | @Test 28 | public void illegalFindTest() { 29 | UnionFind uf = new UnionFind(4); 30 | try { 31 | uf.find(10); 32 | fail("Cannot find an out of range vertex!"); 33 | } catch (IllegalArgumentException e) { 34 | return; 35 | } 36 | try { 37 | uf.union(1, 10); 38 | fail("Cannot union with an out of range vertex!"); 39 | } catch (IllegalArgumentException e) { 40 | return; 41 | } 42 | } 43 | 44 | /** 45 | * Checks that union is done correctly (including the tie-breaking scheme). 46 | */ 47 | @Test 48 | public void basicUnionTest() { 49 | UnionFind uf = new UnionFind(10); 50 | uf.union(0, 1); 51 | assertThat(uf.find(0)).isEqualTo(1); 52 | uf.union(2, 3); 53 | assertThat(uf.find(2)).isEqualTo(3); 54 | uf.union(0, 2); 55 | assertThat(uf.find(1)).isEqualTo(3); 56 | 57 | uf.union(4, 5); 58 | uf.union(6, 7); 59 | uf.union(8, 9); 60 | uf.union(4, 8); 61 | uf.union(4, 6); 62 | 63 | assertThat(uf.find(5)).isEqualTo(9); 64 | assertThat(uf.find(7)).isEqualTo(9); 65 | assertThat(uf.find(8)).isEqualTo(9); 66 | 67 | uf.union(9, 2); 68 | assertThat(uf.find(3)).isEqualTo(9); 69 | } 70 | 71 | /** 72 | * Unions the same item with itself. Calls on find and checks that the outputs are correct. 73 | */ 74 | @Test 75 | public void sameUnionTest() { 76 | UnionFind uf = new UnionFind(4); 77 | uf.union(1, 1); 78 | for (int i = 0; i < 4; i += 1) { 79 | assertThat(uf.find(i)).isEqualTo(i); 80 | } 81 | } 82 | 83 | /** 84 | * Write your own tests below here to verify for correctness. The given tests are not comprehensive. 85 | * Specifically, you may want to write a test for path compression and to check for the correctness 86 | * of all methods in your implementation. 87 | */ 88 | 89 | } 90 | 91 | 92 | -------------------------------------------------------------------------------- /lab06/src/Map61B.java: -------------------------------------------------------------------------------- 1 | import java.util.Set; 2 | 3 | /* Your implementation BSTMap should implement this interface. To do so, 4 | * append "implements Map61B" to the end of your "public class..." 5 | * declaration, though you can and should use other type parameters when 6 | * necessary. 7 | */ 8 | public interface Map61B extends Iterable { 9 | 10 | /** Associates the specified value with the specified key in this map. 11 | * If the map already contains the specified key, replaces the key's mapping 12 | * with the value specified. */ 13 | void put(K key, V value); 14 | 15 | /** Returns the value to which the specified key is mapped, or null if this 16 | * map contains no mapping for the key. */ 17 | V get(K key); 18 | 19 | /** Returns whether this map contains a mapping for the specified key. */ 20 | boolean containsKey(K key); 21 | 22 | /** Returns the number of key-value mappings in this map. */ 23 | int size(); 24 | 25 | /** Removes every mapping from this map. */ 26 | void clear(); 27 | 28 | /** Returns a Set view of the keys contained in this map. Not required for Lab 7. 29 | * If you don't implement this, throw an UnsupportedOperationException. */ 30 | Set keySet(); 31 | 32 | /** Removes the mapping for the specified key from this map if present, 33 | * or null if there is no such mapping. 34 | * Not required for Lab 7. If you don't implement this, throw an 35 | * UnsupportedOperationException. */ 36 | V remove(K key); 37 | } 38 | -------------------------------------------------------------------------------- /lab06/src/speedTestResults.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/lab06/src/speedTestResults.txt -------------------------------------------------------------------------------- /lab06/tests/StringUtils.java: -------------------------------------------------------------------------------- 1 | import java.util.Random; 2 | import java.util.regex.Pattern; 3 | 4 | /** Utility function for Strings. 5 | * @author Josh Hug 6 | */ 7 | public class StringUtils { 8 | /** To get the style checker to be quiet. */ 9 | private static final int ALPHABET_SIZE = 26; 10 | 11 | /** Random number generator for this class. */ 12 | private static Random r = new Random(); 13 | 14 | /** Sets random seed to L so that results of randomString are predictable.*/ 15 | public static void setSeed(long l) { 16 | r = new Random(l); 17 | } 18 | 19 | /** Returns the next random string of length LENGTH. */ 20 | public static String randomString(int length) { 21 | char[] someChars = new char[length]; 22 | for (int i = 0; i < length; i++) { 23 | someChars[i] = (char) (r.nextInt(ALPHABET_SIZE) + 'a'); 24 | } 25 | return new String(someChars); 26 | } 27 | 28 | /** Returns true if string S consists of characters between 29 | * 'a' and 'z' only. No spaces, numbers, upper-case, or any other 30 | * characters are allowed. 31 | */ 32 | public static boolean isLowerCase(String s) { 33 | return Pattern.matches("[a-z]*", s); 34 | } 35 | 36 | /** Returns the string that comes right after S in alphabetical order. 37 | * For example, if s is 'potato', this method will return 'potatp'. If 38 | * the last character is a z, then we add to the next position, and so 39 | * on. 40 | */ 41 | public static String nextString(String s) { 42 | /* Handle all zs as a special case to keep helper method simple. */ 43 | if (isAllzs(s)) { 44 | return allAs(s.length() + 1); 45 | } 46 | char[] charVersion = s.toCharArray(); 47 | incrementCharArray(charVersion, charVersion.length - 1); 48 | return new String(charVersion); 49 | } 50 | 51 | /** Helper function for nextString. Increments the Pth position of X 52 | * by one, wrapping around to 'a' if p == 'z'. If wraparound occurs, 53 | * then we need to carry the one, and we increment position P - 1. 54 | * 55 | * Will fail for a character array containing only zs. 56 | */ 57 | private static void incrementCharArray(char [] x, int p) { 58 | if (x[p] != 'z') { 59 | x[p] += 1; 60 | } else { 61 | x[p] = 'a'; 62 | incrementCharArray(x, p - 1); 63 | } 64 | } 65 | 66 | /** Returns a string of all 'a' of length LEN. */ 67 | private static String allAs(int len) { 68 | StringBuilder sb = new StringBuilder(); 69 | for (int i = 0; i < len; i++) { 70 | sb.append('a'); 71 | } 72 | return sb.toString(); 73 | } 74 | 75 | /** Returns true if S is all 'z'. False for empty strings */ 76 | public static boolean isAllzs(String s) { 77 | return Pattern.matches("[z]+", s); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /lab08/src/hashmap/Map61B.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import java.util.Set; 4 | 5 | /* Your implementation should implement this interface. To do so, 6 | * append "implements Map61B" to the end of your "public class..." 7 | * declaration, though you can and should use other type parameters when 8 | * necessary. 9 | */ 10 | public interface Map61B extends Iterable { 11 | 12 | /** Associates the specified value with the specified key in this map. 13 | * If the map already contains the specified key, replaces the key's mapping 14 | * with the value specified. */ 15 | void put(K key, V value); 16 | 17 | /** Returns the value to which the specified key is mapped, or null if this 18 | * map contains no mapping for the key. */ 19 | V get(K key); 20 | 21 | /** Returns whether this map contains a mapping for the specified key. */ 22 | boolean containsKey(K key); 23 | 24 | /** Returns the number of key-value mappings in this map. */ 25 | int size(); 26 | 27 | /** Removes every mapping from this map. */ 28 | void clear(); 29 | 30 | /** Returns a Set view of the keys contained in this map. Not required for this lab. 31 | * If you don't implement this, throw an UnsupportedOperationException. */ 32 | Set keySet(); 33 | 34 | /** Removes the mapping for the specified key from this map if present, 35 | * or null if there is no such mapping. 36 | * Not required for this lab. If you don't implement this, throw an 37 | * UnsupportedOperationException. */ 38 | V remove(K key); 39 | } 40 | -------------------------------------------------------------------------------- /lab08/src/hashmap/MyHashMap.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import java.util.Collection; 4 | 5 | /** 6 | * A hash table-backed Map implementation. 7 | * 8 | * Assumes null keys will never be inserted, and does not resize down upon remove(). 9 | * @author YOUR NAME HERE 10 | */ 11 | public class MyHashMap implements Map61B { 12 | 13 | /** 14 | * Protected helper class to store key/value pairs 15 | * The protected qualifier allows subclass access 16 | */ 17 | protected class Node { 18 | K key; 19 | V value; 20 | 21 | Node(K k, V v) { 22 | key = k; 23 | value = v; 24 | } 25 | } 26 | 27 | /* Instance Variables */ 28 | private Collection[] buckets; 29 | // You should probably define some more! 30 | 31 | /** Constructors */ 32 | public MyHashMap() { } 33 | 34 | public MyHashMap(int initialCapacity) { } 35 | 36 | /** 37 | * MyHashMap constructor that creates a backing array of initialCapacity. 38 | * The load factor (# items / # buckets) should always be <= loadFactor 39 | * 40 | * @param initialCapacity initial size of backing array 41 | * @param loadFactor maximum load factor 42 | */ 43 | public MyHashMap(int initialCapacity, double loadFactor) { } 44 | 45 | /** 46 | * Returns a data structure to be a hash table bucket 47 | * 48 | * The only requirements of a hash table bucket are that we can: 49 | * 1. Insert items (`add` method) 50 | * 2. Remove items (`remove` method) 51 | * 3. Iterate through items (`iterator` method) 52 | * Note that that this is referring to the hash table bucket itself, 53 | * not the hash map itself. 54 | * 55 | * Each of these methods is supported by java.util.Collection, 56 | * Most data structures in Java inherit from Collection, so we 57 | * can use almost any data structure as our buckets. 58 | * 59 | * Override this method to use different data structures as 60 | * the underlying bucket type 61 | * 62 | * BE SURE TO CALL THIS FACTORY METHOD INSTEAD OF CREATING YOUR 63 | * OWN BUCKET DATA STRUCTURES WITH THE NEW OPERATOR! 64 | */ 65 | protected Collection createBucket() { 66 | // TODO: Fill in this method. 67 | return null; 68 | } 69 | 70 | // TODO: Implement the methods of the Map61B Interface below 71 | // Your code won't compile until you do so! 72 | 73 | } 74 | -------------------------------------------------------------------------------- /lab08/src/results.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/lab08/src/results.txt -------------------------------------------------------------------------------- /lab08/tests/hashmap/MyHashMapFactory.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import java.util.Collection; 4 | 5 | /** This is a helper factory class that allows us to test different bucket types 6 | * without having to write a separate test for each one. You don't need to understand 7 | * how this works. 8 | * 9 | * Please don't modify this class unless you REALLY know what you're doing. 10 | * 11 | * @author Noah Adhikari, Spring 2023 12 | */ 13 | public class MyHashMapFactory { 14 | 15 | /** Returns a MyHashMap with the specified bucket type. 16 | * @param bucketType the type of bucket to use 17 | */ 18 | public static MyHashMap createBucketedMap(Class bucketType) { 19 | return new MyHashMap<>() { 20 | @Override 21 | protected Collection createBucket() { 22 | try { 23 | return bucketType.getConstructor().newInstance(); 24 | } catch (Exception e) { 25 | throw new RuntimeException(e); 26 | } 27 | } 28 | 29 | // for the timing tests 30 | @Override 31 | public String toString() { 32 | return "MyHashMap with " + bucketType.getSimpleName() + " buckets"; 33 | } 34 | }; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lab08/tests/hashmap/TestMyHashMapExtra.java: -------------------------------------------------------------------------------- 1 | package hashmap; 2 | 3 | import static org.junit.Assert.*; 4 | import org.junit.Test; 5 | 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | import static com.google.common.truth.Truth.assertThat; 9 | 10 | /** Tests of optional parts of lab 8. */ 11 | public class TestMyHashMapExtra { 12 | 13 | @Test 14 | public void testRemove() { 15 | MyHashMap q = new MyHashMap<>(); 16 | q.put("c", "a"); 17 | q.put("b", "a"); 18 | q.put("a", "a"); 19 | q.put("d", "a"); 20 | q.put("e", "a"); // a b c d e 21 | assertThat(q.remove("c")).isNotNull(); 22 | assertThat(q.remove("f")).isNull(); 23 | assertThat(q.containsKey("c")).isFalse(); 24 | assertThat(q.containsKey("a")).isTrue(); 25 | assertThat(q.containsKey("b")).isTrue(); 26 | assertThat(q.containsKey("d")).isTrue(); 27 | assertThat(q.containsKey("e")).isTrue(); 28 | } 29 | 30 | /** 31 | * Remove Test 2 32 | * Test the 3 different cases of remove 33 | */ 34 | @Test 35 | public void testRemoveThreeCases() { 36 | MyHashMap q = new MyHashMap<>(); 37 | q.put("c", "a"); 38 | q.put("b", "a"); 39 | q.put("a", "a"); 40 | q.put("d", "a"); 41 | q.put("e", "a"); // a b c d e 42 | assertThat(q.remove("e")).isNotNull(); // a b c d 43 | assertThat(q.containsKey("a")).isTrue(); 44 | assertThat(q.containsKey("b")).isTrue(); 45 | assertThat(q.containsKey("c")).isTrue(); 46 | assertThat(q.containsKey("d")).isTrue(); 47 | assertThat(q.remove("c")).isNotNull(); // a b d 48 | assertThat(q.containsKey("a")).isTrue(); 49 | assertThat(q.containsKey("b")).isTrue(); 50 | assertThat(q.containsKey("d")).isTrue(); 51 | q.put("f", "a"); // a b d f 52 | assertThat(q.remove("d")).isNotNull(); // a b f 53 | assertThat(q.containsKey("a")).isTrue(); 54 | assertThat(q.containsKey("b")).isTrue(); 55 | assertThat(q.containsKey("f")).isTrue(); 56 | } 57 | 58 | @Test 59 | public void sanityKeySetTest() { 60 | sanityKeySetTest(new MyHashMap<>()); 61 | } 62 | 63 | public static void sanityKeySetTest(MyHashMap b) { 64 | HashSet values = new HashSet(); 65 | for (int i = 0; i < 455; i++) { 66 | b.put("hi" + i, 1); 67 | values.add("hi" + i); 68 | } 69 | assertEquals(455, b.size()); //keys are there 70 | Set keySet = b.keySet(); 71 | assertThat(values).containsExactlyElementsIn(keySet); 72 | assertThat(keySet).containsExactlyElementsIn(values); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lab08/tests/speed/StringUtils.java: -------------------------------------------------------------------------------- 1 | package speed; 2 | 3 | import java.util.regex.Pattern; 4 | import java.util.Random; 5 | 6 | /** Utility function for Strings. 7 | * @author Josh Hug 8 | */ 9 | public class StringUtils { 10 | /** To get the style checker to be quiet. */ 11 | private static final int ALPHABET_SIZE = 26; 12 | 13 | /** Random number generator for this class. */ 14 | private static Random r = new Random(); 15 | 16 | /** Sets random seed to L so that results of randomString are predictable.*/ 17 | public static void setSeed(long l) { 18 | r = new Random(l); 19 | } 20 | 21 | /** Returns the next random string of length LENGTH. */ 22 | public static String randomString(int length) { 23 | char[] someChars = new char[length]; 24 | for (int i = 0; i < length; i++) { 25 | someChars[i] = (char) (r.nextInt(ALPHABET_SIZE) + 'a'); 26 | } 27 | return new String(someChars); 28 | } 29 | 30 | /** 31 | * Returns true if string S consists of characters between 32 | * 'a' and 'z' only. No spaces, numbers, upper-case, or any other 33 | * characters are allowed. 34 | */ 35 | public static boolean isLowerCase(String s) { 36 | return Pattern.matches("[a-z]*", s); 37 | } 38 | 39 | /** 40 | * Returns the string that comes right after S in alphabetical order. 41 | * For example, if s is 'potato', this method will return 'potatp'. If 42 | * the last character is a z, then we add to the next position, and so 43 | * on. 44 | */ 45 | public static String nextString(String s) { 46 | /* Handle all zs as a special case to keep helper method simple. */ 47 | if (isAllzs(s)) { 48 | return allAs(s.length() + 1); 49 | } 50 | char[] charVersion = s.toCharArray(); 51 | incrementCharArray(charVersion, charVersion.length - 1); 52 | return new String(charVersion); 53 | } 54 | 55 | /** 56 | * Helper function for nextString. Increments the Pth position of X 57 | * by one, wrapping around to 'a' if p == 'z'. If wraparound occurs, 58 | * then we need to carry the one, and we increment position P - 1. 59 | * 60 | * Will fail for a character array containing only zs. 61 | */ 62 | private static void incrementCharArray(char [] x, int p) { 63 | if (x[p] != 'z') { 64 | x[p] += 1; 65 | } else { 66 | x[p] = 'a'; 67 | incrementCharArray(x, p - 1); 68 | } 69 | } 70 | 71 | /** Returns a string of all 'a' of length LEN. */ 72 | private static String allAs(int len) { 73 | StringBuilder sb = new StringBuilder(); 74 | for (int i = 0; i < len; i++) { 75 | sb.append('a'); 76 | } 77 | return sb.toString(); 78 | } 79 | 80 | /** Returns true if S is all 'z'. False for empty strings */ 81 | public static boolean isAllzs(String s) { 82 | return Pattern.matches("[z]+", s); 83 | } 84 | 85 | } 86 | 87 | -------------------------------------------------------------------------------- /lab09/patterns/blank.txt: -------------------------------------------------------------------------------- 1 | 50 50 2 | 00000000000000000000000000000000000000000000000000 3 | 00000000000000000000000000000000000000000000000000 4 | 00000000000000000000000000000000000000000000000000 5 | 00000000000000000000000000000000000000000000000000 6 | 00000000000000000000000000000000000000000000000000 7 | 00000000000000000000000000000000000000000000000000 8 | 00000000000000000000000000000000000000000000000000 9 | 00000000000000000000000000000000000000000000000000 10 | 00000000000000000000000000000000000000000000000000 11 | 00000000000000000000000000000000000000000000000000 12 | 00000000000000000000000000000000000000000000000000 13 | 00000000000000000000000000000000000000000000000000 14 | 00000000000000000000000000000000000000000000000000 15 | 00000000000000000000000000000000000000000000000000 16 | 00000000000000000000000000000000000000000000000000 17 | 00000000000000000000000000000000000000000000000000 18 | 00000000000000000000000000000000000000000000000000 19 | 00000000000000000000000000000000000000000000000000 20 | 00000000000000000000000000000000000000000000000000 21 | 00000000000000000000000000000000000000000000000000 22 | 00000000000000000000000000000000000000000000000000 23 | 00000000000000000000000000000000000000000000000000 24 | 00000000000000000000000000000000000000000000000000 25 | 00000000000000000000000000000000000000000000000000 26 | 00000000000000000000000000000000000000000000000000 27 | 00000000000000000000000000000000000000000000000000 28 | 00000000000000000000000000000000000000000000000000 29 | 00000000000000000000000000000000000000000000000000 30 | 00000000000000000000000000000000000000000000000000 31 | 00000000000000000000000000000000000000000000000000 32 | 00000000000000000000000000000000000000000000000000 33 | 00000000000000000000000000000000000000000000000000 34 | 00000000000000000000000000000000000000000000000000 35 | 00000000000000000000000000000000000000000000000000 36 | 00000000000000000000000000000000000000000000000000 37 | 00000000000000000000000000000000000000000000000000 38 | 00000000000000000000000000000000000000000000000000 39 | 00000000000000000000000000000000000000000000000000 40 | 00000000000000000000000000000000000000000000000000 41 | 00000000000000000000000000000000000000000000000000 42 | 00000000000000000000000000000000000000000000000000 43 | 00000000000000000000000000000000000000000000000000 44 | 00000000000000000000000000000000000000000000000000 45 | 00000000000000000000000000000000000000000000000000 46 | 00000000000000000000000000000000000000000000000000 47 | 00000000000000000000000000000000000000000000000000 48 | 00000000000000000000000000000000000000000000000000 49 | 00000000000000000000000000000000000000000000000000 50 | 00000000000000000000000000000000000000000000000000 51 | 00000000000000000000000000000000000000000000000000 52 | -------------------------------------------------------------------------------- /lab09/patterns/glidergun.txt: -------------------------------------------------------------------------------- 1 | 50 50 2 | 00000000000000000000000000000000000000000000000000 3 | 00000000000000000000000000000000000000000000000000 4 | 00000000000000000000000000000000000000000000000000 5 | 00000000000000000000000000000000000000000000000000 6 | 00000000000000000000000000000000000000000001100000 7 | 00000000000000000000000000000000000000000001100000 8 | 00000000000000000000000000000000000000000000000000 9 | 00000000000000000000000000000000000000000000000000 10 | 00000000000000000000000000000000000000000000000000 11 | 00000000000000000000000000000000000000000000000000 12 | 00000000000000000000000000000000000000000000000000 13 | 00000000000000000000000000000000000000000000000000 14 | 00000000000000000000000000000000000000000000000000 15 | 00000000000000000000000000000000000000000000000000 16 | 00000000000000000000000000000000000000000011100000 17 | 00000000000000000000000000000000000000000100010000 18 | 00000000000000000000000000000000000000001000001000 19 | 00000000000000000000000000000000000000001000001000 20 | 00000000000000000000000000000000000000000001000000 21 | 00000000000000000000000000000000000000000100010000 22 | 00000000000000000000000000000000000000000011100000 23 | 00000000000000000000000000000000000000000001000000 24 | 00000000000000000000000000000000000000000000000000 25 | 00000000000000000000000000000000000000000000000000 26 | 00000000000000000000000000000000000000000000111000 27 | 00000000000000000000000000000000000000000000111000 28 | 00000000000000000000000000000000000000000001000100 29 | 00000000000000000000000000000000000000000000000000 30 | 00000000000000000000000000000000000000000011000110 31 | 00000000000000000000000000000000000000000000000000 32 | 00000000000000000000000000000000000000000000000000 33 | 00000000000000000000000000000000000000000000000000 34 | 00000000000000000000000000000000000000000000000000 35 | 00000000000000000000000000000000000000000000000000 36 | 00000000000000000000000000000000000000000000000000 37 | 00000000000000000000000000000000000000000000000000 38 | 00000000000000000000000000000000000000000000000000 39 | 00000000000000000000000000000000000000000000000000 40 | 00000000000000000000000000000000000000000000011000 41 | 00000000000000000000000000000000000000000000011000 42 | 00000000000000000000000000000000000000000000000000 43 | 00000000000000000000000000000000000000000000000000 44 | 00000000000000000000000000000000000000000000000000 45 | 00000000000000000000000000000000000000000000000000 46 | 00000000000000000000000000000000000000000000000000 47 | 00000000000000000000000000000000000000000000000000 48 | 00000000000000000000000000000000000000000000000000 49 | 00000000000000000000000000000000000000000000000000 50 | 00000000000000000000000000000000000000000000000000 51 | 00000000000000000000000000000000000000000000000000 52 | -------------------------------------------------------------------------------- /lab09/patterns/hammerhead.txt: -------------------------------------------------------------------------------- 1 | 50 50 2 | 00000000000000000000000000000000000000000000000000 3 | 00000000000000000000000000000000000000000000000000 4 | 00000000000000000000000000000000000000000000000000 5 | 00000000000000000000000000000000000000000000000000 6 | 00000000000000000000000000000000000000000000000000 7 | 00000000000000000000000000000000000000000000000000 8 | 00000000000000000000000000000000000000000000000000 9 | 00000000000000000000000000000000000000000000000000 10 | 00000000000000000000000000000000000000000000000000 11 | 00000000000000000000000000000000000000000000000000 12 | 00000000000000000000000000000000000000000000000000 13 | 00000000000000000000000000000000000000000000000000 14 | 00000000000000000000000000000000000000000000000000 15 | 00000000000000000000000000000000000000000000000000 16 | 00000000000000000000000000000000000000000000000000 17 | 00000000000000000000000000000000000000000000000000 18 | 00000000000000000000000000000000000000000000000000 19 | 00000000000000000000000000000000000000000000000000 20 | 00000000000000000000000000000000000000000000000000 21 | 00000000000000000000000000000000000000000000000000 22 | 00000000000000000000000000000000000000000000000000 23 | 00000000000000000000000000000000000000000000000000 24 | 00000000000000000000000000000000000000000000000000 25 | 00000000000000000000000000000000000000000000000000 26 | 00000000000000000000000000000000000000000000000000 27 | 00000000000000000000000000000000000000000000000000 28 | 00000000000000000000000000000000000000000000000000 29 | 00000000000000000000000000000000000000000000000000 30 | 00000000000000000000000000000000000000000000000000 31 | 00000000000000000000000000000000000000000000000000 32 | 00000000000000000000000000000000000000000000000000 33 | 00000000000000000011100000000001110000000000000000 34 | 00000000000000000010010000000010010000000000000000 35 | 00000000000000000010000000000000010000000000000000 36 | 00000000000000000010001000000100010000000000000000 37 | 00000000000000000010001000000100010000000000000000 38 | 00000000000000000001000100001000100000000000000000 39 | 00000000000000000000000010010000000000000000000000 40 | 00000000000000000000000001100000000000000000000000 41 | 00000000000000000000001010010100000000000000000000 42 | 00000000000000000000001000000100000000000000000000 43 | 00000000000000000000000110011000000000000000000000 44 | 00000000000000000000011000000110000000000000000000 45 | 00000000000000000000111010010111000000000000000000 46 | 00000000000000000001100100001001100000000000000000 47 | 00000000000000000001010000000010100000000000000000 48 | 00000000000000000000111000000111000000000000000000 49 | 00000000000000000000111000000111000000000000000000 50 | 00000000000000000000110000000011000000000000000000 51 | 00000000000000000000000000000000000000000000000000 52 | -------------------------------------------------------------------------------- /lab09/patterns/pentadecathlon.txt: -------------------------------------------------------------------------------- 1 | 50 50 2 | 00000000000000000000000000000000000000000000000000 3 | 00000000000000000000000000000000000000000000000000 4 | 00000000000000000000000000000000000000000000000000 5 | 00000000000000000000000000000000000000000000000000 6 | 00000000000000000000000000000000000000000000000000 7 | 00000000000000000000000000000000000000000000000000 8 | 00000000000000000000000000000000000000000000000000 9 | 00000000000000000000000000000000000000000000000000 10 | 00000000000000000000000000000000000000000000000000 11 | 00000000000000000000000000000000000000000000000000 12 | 00000000000000000000000000000000000000000000000000 13 | 00000000000000000000000000000000000000000000000000 14 | 00000000000000000000000000000000000000000000000000 15 | 00000000000000000000000000000000000000000000000000 16 | 00000000000000000000000000000000000000000000000000 17 | 00000000000000000000000000000000000000000000000000 18 | 00000000000000000000000000000000000000000000000000 19 | 00000000000000000000000000000000000000000000000000 20 | 00000000000000000000000000000000000000000000000000 21 | 00000000000000000000000000110000000000000000000000 22 | 00000000000000000000000010000100000000000000000000 23 | 00000000000000000000000100000010000000000000000000 24 | 00000000000000000000001000000001000000000000000000 25 | 00000000000000000000001000000001000000000000000000 26 | 00000000000000000000001000000001000000000000000000 27 | 00000000000000000000000100000010000000000000000000 28 | 00000000000000000000000010000100000000000000000000 29 | 00000000000000000000000000110000000000000000000000 30 | 00000000000000000000000000000000000000000000000000 31 | 00000000000000000000000000000000000000000000000000 32 | 00000000000000000000000000000000000000000000000000 33 | 00000000000000000000000000000000000000000000000000 34 | 00000000000000000000000000000000000000000000000000 35 | 00000000000000000000000000000000000000000000000000 36 | 00000000000000000000000000000000000000000000000000 37 | 00000000000000000000000000000000000000000000000000 38 | 00000000000000000000000000000000000000000000000000 39 | 00000000000000000000000000000000000000000000000000 40 | 00000000000000000000000000000000000000000000000000 41 | 00000000000000000000000000000000000000000000000000 42 | 00000000000000000000000000000000000000000000000000 43 | 00000000000000000000000000000000000000000000000000 44 | 00000000000000000000000000000000000000000000000000 45 | 00000000000000000000000000000000000000000000000000 46 | 00000000000000000000000000000000000000000000000000 47 | 00000000000000000000000000000000000000000000000000 48 | 00000000000000000000000000000000000000000000000000 49 | 00000000000000000000000000000000000000000000000000 50 | 00000000000000000000000000000000000000000000000000 51 | 00000000000000000000000000000000000000000000000000 52 | -------------------------------------------------------------------------------- /lab09/src/gameoflife/BoringWorldDemo.java: -------------------------------------------------------------------------------- 1 | package gameoflife; 2 | 3 | import tileengine.TERenderer; 4 | import tileengine.TETile; 5 | import tileengine.Tileset; 6 | 7 | /** 8 | * Draws a world that is mostly empty except for a small region. 9 | */ 10 | public class BoringWorldDemo { 11 | 12 | private static final int WIDTH = 60; 13 | private static final int HEIGHT = 30; 14 | 15 | public static void main(String[] args) { 16 | // initialize the tile rendering engine with a window of size WIDTH x HEIGHT 17 | TERenderer ter = new TERenderer(); 18 | ter.initialize(WIDTH, HEIGHT); 19 | 20 | // initialize tiles 21 | TETile[][] world = new TETile[WIDTH][HEIGHT]; 22 | for (int x = 0; x < WIDTH; x++) { 23 | for (int y = 0; y < HEIGHT; y++) { 24 | world[x][y] = Tileset.NOTHING; 25 | } 26 | } 27 | 28 | // fills in a block 15 tiles wide by 5 tiles tall 29 | for (int x = 20; x < 35; x++) { 30 | for (int y = 5; y < 10; y++) { 31 | world[x][y] = Tileset.WALL; 32 | } 33 | } 34 | 35 | // draws the world to the screen 36 | ter.renderFrame(world); 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /lab09/src/gameoflife/RandomWorldDemo.java: -------------------------------------------------------------------------------- 1 | package gameoflife; 2 | 3 | import tileengine.TERenderer; 4 | import tileengine.TETile; 5 | import tileengine.Tileset; 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * Draws a world that contains RANDOM tiles. 11 | */ 12 | public class RandomWorldDemo { 13 | private static final int WIDTH = 50; 14 | private static final int HEIGHT = 50; 15 | 16 | private static final long SEED = 2873123; 17 | private static final Random RANDOM = new Random(SEED); 18 | 19 | /** 20 | * Fills the given 2D array of tiles with RANDOM tiles. 21 | * @param tiles 22 | */ 23 | public static void fillWithRandomTiles(TETile[][] tiles) { 24 | int height = tiles[0].length; 25 | int width = tiles.length; 26 | for (int x = 0; x < width; x++) { 27 | for (int y = 0; y < height; y++) { 28 | tiles[x][y] = randomTile(); 29 | } 30 | } 31 | } 32 | 33 | /** Picks a RANDOM tile with a 33% change of being 34 | * a wall, 33% chance of being a flower, and 33% 35 | * chance of being empty space. 36 | */ 37 | private static TETile randomTile() { 38 | // The following call to nextInt() uses a bound of 3 (this is not a seed!) so 39 | // the result is bounded between 0, inclusive, and 3, exclusive. (0, 1, or 2) 40 | int tileNum = RANDOM.nextInt(3); 41 | return switch (tileNum) { 42 | case 0 -> Tileset.WALL; 43 | case 1 -> Tileset.FLOWER; 44 | default -> Tileset.NOTHING; 45 | }; 46 | } 47 | 48 | public static void main(String[] args) { 49 | TERenderer ter = new TERenderer(); 50 | ter.initialize(WIDTH, HEIGHT); 51 | 52 | TETile[][] randomTiles = new TETile[WIDTH][HEIGHT]; 53 | fillWithRandomTiles(randomTiles); 54 | 55 | ter.renderFrame(randomTiles); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /lab09/src/save.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/lab09/src/save.txt -------------------------------------------------------------------------------- /lab09/src/tileengine/Tileset.java: -------------------------------------------------------------------------------- 1 | package tileengine; 2 | 3 | import java.awt.Color; 4 | 5 | /** 6 | * Contains constant tile objects, to avoid having to remake the same tiles in different parts of 7 | * the code. 8 | * 9 | * You are free to (and encouraged to) create and add your own tiles to this file. This file will 10 | * be turned in with the rest of your code. 11 | * 12 | * Ex: 13 | * world[x][y] = Tileset.FLOOR; 14 | * 15 | * The style checker may crash when you try to style check this file due to use of unicode 16 | * characters. This is OK. 17 | */ 18 | 19 | public class Tileset { 20 | public static final TETile AVATAR = new TETile('@', Color.white, Color.black, "you"); 21 | public static final TETile WALL = new TETile('#', new Color(216, 128, 128), Color.darkGray, 22 | "wall"); 23 | public static final TETile FLOOR = new TETile('·', new Color(128, 192, 128), Color.black, 24 | "floor"); 25 | public static final TETile NOTHING = new TETile(' ', Color.black, Color.black, "nothing"); 26 | public static final TETile GRASS = new TETile('"', Color.green, Color.black, "grass"); 27 | public static final TETile WATER = new TETile('≈', Color.blue, Color.black, "water"); 28 | public static final TETile FLOWER = new TETile('❀', Color.magenta, Color.pink, "flower"); 29 | public static final TETile LOCKED_DOOR = new TETile('█', Color.orange, Color.black, 30 | "locked door"); 31 | public static final TETile UNLOCKED_DOOR = new TETile('▢', Color.orange, Color.black, 32 | "unlocked door"); 33 | public static final TETile SAND = new TETile('▒', Color.yellow, Color.black, "sand"); 34 | public static final TETile MOUNTAIN = new TETile('▲', Color.gray, Color.black, "mountain"); 35 | public static final TETile TREE = new TETile('♠', Color.green, Color.black, "tree"); 36 | public static final TETile CELL = new TETile('█', Color.white, Color.black, "cell"); 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /lab09/src/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | 7 | /** 8 | * A library of simple file operations. Feel free to modify this file. 9 | */ 10 | public class FileUtils { 11 | /** 12 | * Writes the specified contents to a file with the given filename. 13 | * 14 | * @param filename The name of the file to write to. 15 | * @param contents The contents to write to the file. 16 | * @throws RuntimeException if an IOException occurs during the write operation. 17 | */ 18 | public static void writeFile(String filename, String contents) { 19 | try { 20 | Files.writeString(new File(filename).toPath(), newlineReplacer(contents)); 21 | } catch (IOException ex) { 22 | throw new RuntimeException(ex); 23 | } 24 | } 25 | 26 | /** 27 | * Reads the contents of a file with the given filename. 28 | * 29 | * @param filename The name of the file to read from. 30 | * @return The contents of the file as a String. 31 | * @throws RuntimeException if an IOException occurs during the read operation. 32 | */ 33 | public static String readFile(String filename) { 34 | try { 35 | return newlineReplacer(Files.readString(new File(filename).toPath())); 36 | } catch (IOException ex) { 37 | throw new RuntimeException(ex); 38 | } 39 | } 40 | 41 | /** 42 | * Checks if a file with the given filename exists. 43 | * 44 | * @param filename The name of the file to check for existence. 45 | * @return true if the file exists, false otherwise. 46 | */ 47 | public static boolean fileExists(String filename) { 48 | return new File(filename).exists(); 49 | } 50 | 51 | /** 52 | * Removes '\r' character from strings for improved compatability for this lab between Windows and other systems 53 | * @param contents 54 | * @return contents minus the '\r' char 55 | */ 56 | private static String newlineReplacer(String contents) { 57 | return contents.replace("\r", ""); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lab09/tests/testFiles/loadTest.txt: -------------------------------------------------------------------------------- 1 | 3 3 2 | 000 3 | 000 4 | 000 5 | -------------------------------------------------------------------------------- /lab09/tests/testFiles/saveTest.txt: -------------------------------------------------------------------------------- 1 | 3 4 2 | 010 3 | 011 4 | 100 5 | 010 6 | -------------------------------------------------------------------------------- /lab10/src/magic_word.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/lab10/src/magic_word.txt -------------------------------------------------------------------------------- /lab10/src/tetris/BagRandomizer.java: -------------------------------------------------------------------------------- 1 | package tetris; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Random; 5 | 6 | /** 7 | * A Tetris-accurate Tetromino randomizer. 8 | * This prevents the same Tetromino shape from appearing multiple times in succession. 9 | * 10 | * @author Erik Nelson 11 | */ 12 | 13 | public class BagRandomizer { 14 | 15 | private Random random; 16 | 17 | // A list of current values in the "bag". 18 | ArrayList values; 19 | 20 | // The total capacity of the bag. 21 | int capacity; 22 | 23 | public BagRandomizer(Random r, int n) { 24 | this.random = r; 25 | this.capacity = n; 26 | 27 | refillValues(); 28 | } 29 | 30 | /** 31 | * Resets the values of the bag to contain integers from 0 (inclusive) to capacity (exclusive). 32 | */ 33 | private void refillValues() { 34 | ArrayList newValues = new ArrayList<>(); 35 | for (int i = 0; i < this.capacity; i++) { 36 | newValues.add(i); 37 | } 38 | values = newValues; 39 | } 40 | 41 | /** 42 | * Grabs and removes a random item from the bag. If the bag is empty, refill it. 43 | * @return the removed integer 44 | */ 45 | public int getValue() { 46 | if (values.isEmpty()) { 47 | refillValues(); 48 | } 49 | 50 | int randomIndex = random.nextInt(values.size()); 51 | int randomValue = values.get(randomIndex); 52 | 53 | values.remove(randomIndex); 54 | return randomValue; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lab10/src/tetris/Tetromino.java: -------------------------------------------------------------------------------- 1 | package tetris; 2 | 3 | import tileengine.TETile; 4 | 5 | import java.awt.*; 6 | 7 | /** 8 | * Provides the logic for Tetris. 9 | * 10 | * @author Erik Nelson, Omar Yu, and Noah Adhikari 11 | */ 12 | 13 | public enum Tetromino { 14 | // colors from tetris wiki 15 | I(new Color(0x31e7ef), new boolean[][]{ 16 | {false, false, false, false}, 17 | {true, true, true, true}, 18 | {false, false, false, false}, 19 | {false, false, false, false} 20 | }), 21 | J(new Color(0x5a65ad), new boolean[][]{ 22 | {true, false, false}, 23 | {true, true, true}, 24 | {false, false, false}, 25 | }), 26 | L(new Color(0xef7921), new boolean[][]{ 27 | {false, false, true}, 28 | {true, true, true}, 29 | {false, false, false}, 30 | }), 31 | O(new Color(0xf7d308), new boolean[][]{ 32 | {true, true}, 33 | {true, true}, 34 | }), 35 | S(new Color(0x42b642), new boolean[][]{ 36 | {false, true, true}, 37 | {true, true, false}, 38 | {false, false, false} 39 | }), 40 | T(new Color(0xad4d9c), new boolean[][]{ 41 | {false, true, false}, 42 | {true, true, true}, 43 | {false, false, false}, 44 | }), 45 | Z(new Color(0xef2029), new boolean[][]{ 46 | {true, true, false}, 47 | {false, true, true}, 48 | {false, false, false} 49 | }); 50 | 51 | private final TETile tile; 52 | boolean[][] shape; 53 | int width; 54 | int height; 55 | 56 | Point pos; 57 | 58 | Tetromino(Color color, boolean[][] s) { 59 | this.tile = new TETile('█', color, Color.BLACK, "", 0); 60 | // need to convert from ij to xy coords because tile renderer coordinates are mismatched 61 | this.shape = ijToXY(s); 62 | this.width = shape[0].length; 63 | this.height = shape.length; 64 | this.pos = new Point(3, 20); 65 | } 66 | 67 | /** Converts from ij coordinates to xy coordinates. This is specifically for converting 68 | * the 2D boolean array representation of a piece to the tile rendering coordinates, since 69 | * orientation is not aligned. 70 | */ 71 | private static boolean[][] ijToXY(boolean[][] ijArr) { 72 | int numRows = ijArr.length; 73 | int numCols = ijArr[0].length; 74 | boolean[][] result = new boolean[numCols][numRows]; 75 | for (int x = 0; x < numCols; x++) { 76 | for (int y = 0; y < numRows; y++) { 77 | result[x][y] = ijArr[numRows - y - 1][x]; 78 | } 79 | } 80 | return result; 81 | } 82 | 83 | 84 | /** 85 | * Draws the piece at the given coordinates of the given board. (x,y) = 0,0 is bottom-left. 86 | * Does not do bounds-checking. 87 | */ 88 | public static void draw(Tetromino t, TETile[][] board, int bx, int by) { 89 | for (int tx = 0; tx < t.width; tx++) { 90 | for (int ty = 0; ty < t.height; ty++) { 91 | if (t.shape[tx][ty]) { 92 | board[bx + tx][by + ty] = t.tile; 93 | } 94 | } 95 | } 96 | } 97 | 98 | /** 99 | * Sets the point of a Tetromino to (3, 20), specifically for spawning. 100 | */ 101 | public void reset() { 102 | this.pos = new Point(3, 20); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /lab10/src/tileengine/Tileset.java: -------------------------------------------------------------------------------- 1 | package tileengine; 2 | 3 | import java.awt.Color; 4 | 5 | /** 6 | * Contains constant tile objects, to avoid having to remake the same tiles in different parts of 7 | * the code. 8 | * 9 | * You are free to (and encouraged to) create and add your own tiles to this file. This file will 10 | * be turned in with the rest of your code. 11 | * 12 | * Ex: 13 | * world[x][y] = Tileset.FLOOR; 14 | * 15 | * The style checker may crash when you try to style check this file due to use of unicode 16 | * characters. This is OK. 17 | */ 18 | 19 | public class Tileset { 20 | public static final TETile AVATAR = new TETile('@', Color.white, Color.black, "you", 0); 21 | public static final TETile WALL = new TETile('#', new Color(216, 128, 128), Color.darkGray, 22 | "wall", 1); 23 | public static final TETile FLOOR = new TETile('·', new Color(128, 192, 128), Color.black, "floor", 2); 24 | public static final TETile NOTHING = new TETile(' ', Color.black, Color.black, "nothing", 3); 25 | public static final TETile GRASS = new TETile('"', Color.green, Color.black, "grass", 4); 26 | public static final TETile WATER = new TETile('≈', Color.blue, Color.black, "water", 5); 27 | public static final TETile FLOWER = new TETile('❀', Color.magenta, Color.pink, "flower", 6); 28 | public static final TETile LOCKED_DOOR = new TETile('█', Color.orange, Color.black, 29 | "locked door", 7); 30 | public static final TETile UNLOCKED_DOOR = new TETile('▢', Color.orange, Color.black, 31 | "unlocked door", 8); 32 | public static final TETile SAND = new TETile('▒', Color.yellow, Color.black, "sand", 9); 33 | public static final TETile MOUNTAIN = new TETile('▲', Color.gray, Color.black, "mountain", 10); 34 | public static final TETile TREE = new TETile('♠', Color.green, Color.black, "tree", 11); 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /lab10/src/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | 7 | /** 8 | * A library of simple file operations. Feel free to modify this file. 9 | */ 10 | public class FileUtils { 11 | /** 12 | * Writes the specified contents to a file with the given filename. 13 | * 14 | * @param filename The name of the file to write to. 15 | * @param contents The contents to write to the file. 16 | * @throws RuntimeException if an IOException occurs during the write operation. 17 | */ 18 | public static void writeFile(String filename, String contents) { 19 | try { 20 | Files.writeString(new File(filename).toPath(), contents); 21 | } catch (IOException ex) { 22 | throw new RuntimeException(ex); 23 | } 24 | } 25 | 26 | /** 27 | * Reads the contents of a file with the given filename. 28 | * 29 | * @param filename The name of the file to read from. 30 | * @return The contents of the file as a String. 31 | * @throws RuntimeException if an IOException occurs during the read operation. 32 | */ 33 | public static String readFile(String filename) { 34 | try { 35 | return Files.readString(new File(filename).toPath()); 36 | } catch (IOException ex) { 37 | throw new RuntimeException(ex); 38 | } 39 | } 40 | 41 | /** 42 | * Checks if a file with the given filename exists. 43 | * 44 | * @param filename The name of the file to check for existence. 45 | * @return true if the file exists, false otherwise. 46 | */ 47 | public static boolean fileExists(String filename) { 48 | return new File(filename).exists(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /proj0/skeleton2.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /proj0/src/game2048rendering/GUI.java: -------------------------------------------------------------------------------- 1 | package game2048rendering; 2 | 3 | import game2048logic.Model; 4 | import ucb.gui2.TopLevel; 5 | import ucb.gui2.LayoutSpec; 6 | 7 | import java.util.concurrent.ArrayBlockingQueue; 8 | 9 | import java.awt.event.KeyEvent; 10 | 11 | 12 | /** The GUI controller for a 2048 board and buttons. 13 | * @author P. N. Hilfinger 14 | */ 15 | class GUI extends TopLevel { 16 | 17 | /** A new window with given TITLE providing a view of MODEL. */ 18 | GUI(String title, Model model) { 19 | super(title, true); 20 | addMenuButton("Game->New", this::newGame); 21 | addMenuButton("Game->Quit", this::quit); 22 | 23 | addLabel("", "Score", new LayoutSpec("y", 1)); 24 | 25 | _model = model; 26 | 27 | _widget = new BoardWidget(model.size()); 28 | add(_widget, 29 | new LayoutSpec("y", 0, 30 | "height", "REMAINDER", 31 | "width", "REMAINDER")); 32 | 33 | _widget.requestFocusInWindow(); 34 | _widget.setKeyHandler("keypress", this::keyPressed); 35 | setPreferredFocus(_widget); 36 | setScore(0); 37 | } 38 | 39 | /** Response to "Quit" button click. */ 40 | private void quit(String dummy) { 41 | _pendingKeys.offer("Quit"); 42 | _widget.requestFocusInWindow(); 43 | } 44 | 45 | /** Response to "New Game" button click. */ 46 | private void newGame(String dummy) { 47 | _pendingKeys.offer("New Game"); 48 | _widget.requestFocusInWindow(); 49 | } 50 | 51 | /** Respond to the user pressing key E by queuing the key on our 52 | * queue of pending keys.*/ 53 | private void keyPressed(String unused, KeyEvent e) { 54 | _pendingKeys.offer(e.getKeyCode() + ""); 55 | } 56 | 57 | /** Return the next pending event, waiting for it as necessary. 58 | * Ordinary key presses are reported as the key codes of the 59 | * character pressed. In addition, menu-button clicks result in 60 | * the messages "Quit" or "New Game". */ 61 | private String readKey() { 62 | try { 63 | return _pendingKeys.take(); 64 | } catch (InterruptedException excp) { 65 | throw new Error("unexpected interrupt"); 66 | } 67 | } 68 | 69 | /** Return which direction arrow was pressed. */ 70 | String getKey() { 71 | String command = readKey(); 72 | switch (command) { 73 | case "↑" -> command = "Up"; 74 | case "→" -> command = "Right"; 75 | case "↓" -> command = "Down"; 76 | case "←" -> command = "Left"; 77 | default -> {} 78 | } 79 | 80 | return command; 81 | } 82 | 83 | /** Set the current score being displayed to SCORE. */ 84 | private void setScore(int score) { 85 | setLabel("Score", String.format("Score: %6d", score)); 86 | } 87 | 88 | /** Plays an animation to update the GUI to the new state of the board. */ 89 | void update() { 90 | _widget.update(_model); 91 | setScore(_model.score()); 92 | } 93 | 94 | /** The board widget. */ 95 | private final BoardWidget _widget; 96 | 97 | /** The game model being viewed. */ 98 | private final Model _model; 99 | 100 | /** Queue of pending key presses. */ 101 | private final ArrayBlockingQueue _pendingKeys = 102 | new ArrayBlockingQueue<>(5); 103 | 104 | } 105 | -------------------------------------------------------------------------------- /proj0/src/game2048rendering/Main.java: -------------------------------------------------------------------------------- 1 | package game2048rendering; 2 | 3 | import game2048logic.Model; 4 | 5 | /** The main class for the 2048 game. 6 | * @author P. N. Hilfinger 7 | */ 8 | public class Main { 9 | /** Probability of choosing 2 as random tile (as opposed to 4). */ 10 | static final double TILE2_PROBABILITY = 0.9; 11 | 12 | /** Number of squares on the side of a board. */ 13 | static final int BOARD_SIZE = 4; 14 | 15 | /** Random seed. Ignored if 0. */ 16 | static final long RANDOM_SEED = 0; 17 | 18 | /** If true, the custom start is used. Otherwise, the board starts off blank. */ 19 | static final boolean USE_CUSTOM_START = false; 20 | 21 | /** Custom starting state of the game. Useful for debugging. */ 22 | static final Model CUSTOM_START = new Model(new int[][]{ 23 | {2, 0, 2, 128}, 24 | {0, 0, 8, 0}, 25 | {8, 64, 0, 128}, 26 | {4, 64, 8, 256}, 27 | }, 0); 28 | 29 | public static void main(String[] args) { 30 | Model model = USE_CUSTOM_START ? CUSTOM_START : new Model(BOARD_SIZE); 31 | 32 | GUI gui = new GUI("2048 61B", model); 33 | gui.display(true); 34 | 35 | Game game = new Game(model, gui, TILE2_PROBABILITY, RANDOM_SEED); 36 | try { 37 | game.playGame(USE_CUSTOM_START); 38 | while (game.playing()) { 39 | game.playGame(false); 40 | } 41 | } catch (IllegalStateException excp) { 42 | System.err.printf("Internal error: %s%n", excp.getMessage()); 43 | System.exit(1); 44 | } 45 | 46 | System.exit(0); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /proj0/src/game2048rendering/Side.java: -------------------------------------------------------------------------------- 1 | package game2048rendering; 2 | 3 | /** Symbolic names for the four sides of a board. 4 | * @author P. N. Hilfinger */ 5 | public enum Side { 6 | /** The parameters (COL0, ROW0, DCOL, and DROW) for each of the 7 | * symbolic directions, D, below are to be interpreted as follows: 8 | * The board's standard orientation has the top of the board 9 | * as NORTH, and rows and columns (see Model) are numbered 10 | * from its lower-left corner. Consider the board oriented 11 | * so that side D of the board is farthest from you. Then 12 | * * (COL0*s, ROW0*s) are the standard coordinates of the 13 | * lower-left corner of the reoriented board (where s is the 14 | * board size), and 15 | * * If (x, y) are the standard coordinates of a certain 16 | * square on the reoriented board, then (x+DCOL, y+DROW) 17 | * are the standard coordinates of the squares immediately 18 | * above it on the reoriented board. 19 | * The idea behind going to this trouble is that by using the 20 | * x() and y() methods below to translate from reoriented to 21 | * standard coordinates, one can arrange to use exactly the same code 22 | * to compute the result of tilting the board in any particular 23 | * direction. */ 24 | 25 | NORTH(0, 0, 0, 1), 26 | EAST(0, 1, 1, 0), 27 | SOUTH(1, 1, 0, -1), 28 | WEST(1, 0, -1, 0); 29 | 30 | /** The side that is in the direction (DCOL, DROW) from any square 31 | * of the board. Here, "direction (DCOL, DROW) means that to 32 | * move one space in the direction of this Side increases the row 33 | * by DROW and the colunn by DCOL. (COL0, ROW0) are the row and 34 | * column of the lower-left square when sitting at the board facing 35 | * towards this Side. */ 36 | Side(int col0, int row0, int dcol, int drow) { 37 | this._row0 = row0; 38 | this._col0 = col0; 39 | this._drow = drow; 40 | this._dcol = dcol; 41 | } 42 | 43 | /** Return the standard x-coordinate for square (x, y) on a board 44 | * of size SIZE oriented with this Side on top. */ 45 | int x(int x, int y, int size) { 46 | return _col0 * (size - 1) + x * _drow + y * _dcol; 47 | } 48 | 49 | /** Return the standard y-coordinate for square (x, y) on a board 50 | * of size SIZE oriented with this Side on top. */ 51 | int y(int x, int y, int size) { 52 | return _row0 * (size - 1) - x * _dcol + y * _drow; 53 | } 54 | 55 | /** Parameters describing this Side, as documented in the comment at the 56 | * start of this class. */ 57 | private final int _row0, _col0, _drow, _dcol; 58 | } 59 | -------------------------------------------------------------------------------- /proj0/src/game2048rendering/Tile.java: -------------------------------------------------------------------------------- 1 | package game2048rendering; 2 | 3 | /** Represents the image of a numbered tile on a 2048 board. 4 | * @author P. N. Hilfinger. 5 | */ 6 | public class Tile { 7 | 8 | /** A new tile with VALUE as its value at (x, y). This 9 | * constructor is private, so all tiles are created by the 10 | * factory method create. */ 11 | private Tile(int value, int x, int y) { 12 | this._value = value; 13 | this._x = x; 14 | this._y = y; 15 | this._next = null; 16 | this._merged = false; 17 | } 18 | 19 | /** Return whether this tile was already merged. */ 20 | public boolean wasMerged() { 21 | return _merged; 22 | } 23 | 24 | void setMerged(boolean merged) { 25 | this._merged = merged; 26 | } 27 | 28 | /** Return my current y-coordinate. */ 29 | int y() { 30 | return _y; 31 | } 32 | 33 | /** Return my current x-coordinate. */ 34 | int x() { 35 | return _x; 36 | } 37 | 38 | /** Return the value supplied to my constructor. */ 39 | public int value() { 40 | return _value; 41 | } 42 | 43 | /** Return my next state. Before I am moved or merged, I am my 44 | * own successor. */ 45 | Tile next() { 46 | return _next == null ? this : _next; 47 | } 48 | 49 | /** Set my next state when I am moved or merged. */ 50 | void setNext(Tile otherTile) { 51 | _next = otherTile; 52 | } 53 | 54 | /** Return a new tile at (x, y) with value VALUE. */ 55 | public static Tile create(int value, int x, int y) { 56 | return new Tile(value, x, y); 57 | } 58 | 59 | /** Return the distance in rows or columns between me and my successor 60 | * tile (0 if I have no successor). */ 61 | int distToNext() { 62 | if (_next == null) { 63 | return 0; 64 | } else { 65 | return Math.max(Math.abs(_y - _next.y()), 66 | Math.abs(_x - _next.x())); 67 | } 68 | } 69 | 70 | @Override 71 | public String toString() { 72 | return String.format("Tile %d at position (%d, %d)", value(), x(), y()); 73 | } 74 | 75 | /** My value. */ 76 | private final int _value; 77 | 78 | /** My last position on the board. */ 79 | private final int _x; 80 | private final int _y; 81 | 82 | /** Whether I have merged. */ 83 | private boolean _merged; 84 | 85 | /** Successor tile: one I am moved to or merged with. */ 86 | private Tile _next; 87 | } 88 | -------------------------------------------------------------------------------- /proj0/tests/game2048logic/TestTask5.java: -------------------------------------------------------------------------------- 1 | package game2048logic; 2 | import org.junit.jupiter.api.DisplayName; 3 | import org.junit.jupiter.api.Tag; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.Timeout; 6 | 7 | import static com.google.common.truth.Truth.assertWithMessage; 8 | 9 | /** Tests the moveTileUpAsFarAsPossible() method of Model. 10 | * Does not expect merge or score to be implemented. 11 | * 12 | * 13 | * @author Erik Kizior 14 | */ 15 | @Timeout(value = 60, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) 16 | public class TestTask5 { 17 | 18 | /** No merging required. */ 19 | @Test 20 | @Tag("task5") 21 | @DisplayName("Single tile in empty column") 22 | public void testOneTile() { 23 | int[][] board = { 24 | {0, 0, 0, 0}, 25 | {0, 0, 0, 0}, 26 | {0, 0, 0, 0}, 27 | {2, 0, 0, 0} 28 | }; 29 | Model before = new Model(board, 0); 30 | before.moveTileUpAsFarAsPossible(0, 0); 31 | 32 | int[][] result = { 33 | {2, 0, 0, 0}, 34 | {0, 0, 0, 0}, 35 | {0, 0, 0, 0}, 36 | {0, 0, 0, 0} 37 | }; 38 | 39 | Model after = new Model(result, 0); 40 | assertWithMessage("Boards should match:").that(before.toString()).isEqualTo(after.toString()); 41 | } 42 | 43 | /** No merging required. Tile blocks movement. */ 44 | @Test 45 | @Tag("task5") 46 | @DisplayName("two tiles, different values") 47 | public void testTwoTiles() { 48 | int[][] board = { 49 | {4, 0, 0, 0}, 50 | {0, 0, 0, 0}, 51 | {0, 0, 0, 0}, 52 | {2, 0, 0, 0} 53 | }; 54 | Model before = new Model(board, 0); 55 | before.moveTileUpAsFarAsPossible(0, 0); 56 | 57 | int[][] result = { 58 | {4, 0, 0, 0}, 59 | {2, 0, 0, 0}, 60 | {0, 0, 0, 0}, 61 | {0, 0, 0, 0} 62 | }; 63 | 64 | Model after = new Model(result, 0); 65 | assertWithMessage("Boards should match:").that(before.toString()).isEqualTo(after.toString()); 66 | } 67 | 68 | /** No merging required. Board shouldn't change. */ 69 | @Test 70 | @Tag("task5") 71 | @DisplayName("one tile, no movement") 72 | public void testTileWithItself() { 73 | int[][] board = { 74 | {4, 0, 0, 0}, 75 | {0, 0, 0, 0}, 76 | {0, 0, 0, 0}, 77 | {0, 0, 0, 0} 78 | }; 79 | Model before = new Model(board, 0); 80 | before.moveTileUpAsFarAsPossible(0, 3); 81 | 82 | int[][] result = { 83 | {4, 0, 0, 0}, 84 | {0, 0, 0, 0}, 85 | {0, 0, 0, 0}, 86 | {0, 0, 0, 0} 87 | }; 88 | 89 | Model after = new Model(result, 0); 90 | assertWithMessage("Boards should match:").that(before.toString()).isEqualTo(after.toString()); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /proj0/tests/game2048logic/TestTask8.java: -------------------------------------------------------------------------------- 1 | package game2048logic; 2 | import game2048rendering.Side; 3 | import org.junit.jupiter.api.DisplayName; 4 | import org.junit.jupiter.api.Tag; 5 | import org.junit.jupiter.api.Test; 6 | import org.junit.jupiter.api.Timeout; 7 | 8 | import static com.google.common.truth.Truth.assertWithMessage; 9 | import static game2048logic.TestUtils.checkTilt; 10 | 11 | /** Tests the tilt() method in the up (Side.NORTH) direction only. 12 | * 13 | * @author Omar Khan, Erik Kizior 14 | */ 15 | @Timeout(value = 60, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) 16 | public class TestTask8 { 17 | 18 | /** Move tiles up (no merging). */ 19 | @Test 20 | @Tag("task8") 21 | @DisplayName("Up Tilt") 22 | public void testUpNoMerge() { 23 | int[][] before = new int[][] { 24 | {0, 0, 4, 0}, 25 | {0, 0, 0, 2}, 26 | {0, 0, 0, 0}, 27 | {0, 0, 0, 0}, 28 | }; 29 | int[][] after = new int[][] { 30 | {0, 0, 4, 2}, 31 | {0, 0, 0, 0}, 32 | {0, 0, 0, 0}, 33 | {0, 0, 0, 0}, 34 | }; 35 | checkTilt(new Model(before, 0), new Model(after, 0), Side.NORTH); 36 | } 37 | 38 | /** Move tiles up with a merge. Must merge in the proper order. Score does not matter. */ 39 | @Test 40 | @Tag("task8") 41 | @DisplayName("Up Tilt") 42 | public void testUpMergeNoSkips() { 43 | int[][] board = new int[][] { 44 | {4, 4, 4, 4}, 45 | {2, 2, 2, 2}, 46 | {2, 2, 2, 2}, 47 | {4, 4, 4, 4}, 48 | }; 49 | 50 | Model before = new Model(board, 0); 51 | before.tiltWrapper(Side.NORTH); 52 | 53 | int[][] result = new int[][] { 54 | {4, 4, 4, 4}, 55 | {4, 4, 4, 4}, 56 | {4, 4, 4, 4}, 57 | {0, 0, 0, 0}, 58 | }; 59 | 60 | Model after = new Model(result, before.score()); 61 | assertWithMessage("Boards should match:").that(before.toString()).isEqualTo(after.toString()); 62 | } 63 | 64 | /** Move tiles up with trickier merges. Score does not matter. */ 65 | @Test 66 | @Tag("task8") 67 | @DisplayName("Up Tilt") 68 | public void testUpComplicated() { 69 | int[][] board = new int[][] { 70 | {4, 4, 4, 0}, 71 | {0, 4, 8, 2}, 72 | {2, 4, 2, 2}, 73 | {4, 4, 2, 0}, 74 | }; 75 | 76 | Model before = new Model(board, 0); 77 | before.tiltWrapper(Side.NORTH); 78 | 79 | int[][] result = new int[][] { 80 | {4, 8, 4, 4}, 81 | {2, 8, 8, 0}, 82 | {4, 0, 4, 0}, 83 | {0, 0, 0, 0}, 84 | }; 85 | 86 | Model after = new Model(result, before.score()); 87 | assertWithMessage("Boards should match:").that(before.toString()).isEqualTo(after.toString()); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /proj0/tests/game2048logic/TestUtils.java: -------------------------------------------------------------------------------- 1 | package game2048logic; 2 | 3 | import game2048rendering.Side; 4 | 5 | import static com.google.common.truth.Truth.assertWithMessage; 6 | 7 | public class TestUtils { 8 | 9 | /** 10 | * Checks that performing a tilt in the specified direction on the before 11 | * Model results in the after Model 12 | */ 13 | public static void checkTilt(Model before, Model after, Side direction) { 14 | String prevBoard = before.toString(); 15 | before.tiltWrapper(direction); 16 | String errMsg = String.format("Board incorrect. Before tilting towards" 17 | + " %s, your board looked like:%s%nAfter the call to" 18 | + " tilt, we expected:%s%nBut your board looks like:%s.", 19 | direction, prevBoard, after, before); 20 | assertWithMessage(errMsg).that(before).isEqualTo(after); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /proj1a/src/deque/Deque61B.java: -------------------------------------------------------------------------------- 1 | package deque; 2 | import java.util.List; 3 | 4 | /** 5 | * Created by hug on 2/4/2017. Methods are provided in the suggested order 6 | * that they should be completed. 7 | */ 8 | public interface Deque61B { 9 | 10 | /** 11 | * Add {@code x} to the front of the deque. Assumes {@code x} is never null. 12 | * 13 | * @param x item to add 14 | */ 15 | void addFirst(T x); 16 | 17 | /** 18 | * Add {@code x} to the back of the deque. Assumes {@code x} is never null. 19 | * 20 | * @param x item to add 21 | */ 22 | void addLast(T x); 23 | 24 | /** 25 | * Returns a List copy of the deque. Does not alter the deque. 26 | * 27 | * @return a new list copy of the deque. 28 | */ 29 | List toList(); 30 | 31 | /** 32 | * Returns if the deque is empty. Does not alter the deque. 33 | * 34 | * @return {@code true} if the deque has no elements, {@code false} otherwise. 35 | */ 36 | boolean isEmpty(); 37 | 38 | /** 39 | * Returns the size of the deque. Does not alter the deque. 40 | * 41 | * @return the number of items in the deque. 42 | */ 43 | int size(); 44 | 45 | /** 46 | * Remove and return the element at the front of the deque, if it exists. 47 | * 48 | * @return removed element, otherwise {@code null}. 49 | */ 50 | T removeFirst(); 51 | 52 | /** 53 | * Remove and return the element at the back of the deque, if it exists. 54 | * 55 | * @return removed element, otherwise {@code null}. 56 | */ 57 | T removeLast(); 58 | 59 | /** 60 | * The Deque61B abstract data type does not typically have a get method, 61 | * but we've included this extra operation to provide you with some 62 | * extra programming practice. Gets the element, iteratively. Returns 63 | * null if index is out of bounds. Does not alter the deque. 64 | * 65 | * @param index index to get 66 | * @return element at {@code index} in the deque 67 | */ 68 | T get(int index); 69 | 70 | /** 71 | * This method technically shouldn't be in the interface, but it's here 72 | * to make testing nice. Gets an element, recursively. Returns null if 73 | * index is out of bounds. Does not alter the deque. 74 | * 75 | * @param index index to get 76 | * @return element at {@code index} in the deque 77 | */ 78 | T getRecursive(int index); 79 | } -------------------------------------------------------------------------------- /proj1a/src/gh2/GuitarHeroLite.java: -------------------------------------------------------------------------------- 1 | package gh2; 2 | 3 | import edu.princeton.cs.algs4.StdAudio; 4 | import edu.princeton.cs.algs4.StdDraw; 5 | 6 | /** 7 | * A client that uses the synthesizer package to replicate a plucked guitar string sound 8 | */ 9 | public class GuitarHeroLite { 10 | private static final double CONCERT_A = 440.0; 11 | private static final double CONCERT_C = CONCERT_A * Math.pow(2, 3.0 / 12.0); 12 | private static final int WIDTH = 512; 13 | private static final int HEIGHT = 512; 14 | 15 | public static void main(String[] args) { 16 | /* create two guitar strings, for concert A and C */ 17 | GuitarString stringA = new GuitarString(CONCERT_A); 18 | GuitarString stringC = new GuitarString(CONCERT_C); 19 | StdDraw.setCanvasSize(WIDTH, HEIGHT); 20 | StdDraw.setXscale(0, WIDTH); 21 | StdDraw.setYscale(0, HEIGHT); 22 | StdDraw.setPenColor(StdDraw.BLACK); 23 | StdDraw.setPenRadius(0.05); 24 | StdDraw.text(WIDTH / 2, (HEIGHT + 16) / 2, "Play the guitar!"); 25 | StdDraw.text(WIDTH / 2, (HEIGHT - 32) / 2, "Type A or C"); 26 | while (true) { 27 | 28 | /* check if the user has typed a key; if so, process it */ 29 | if (StdDraw.hasNextKeyTyped()) { 30 | char key = StdDraw.nextKeyTyped(); 31 | if (key == 'a') { 32 | StdDraw.clear(); 33 | StdDraw.text(WIDTH / 2, HEIGHT / 2, "A"); 34 | 35 | StdDraw.show(); 36 | stringA.pluck(); 37 | 38 | } else if (key == 'c') { 39 | StdDraw.clear(); 40 | StdDraw.text(WIDTH / 2, HEIGHT / 2, "C"); 41 | StdDraw.show(); 42 | 43 | stringC.pluck(); 44 | } 45 | } 46 | 47 | /* compute the superposition of samples */ 48 | double sample = stringA.sample() + stringC.sample(); 49 | 50 | /* play the sample on standard audio */ 51 | StdAudio.play(sample); 52 | 53 | /* advance the simulation of each guitar string by one step */ 54 | stringA.tic(); 55 | stringC.tic(); 56 | 57 | } 58 | } 59 | } 60 | 61 | -------------------------------------------------------------------------------- /proj1a/src/gh2/GuitarString.java: -------------------------------------------------------------------------------- 1 | package gh2; 2 | import deque.*; 3 | 4 | // TODO: maybe more imports 5 | 6 | //Note: This file will not compile until you complete the Deque61B implementations 7 | public class GuitarString { 8 | /** Constants. Do not change. In case you're curious, the keyword final 9 | * means the values cannot be changed at runtime. We'll discuss this and 10 | * other topics in lecture on Friday. */ 11 | private static final int SR = 44100; // Sampling Rate 12 | private static final double DECAY = .996; // energy decay factor 13 | 14 | /* Buffer for storing sound data. */ 15 | // TODO: uncomment the following line once you're ready to start this portion 16 | // private Deque61B buffer; 17 | 18 | /* Create a guitar string of the given frequency. */ 19 | public GuitarString(double frequency) { 20 | // TODO: Initialize the buffer with capacity = SR / frequency. You'll need to 21 | // cast the result of this division operation into an int. For 22 | // better accuracy, use the Math.round() function before casting. 23 | // Your should initially fill your buffer with zeros. 24 | } 25 | 26 | 27 | /* Pluck the guitar string by replacing the buffer with white noise. */ 28 | public void pluck() { 29 | // TODO: Dequeue everything in buffer, and replace with random numbers 30 | // between -0.5 and 0.5. You can get such a number by using: 31 | // double r = Math.random() - 0.5; 32 | // 33 | // Make sure that your random numbers are different from each 34 | // other. This does not mean that you need to check that the numbers 35 | // are different from each other. It means you should repeatedly call 36 | // Math.random() - 0.5 to generate new random numbers for each array index. 37 | } 38 | 39 | /* Advance the simulation one time step by performing one iteration of 40 | * the Karplus-Strong algorithm. 41 | */ 42 | public void tic() { 43 | // TODO: Dequeue the front sample and enqueue a new sample that is 44 | // the average of the two multiplied by the DECAY factor. 45 | // **Do not call StdAudio.play().** 46 | } 47 | 48 | /* Return the double at the front of the buffer. */ 49 | public double sample() { 50 | // TODO: Return the correct thing. 51 | return 0; 52 | } 53 | } 54 | // TODO: Remove all comments that say TODO when you're done. 55 | -------------------------------------------------------------------------------- /proj1a/tests/LinkedListDeque61BTest.java: -------------------------------------------------------------------------------- 1 | import jh61b.utils.Reflection; 2 | import org.junit.jupiter.api.DisplayName; 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static com.google.common.truth.Truth.assertThat; 6 | import static com.google.common.truth.Truth.assertWithMessage; 7 | 8 | import deque.*; 9 | 10 | /** Performs some basic linked list tests. */ 11 | public class LinkedListDeque61BTest { 12 | 13 | // @Test 14 | // /** In this test, we have three different assert statements that verify that addFirst works correctly. */ 15 | // public void addFirstTestBasic() { 16 | // Deque61B lld1 = new LinkedListDeque61B<>(); 17 | 18 | // lld1.addFirst("back"); // after this call we expect: ["back"] 19 | // assertThat(lld1.toList()).containsExactly("back").inOrder(); 20 | 21 | // lld1.addFirst("middle"); // after this call we expect: ["middle", "back"] 22 | // assertThat(lld1.toList()).containsExactly("middle", "back").inOrder(); 23 | 24 | // lld1.addFirst("front"); // after this call we expect: ["front", "middle", "back"] 25 | // assertThat(lld1.toList()).containsExactly("front", "middle", "back").inOrder(); 26 | 27 | // /* Note: The first two assertThat statements aren't really necessary. For example, it's hard 28 | // to imagine a bug in your code that would lead to ["front"] and ["front", "middle"] failing, 29 | // but not ["front", "middle", "back"]. 30 | // */ 31 | // } 32 | 33 | // @Test 34 | // /** In this test, we use only one assertThat statement. IMO this test is just as good as addFirstTestBasic. 35 | // * In other words, the tedious work of adding the extra assertThat statements isn't worth it. */ 36 | // public void addLastTestBasic() { 37 | // Deque61B lld1 = new LinkedListDeque61B<>(); 38 | 39 | // lld1.addLast("front"); // after this call we expect: ["front"] 40 | // lld1.addLast("middle"); // after this call we expect: ["front", "middle"] 41 | // lld1.addLast("back"); // after this call we expect: ["front", "middle", "back"] 42 | // assertThat(lld1.toList()).containsExactly("front", "middle", "back").inOrder(); 43 | // } 44 | 45 | // @Test 46 | // /** This test performs interspersed addFirst and addLast calls. */ 47 | // public void addFirstAndAddLastTest() { 48 | // Deque61B lld1 = new LinkedListDeque61B<>(); 49 | 50 | // /* I've decided to add in comments the state after each call for the convenience of the 51 | // person reading this test. Some programmers might consider this excessively verbose. */ 52 | // lld1.addLast(0); // [0] 53 | // lld1.addLast(1); // [0, 1] 54 | // lld1.addFirst(-1); // [-1, 0, 1] 55 | // lld1.addLast(2); // [-1, 0, 1, 2] 56 | // lld1.addFirst(-2); // [-2, -1, 0, 1, 2] 57 | 58 | // assertThat(lld1.toList()).containsExactly(-2, -1, 0, 1, 2).inOrder(); 59 | // } 60 | 61 | // Below, you'll write your own tests for LinkedListDeque61B. 62 | } -------------------------------------------------------------------------------- /proj1a/tests/TestGuitarString.java: -------------------------------------------------------------------------------- 1 | /* Imports the required audio library from the 2 | * edu.princeton.cs.algs4 package. */ 3 | import edu.princeton.cs.algs4.StdAudio; 4 | import org.junit.jupiter.api.Test; 5 | import gh2.GuitarString; 6 | 7 | import static com.google.common.truth.Truth.assertThat; 8 | import static com.google.common.truth.Truth.assertWithMessage; 9 | 10 | /** Tests the GuitarString class. 11 | * @author Josh Hug 12 | */ 13 | public class TestGuitarString { 14 | 15 | @Test 16 | public void testPluckTheAString() { 17 | double CONCERT_A = 440.0; 18 | GuitarString aString = new GuitarString(CONCERT_A); 19 | aString.pluck(); 20 | for (int i = 0; i < 50000; i += 1) { 21 | StdAudio.play(aString.sample()); 22 | aString.tic(); 23 | } 24 | } 25 | 26 | @Test 27 | public void testSample() { 28 | GuitarString s = new GuitarString(100); 29 | assertThat(s.sample()).isEqualTo(0.0); 30 | assertThat(s.sample()).isEqualTo(0.0); 31 | assertThat(s.sample()).isEqualTo(0.0); 32 | s.pluck(); 33 | 34 | double sample = s.sample(); 35 | assertWithMessage("After plucking, your samples should not be 0").that(sample).isNotEqualTo(0); 36 | 37 | String errorMsg = "Sample should not change the state of your string"; 38 | assertWithMessage(errorMsg).that(s.sample()).isWithin(0.0).of(sample); 39 | assertWithMessage(errorMsg).that(s.sample()).isWithin(0.0).of(sample); 40 | } 41 | 42 | @Test 43 | public void testTic() { 44 | GuitarString s = new GuitarString(100); 45 | assertThat(s.sample()).isEqualTo(0.0); 46 | assertThat(s.sample()).isEqualTo(0.0); 47 | assertThat(s.sample()).isEqualTo(0.0); 48 | s.pluck(); 49 | 50 | double sample1 = s.sample(); 51 | assertWithMessage("After plucking, your samples should not be 0").that(sample1).isNotEqualTo(0); 52 | 53 | s.tic(); 54 | String errorMsg = "After tic(), your samples should not stay the same"; 55 | assertWithMessage(errorMsg).that(s.sample()).isNotEqualTo(sample1); 56 | } 57 | 58 | @Test 59 | public void testTicCalculations() { 60 | // Create a GuitarString of frequency 11025, which 61 | // is a Deque61B of length 4. 62 | GuitarString s = new GuitarString(11025); 63 | s.pluck(); 64 | 65 | // Record the front four values, ticcing as we go. 66 | double s1 = s.sample(); 67 | s.tic(); 68 | double s2 = s.sample(); 69 | s.tic(); 70 | double s3 = s.sample(); 71 | s.tic(); 72 | double s4 = s.sample(); 73 | 74 | // If we tic once more, it should be equal to 0.996*0.5*(s1 + s2) 75 | s.tic(); 76 | 77 | double s5 = s.sample(); 78 | double expected = 0.996 * 0.5 * (s1 + s2); 79 | 80 | // Check that new sample is correct, using tolerance of 0.001. 81 | String errorMsg = "Wrong tic value. Try running the testTic method in TestGuitarString.java"; 82 | assertWithMessage(errorMsg).that(s5).isWithin(0.001).of(expected); 83 | } 84 | } 85 | 86 | -------------------------------------------------------------------------------- /proj1b/src/Deque61B.java: -------------------------------------------------------------------------------- 1 | import java.util.List; 2 | 3 | /** 4 | * Created by hug on 2/4/2017. Methods are provided in the suggested order 5 | * that they should be completed. 6 | */ 7 | public interface Deque61B { 8 | 9 | /** 10 | * Add {@code x} to the front of the deque. Assumes {@code x} is never null. 11 | * 12 | * @param x item to add 13 | */ 14 | void addFirst(T x); 15 | 16 | /** 17 | * Add {@code x} to the back of the deque. Assumes {@code x} is never null. 18 | * 19 | * @param x item to add 20 | */ 21 | void addLast(T x); 22 | 23 | /** 24 | * Returns a List copy of the deque. Does not alter the deque. 25 | * 26 | * @return a new list copy of the deque. 27 | */ 28 | List toList(); 29 | 30 | /** 31 | * Returns if the deque is empty. Does not alter the deque. 32 | * 33 | * @return {@code true} if the deque has no elements, {@code false} otherwise. 34 | */ 35 | boolean isEmpty(); 36 | 37 | /** 38 | * Returns the size of the deque. Does not alter the deque. 39 | * 40 | * @return the number of items in the deque. 41 | */ 42 | int size(); 43 | 44 | /** 45 | * Remove and return the element at the front of the deque, if it exists. 46 | * 47 | * @return removed element, otherwise {@code null}. 48 | */ 49 | T removeFirst(); 50 | 51 | /** 52 | * Remove and return the element at the back of the deque, if it exists. 53 | * 54 | * @return removed element, otherwise {@code null}. 55 | */ 56 | T removeLast(); 57 | 58 | /** 59 | * The Deque61B abstract data type does not typically have a get method, 60 | * but we've included this extra operation to provide you with some 61 | * extra programming practice. Gets the element, iteratively. Returns 62 | * null if index is out of bounds. Does not alter the deque. 63 | * 64 | * @param index index to get 65 | * @return element at {@code index} in the deque 66 | */ 67 | T get(int index); 68 | 69 | /** 70 | * This method technically shouldn't be in the interface, but it's here 71 | * to make testing nice. Gets an element, recursively. Returns null if 72 | * index is out of bounds. Does not alter the deque. 73 | * 74 | * @param index index to get 75 | * @return element at {@code index} in the deque 76 | */ 77 | T getRecursive(int index); 78 | } -------------------------------------------------------------------------------- /proj1b/tests/ArrayDeque61BPreconditionTest.java: -------------------------------------------------------------------------------- 1 | import jh61b.utils.Reflection; 2 | import org.junit.jupiter.api.DisplayName; 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.lang.reflect.Field; 6 | import java.util.List; 7 | 8 | import static com.google.common.truth.Truth.assertWithMessage; 9 | 10 | public class ArrayDeque61BPreconditionTest { 11 | 12 | @Test 13 | @DisplayName("ArrayDeque61B has no fields besides backing array and primitives") 14 | void noNonTrivialFields() { 15 | List badFields = Reflection.getFields(ArrayDeque61B.class) 16 | .filter(f -> !(f.getType().isPrimitive() || f.getType().equals(Object[].class) || f.isSynthetic())) 17 | .toList(); 18 | 19 | assertWithMessage("Found fields that are not array or primitives").that(badFields).isEmpty(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /proj1b/tests/ArrayDeque61BTest.java: -------------------------------------------------------------------------------- 1 | import jh61b.utils.Reflection; 2 | import org.junit.jupiter.api.DisplayName; 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.lang.reflect.Field; 6 | import java.util.List; 7 | 8 | import static com.google.common.truth.Truth.assertThat; 9 | import static com.google.common.truth.Truth.assertWithMessage; 10 | 11 | public class ArrayDeque61BTest { 12 | 13 | // @Test 14 | // @DisplayName("ArrayDeque61B has no fields besides backing array and primitives") 15 | // void noNonTrivialFields() { 16 | // List badFields = Reflection.getFields(ArrayDeque61B.class) 17 | // .filter(f -> !(f.getType().isPrimitive() || f.getType().equals(Object[].class) || f.isSynthetic())) 18 | // .toList(); 19 | // 20 | // assertWithMessage("Found fields that are not array or primitives").that(badFields).isEmpty(); 21 | // } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /proj1b/tests/MaxArrayDeque61BTest.java: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.*; 2 | 3 | import java.util.Comparator; 4 | 5 | import static com.google.common.truth.Truth.assertThat; 6 | import static com.google.common.truth.Truth.assertWithMessage; 7 | 8 | public class MaxArrayDeque61BTest { 9 | private static class StringLengthComparator implements Comparator { 10 | public int compare(String a, String b) { 11 | return a.length() - b.length(); 12 | } 13 | } 14 | // @Test 15 | // public void basicTest() { 16 | // MaxArrayDeque61B mad = new MaxArrayDeque61B<>(new StringLengthComparator()); 17 | // mad.addFirst(""); 18 | // mad.addFirst("2"); 19 | // mad.addFirst("fury road"); 20 | // assertThat(mad.max()).isEqualTo("fury road"); 21 | // } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /proj2a/src/browser/NgordnetQuery.java: -------------------------------------------------------------------------------- 1 | package browser; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by hug. 7 | */ 8 | public record NgordnetQuery(List words, 9 | int startYear, 10 | int endYear, 11 | int k) { 12 | } 13 | -------------------------------------------------------------------------------- /proj2a/src/browser/NgordnetQueryHandler.java: -------------------------------------------------------------------------------- 1 | package browser; 2 | 3 | import com.google.gson.Gson; 4 | import spark.QueryParamsMap; 5 | import spark.Request; 6 | import spark.Response; 7 | import spark.Route; 8 | 9 | import java.util.Arrays; 10 | import java.util.List; 11 | 12 | public abstract class NgordnetQueryHandler implements Route { 13 | public abstract String handle(browser.NgordnetQuery q); 14 | private static final Gson gson = new Gson(); 15 | 16 | private static List commaSeparatedStringToList(String s) { 17 | String[] requestedWords = s.split(","); 18 | for (int i = 0; i < requestedWords.length; i += 1) { 19 | requestedWords[i] = requestedWords[i].trim(); 20 | } 21 | return Arrays.asList(requestedWords); 22 | } 23 | 24 | private static browser.NgordnetQuery readQueryMap(QueryParamsMap qm) { 25 | List words = commaSeparatedStringToList(qm.get("words").value()); 26 | 27 | int startYear; 28 | int endYear; 29 | int k; 30 | 31 | try { 32 | startYear = Integer.parseInt(qm.get("startYear").value()); 33 | } catch(RuntimeException e) { 34 | startYear = 1900; 35 | } 36 | 37 | try { 38 | endYear = Integer.parseInt(qm.get("endYear").value()); 39 | } catch(RuntimeException e) { 40 | endYear = 2020; 41 | } 42 | 43 | try { 44 | k = Integer.parseInt(qm.get("k").value()); 45 | } catch(RuntimeException e) { 46 | k = 0; 47 | } 48 | 49 | return new browser.NgordnetQuery(words, startYear, endYear, k); 50 | } 51 | 52 | @Override 53 | public String handle(Request request, Response response) throws Exception { 54 | QueryParamsMap qm = request.queryMap(); 55 | NgordnetQuery nq = readQueryMap(qm); 56 | String queryResult = handle(nq); 57 | return gson.toJson(queryResult); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /proj2a/src/browser/NgordnetServer.java: -------------------------------------------------------------------------------- 1 | package browser; 2 | 3 | import static spark.Spark.*; 4 | 5 | /** 6 | * Created by hug. 7 | */ 8 | public class NgordnetServer { 9 | public void register(String URL, NgordnetQueryHandler nqh) { 10 | get(URL, nqh); 11 | } 12 | 13 | public void startUp() { 14 | staticFiles.externalLocation("static"); 15 | 16 | /* Allow for all origin requests (since this is not an authenticated server, we do not 17 | * care about CSRF). */ 18 | before((request, response) -> { 19 | response.header("Access-Control-Allow-Origin", "*"); 20 | response.header("Access-Control-Request-Method", "*"); 21 | response.header("Access-Control-Allow-Headers", "*"); 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /proj2a/src/main/DummyHistoryHandler.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import browser.NgordnetQuery; 4 | import browser.NgordnetQueryHandler; 5 | import ngrams.TimeSeries; 6 | import plotting.Plotter; 7 | import org.knowm.xchart.XYChart; 8 | 9 | import java.util.ArrayList; 10 | 11 | 12 | public class DummyHistoryHandler extends NgordnetQueryHandler { 13 | @Override 14 | public String handle(NgordnetQuery q) { 15 | System.out.println("Got query that looks like:"); 16 | System.out.println("Words: " + q.words()); 17 | System.out.println("Start Year: " + q.startYear()); 18 | System.out.println("End Year: " + q.endYear()); 19 | 20 | System.out.println("But I'm totally ignoring that and just plotting a parabola\n" + 21 | "and a sine wave, because your job will be to figure out how to\n" + 22 | "actually use the query data."); 23 | 24 | TimeSeries parabola = new TimeSeries(); 25 | for (int i = 1400; i < 1500; i += 1) { 26 | parabola.put(i, (i - 50.0) * (i - 50.0) + 3); 27 | } 28 | 29 | TimeSeries sinWave = new TimeSeries(); 30 | for (int i = 1400; i < 1500; i += 1) { 31 | sinWave.put(i, 1000 + 500 * Math.sin(i/100.0*2*Math.PI)); 32 | } 33 | 34 | ArrayList lts = new ArrayList<>(); 35 | ArrayList labels = new ArrayList<>(); 36 | 37 | labels.add("parabola"); 38 | labels.add("sine wave"); 39 | 40 | lts.add(parabola); 41 | lts.add(sinWave); 42 | 43 | XYChart chart = Plotter.generateTimeSeriesChart(labels, lts); 44 | String encodedImage = Plotter.encodeChartAsString(chart); 45 | 46 | return encodedImage; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /proj2a/src/main/DummyHistoryTextHandler.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import browser.NgordnetQuery; 4 | import browser.NgordnetQueryHandler; 5 | 6 | import java.util.List; 7 | 8 | public class DummyHistoryTextHandler extends NgordnetQueryHandler { 9 | @Override 10 | public String handle(NgordnetQuery q) { 11 | List words = q.words(); 12 | int startYear = q.startYear(); 13 | int endYear = q.endYear(); 14 | 15 | String response = "You entered the following info into the browser:\n"; 16 | response += "Words: " + q.words() + "\n"; 17 | response += "Start Year: " + q.startYear() + "\n"; 18 | response += "End Year: " + q.endYear() + "\n"; 19 | return response; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /proj2a/src/main/FileReadDemo.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import edu.princeton.cs.algs4.In; 4 | 5 | import static utils.Utils.*; 6 | 7 | public class FileReadDemo { 8 | public static void main(String[] args) { 9 | In in = new In(SHORT_WORDS_FILE); 10 | int i = 0; 11 | 12 | while (!in.isEmpty()) { 13 | i += 1; 14 | String nextLine = in.readLine(); 15 | System.out.print("Line " + i + " is: "); 16 | System.out.println(nextLine); 17 | System.out.print("After splitting on tab characters, the first word is: "); 18 | String[] splitLine = nextLine.split("\t"); 19 | System.out.println(splitLine[0]); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /proj2a/src/main/Main.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import static utils.Utils.*; 4 | 5 | import org.slf4j.LoggerFactory; 6 | 7 | import browser.NgordnetServer; 8 | 9 | public class Main { 10 | static { 11 | LoggerFactory.getLogger(Main.class).info("\033[1;38mChanging text color to white"); 12 | } 13 | /* Do not delete or modify the code above! */ 14 | 15 | public static void main(String[] args) { 16 | NgordnetServer hns = new NgordnetServer(); 17 | 18 | /* The following code might be useful to you. 19 | 20 | NGramMap ngm = new NGramMap(SHORT_WORDS_FILE, TOTAL_COUNTS_FILE); 21 | 22 | */ 23 | 24 | hns.startUp(); 25 | hns.register("history", new DummyHistoryHandler()); 26 | hns.register("historytext", new DummyHistoryTextHandler()); 27 | 28 | System.out.println("Finished server startup! Visit http://localhost:4567/ngordnet_2a.html"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /proj2a/src/main/PlotDemo.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import ngrams.NGramMap; 4 | import ngrams.TimeSeries; 5 | import plotting.Plotter; 6 | import org.knowm.xchart.XYChart; 7 | 8 | import static utils.Utils.*; 9 | import java.util.ArrayList; 10 | 11 | public class PlotDemo { 12 | public static void main(String[] args) { 13 | 14 | NGramMap ngm = new NGramMap(TOP_14337_WORDS_FILE, TOTAL_COUNTS_FILE); 15 | ArrayList words = new ArrayList<>(); 16 | words.add("cat"); 17 | words.add("dog"); 18 | 19 | ArrayList lts = new ArrayList<>(); 20 | for (String word : words) { 21 | lts.add(ngm.weightHistory(word, 1900, 1950)); 22 | } 23 | 24 | XYChart chart = Plotter.generateTimeSeriesChart(words, lts); 25 | String s = Plotter.encodeChartAsString(chart); 26 | System.out.println(s); 27 | 28 | // you can also do this to display locally: 29 | // Plotter.displayChart(chart); 30 | 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /proj2a/src/ngrams/TimeSeries.java: -------------------------------------------------------------------------------- 1 | package ngrams; 2 | 3 | import java.util.List; 4 | import java.util.TreeMap; 5 | 6 | /** 7 | * An object for mapping a year number (e.g. 1996) to numerical data. Provides 8 | * utility methods useful for data analysis. 9 | * 10 | * @author Josh Hug 11 | */ 12 | public class TimeSeries extends TreeMap { 13 | 14 | /** If it helps speed up your code, you can assume year arguments to your NGramMap 15 | * are between 1400 and 2100. We've stored these values as the constants 16 | * MIN_YEAR and MAX_YEAR here. */ 17 | public static final int MIN_YEAR = 1400; 18 | public static final int MAX_YEAR = 2100; 19 | 20 | /** 21 | * Constructs a new empty TimeSeries. 22 | */ 23 | public TimeSeries() { 24 | super(); 25 | } 26 | 27 | /** 28 | * Creates a copy of TS, but only between STARTYEAR and ENDYEAR, 29 | * inclusive of both end points. 30 | */ 31 | public TimeSeries(TimeSeries ts, int startYear, int endYear) { 32 | super(); 33 | // TODO: Fill in this constructor. 34 | } 35 | 36 | /** 37 | * Returns all years for this time series in ascending order. 38 | */ 39 | public List years() { 40 | // TODO: Fill in this method. 41 | return null; 42 | } 43 | 44 | /** 45 | * Returns all data for this time series. Must correspond to the 46 | * order of years(). 47 | */ 48 | public List data() { 49 | // TODO: Fill in this method. 50 | return null; 51 | } 52 | 53 | /** 54 | * Returns the year-wise sum of this TimeSeries with the given TS. In other words, for 55 | * each year, sum the data from this TimeSeries with the data from TS. Should return a 56 | * new TimeSeries (does not modify this TimeSeries). 57 | * 58 | * If both TimeSeries don't contain any years, return an empty TimeSeries. 59 | * If one TimeSeries contains a year that the other one doesn't, the returned TimeSeries 60 | * should store the value from the TimeSeries that contains that year. 61 | */ 62 | public TimeSeries plus(TimeSeries ts) { 63 | // TODO: Fill in this method. 64 | return null; 65 | } 66 | 67 | /** 68 | * Returns the quotient of the value for each year this TimeSeries divided by the 69 | * value for the same year in TS. Should return a new TimeSeries (does not modify this 70 | * TimeSeries). 71 | * 72 | * If TS is missing a year that exists in this TimeSeries, throw an 73 | * IllegalArgumentException. 74 | * If TS has a year that is not in this TimeSeries, ignore it. 75 | */ 76 | public TimeSeries dividedBy(TimeSeries ts) { 77 | // TODO: Fill in this method. 78 | return null; 79 | } 80 | 81 | // TODO: Add any private helper methods. 82 | // TODO: Remove all TODO comments before submitting. 83 | } 84 | -------------------------------------------------------------------------------- /proj2a/src/plotting/Plotter.java: -------------------------------------------------------------------------------- 1 | package plotting; 2 | 3 | import ngrams.TimeSeries; 4 | import org.knowm.xchart.BitmapEncoder; 5 | import org.knowm.xchart.SwingWrapper; 6 | import org.knowm.xchart.XYChart; 7 | 8 | import javax.imageio.ImageIO; 9 | import java.awt.image.BufferedImage; 10 | import java.io.ByteArrayOutputStream; 11 | import java.io.IOException; 12 | import java.util.Base64; 13 | import java.util.List; 14 | 15 | public class Plotter { 16 | 17 | public static XYChart generateTimeSeriesChart(List words, List lts) { 18 | if (words.size() != lts.size()) { 19 | throw new IllegalArgumentException("List of words and List of time series objects must be the same length"); 20 | } 21 | 22 | XYChart chart = new XYChart(800, 600); 23 | 24 | for (int i = 0; i < words.size(); i += 1) { 25 | TimeSeries ts = lts.get(i); 26 | String word = words.get(i); 27 | chart.addSeries(word, ts.years(), ts.data()); 28 | } 29 | 30 | return chart; 31 | } 32 | 33 | public static void displayChart(XYChart chart) { 34 | new SwingWrapper(chart).displayChart(); 35 | } 36 | 37 | public static String encodeChartAsString(XYChart chart) { 38 | BufferedImage img = BitmapEncoder.getBufferedImage(chart); 39 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 40 | 41 | try { 42 | ImageIO.write(img, "png", os); 43 | } catch (IOException e) { 44 | e.printStackTrace(); 45 | } 46 | 47 | String encodedImage = Base64.getEncoder().encodeToString(os.toByteArray()); 48 | return encodedImage; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /proj2a/src/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | /** A collection of file paths to data files. Make sure your data folder is on the same 4 | * level as "src". 5 | */ 6 | public class Utils { 7 | private static final String PREFIX = "./data/ngrams/"; 8 | public static final String TOP_14337_WORDS_FILE = PREFIX + "top_14377_words.csv"; 9 | public static final String TOP_49887_WORDS_FILE = PREFIX + "top_49887_words.csv"; 10 | public static final String Q_WORDS_FILE = PREFIX + "words_that_start_with_q.csv"; 11 | public static final String SHORT_WORDS_FILE = PREFIX + "very_short.csv"; 12 | public static final String TOTAL_COUNTS_FILE = PREFIX + "total_counts.csv"; 13 | public static final String SHORTER_WORDS_FILE = PREFIX + "less_short.csv"; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /proj2a/static/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/proj2a/static/blank.png -------------------------------------------------------------------------------- /proj2a/static/ngordnet.css: -------------------------------------------------------------------------------- 1 | .textresult { 2 | overflow-y: auto; 3 | height: 600px; 4 | width: 800px; 5 | resize: none; 6 | display: none; 7 | padding: 0px; 8 | margin: 0px; 9 | } 10 | .hiddentext { 11 | display: none; 12 | } 13 | .btn { 14 | text-decoration: none; 15 | color: #fff; 16 | background-color: #d14836; 17 | background-image: -webkit-linear-gradient(top,#dd4b39,#d14836); 18 | background-image: linear-gradient(top,#dd4b39,#d14836); 19 | color: #fff; 20 | border: 1px solid transparent; 21 | text-align: center; 22 | letter-spacing: .5px; 23 | transition: .2s ease-out; 24 | cursor: pointer; 25 | border: none; 26 | border-radius: 0.25rem; 27 | display: inline-block; 28 | height: 36px; 29 | line-height: 36px; 30 | padding: 0 2rem; 31 | margin: .5rem 0; 32 | text-transform: uppercase; 33 | vertical-align: middle; 34 | -webkit-tap-highlight-color: transparent; 35 | } 36 | .btn:hover { 37 | box-shadow: 0 0 0px .25rem #d14836; 38 | } 39 | img, textarea { 40 | border-radius: .5rem; 41 | height: auto; 42 | transform: translateX(-50%); 43 | max-width: 100%; 44 | left: 50%; 45 | position: relative; 46 | border: 3px solid black; 47 | } 48 | table { 49 | position: relative; 50 | transform: translateX(-50%); 51 | left: 50%; 52 | } 53 | input { 54 | width: calc(100% - 1rem); 55 | max-width: 180px; 56 | border: 1px solid black; 57 | border-radius: 3px; 58 | padding: .25rem; 59 | } 60 | -------------------------------------------------------------------------------- /proj2a/static/ngordnet.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

14 | 15 | 16 | 17 |

18 | 19 | 20 | 21 | 25 | 29 | 33 | 37 | 38 |
22 | words
23 |
24 |
26 | start
27 |
28 |
30 | end
31 |
32 |
34 | k
35 |
36 |
39 | 40 | 41 | 43 | 46 | 48 | 49 | 50 | 51 |
42 |
history
44 |
history (text)
45 |
47 |
hyponyms
52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /proj2a/static/ngordnet.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | plot = document.getElementById('plot'); 3 | textresult = document.getElementById('textresult'); 4 | 5 | var host; 6 | 7 | host = 'http://localhost:4567'; 8 | const history_server = host + '/history'; 9 | const historytext_server = host + '/historytext'; 10 | const hyponyms_server = host + '/hyponyms'; 11 | 12 | function get_params() { 13 | return { 14 | words: document.getElementById('words').value, 15 | startYear: document.getElementById('start').value, 16 | endYear: document.getElementById('end').value, 17 | k: document.getElementById('k').value 18 | } 19 | } 20 | 21 | $('#history').click(historyButton); 22 | $('#historytext').click(historyTextButton); 23 | $('#hyponyms').click(hyponymsButton); 24 | 25 | function historyButton() { 26 | $("#textresult").hide(); 27 | $("#plot").show(); 28 | 29 | var params = get_params(); 30 | console.log(params); 31 | $.get({ 32 | async: false, 33 | url: history_server, 34 | data: params, 35 | success: function(data) { 36 | console.log(data) 37 | 38 | plot.src = 'data:image/png;base64,' + data; 39 | 40 | }, 41 | error: function(data) { 42 | console.log("error") 43 | console.log(data); 44 | plot.src = 'data:image/png;base64,' + data; 45 | }, 46 | dataType: 'json' 47 | }); 48 | } 49 | 50 | function historyTextButton() { 51 | console.log("history text call"); 52 | $("#plot").hide(); 53 | $("#textresult").show(); 54 | 55 | var params = get_params(); 56 | console.log(params); 57 | $.get({ 58 | async: false, 59 | url: historytext_server, 60 | data: params, 61 | success: function(data) { 62 | console.log(data) 63 | 64 | textresult.value = data; 65 | 66 | }, 67 | error: function(data) { 68 | console.log("error") 69 | console.log(data); 70 | }, 71 | dataType: 'json' 72 | }); 73 | } 74 | 75 | function hyponymsButton() { 76 | console.log("hyponyms call"); 77 | $("#plot").hide(); 78 | $("#textresult").show(); 79 | 80 | var params = get_params(); 81 | console.log(params); 82 | $.get({ 83 | async: false, 84 | url: hyponyms_server, 85 | data: params, 86 | success: function(data) { 87 | console.log(data) 88 | 89 | textresult.value = data; 90 | 91 | }, 92 | error: function(data) { 93 | console.log("error") 94 | console.log(data); 95 | }, 96 | dataType: 'json' 97 | }); 98 | } 99 | 100 | }); -------------------------------------------------------------------------------- /proj2a/static/ngordnet_2a.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

14 | 15 | 16 | 17 |

18 | 19 | 20 | 21 | 25 | 29 | 33 | 37 | 38 |
22 | words
23 |
24 |
26 | start
27 |
28 |
30 | end
31 |
32 |
34 |
35 |
36 |
39 | 40 | 41 | 43 | 46 | 58 | 59 | 60 |
42 |
history
44 |
history (text)
45 |
61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /proj2a/tests/HistoryTextHandlerTest.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | import browser.NgordnetQuery; 4 | import main.HistoryTextHandler; 5 | import ngrams.NGramMap; 6 | 7 | import org.junit.jupiter.api.Test; 8 | import java.util.List; 9 | 10 | import static utils.Utils.*; 11 | import static com.google.common.truth.Truth.assertThat; 12 | */ 13 | 14 | // uncomment this test whenever you are ready! 15 | public class HistoryTextHandlerTest { 16 | /* 17 | @Test 18 | public void testHandle() { 19 | NGramMap ngm = new NGramMap(SHORT_WORDS_FILE, TOTAL_COUNTS_FILE); 20 | HistoryTextHandler handler = new HistoryTextHandler(ngm); 21 | NgordnetQuery query = new NgordnetQuery(List.of("request", "airport"), 2006, 2007, 0); 22 | String actual = handler.handle(query); 23 | String expected = """ 24 | request: {2006=2.44740192927834E-5, 2007=2.464488338318067E-5} 25 | airport: {2007=6.2068176510855946E-6} 26 | """; 27 | assertThat(actual).isEqualTo(expected); 28 | } 29 | */ 30 | } 31 | -------------------------------------------------------------------------------- /proj2a/tests/TimeSeriesTest.java: -------------------------------------------------------------------------------- 1 | import ngrams.TimeSeries; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import static com.google.common.truth.Truth.assertThat; 10 | 11 | /** Unit Tests for the TimeSeries class. 12 | * @author Josh Hug 13 | */ 14 | public class TimeSeriesTest { 15 | @Test 16 | public void testFromSpec() { 17 | TimeSeries catPopulation = new TimeSeries(); 18 | catPopulation.put(1991, 0.0); 19 | catPopulation.put(1992, 100.0); 20 | catPopulation.put(1994, 200.0); 21 | 22 | TimeSeries dogPopulation = new TimeSeries(); 23 | dogPopulation.put(1994, 400.0); 24 | dogPopulation.put(1995, 500.0); 25 | 26 | TimeSeries totalPopulation = catPopulation.plus(dogPopulation); 27 | // expected: 1991: 0, 28 | // 1992: 100 29 | // 1994: 600 30 | // 1995: 500 31 | 32 | List expectedYears = new ArrayList<> 33 | (Arrays.asList(1991, 1992, 1994, 1995)); 34 | 35 | assertThat(totalPopulation.years()).isEqualTo(expectedYears); 36 | 37 | List expectedTotal = new ArrayList<> 38 | (Arrays.asList(0.0, 100.0, 600.0, 500.0)); 39 | 40 | for (int i = 0; i < expectedTotal.size(); i += 1) { 41 | assertThat(totalPopulation.data().get(i)).isWithin(1E-10).of(expectedTotal.get(i)); 42 | } 43 | } 44 | 45 | @Test 46 | public void testEmptyBasic() { 47 | TimeSeries catPopulation = new TimeSeries(); 48 | TimeSeries dogPopulation = new TimeSeries(); 49 | 50 | assertThat(catPopulation.years()).isEmpty(); 51 | assertThat(catPopulation.data()).isEmpty(); 52 | 53 | TimeSeries totalPopulation = catPopulation.plus(dogPopulation); 54 | 55 | assertThat(totalPopulation.years()).isEmpty(); 56 | assertThat(totalPopulation.data()).isEmpty(); 57 | } 58 | } -------------------------------------------------------------------------------- /proj2b/src/browser/NgordnetQuery.java: -------------------------------------------------------------------------------- 1 | package browser; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by hug. 7 | */ 8 | public record NgordnetQuery(List words, 9 | int startYear, 10 | int endYear, 11 | int k) {} 12 | -------------------------------------------------------------------------------- /proj2b/src/browser/NgordnetQueryHandler.java: -------------------------------------------------------------------------------- 1 | package browser; 2 | 3 | import com.google.gson.Gson; 4 | import spark.QueryParamsMap; 5 | import spark.Request; 6 | import spark.Response; 7 | import spark.Route; 8 | 9 | import java.util.Arrays; 10 | import java.util.List; 11 | 12 | public abstract class NgordnetQueryHandler implements Route { 13 | public abstract String handle(browser.NgordnetQuery q); 14 | private static final Gson gson = new Gson(); 15 | 16 | private static List commaSeparatedStringToList(String s) { 17 | String[] requestedWords = s.split(","); 18 | for (int i = 0; i < requestedWords.length; i += 1) { 19 | requestedWords[i] = requestedWords[i].trim(); 20 | } 21 | return Arrays.asList(requestedWords); 22 | } 23 | 24 | private static NgordnetQuery readQueryMap(QueryParamsMap qm) { 25 | List words = commaSeparatedStringToList(qm.get("words").value()); 26 | 27 | int startYear; 28 | int endYear; 29 | int k; 30 | 31 | try { 32 | startYear = Integer.parseInt(qm.get("startYear").value()); 33 | } catch (RuntimeException e) { 34 | startYear = 1900; 35 | } 36 | 37 | try { 38 | endYear = Integer.parseInt(qm.get("endYear").value()); 39 | } catch (RuntimeException e) { 40 | endYear = 2020; 41 | } 42 | 43 | try { 44 | k = Integer.parseInt(qm.get("k").value()); 45 | } catch (RuntimeException e) { 46 | k = 0; 47 | } 48 | 49 | return new NgordnetQuery(words, startYear, endYear, k); 50 | } 51 | 52 | @Override 53 | public String handle(Request request, Response response) throws Exception { 54 | QueryParamsMap qm = request.queryMap(); 55 | NgordnetQuery nq = readQueryMap(qm); 56 | String queryResult = handle(nq); 57 | return gson.toJson(queryResult); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /proj2b/src/browser/NgordnetServer.java: -------------------------------------------------------------------------------- 1 | package browser; 2 | 3 | import static spark.Spark.*; 4 | 5 | /** 6 | * Created by hug. 7 | */ 8 | public class NgordnetServer { 9 | public void register(String URL, NgordnetQueryHandler nqh) { 10 | get(URL, nqh); 11 | } 12 | 13 | public void startUp() { 14 | staticFiles.externalLocation("static"); 15 | 16 | /* Allow for all origin requests (since this is not an authenticated server, we do not 17 | * care about CSRF). */ 18 | before((request, response) -> { 19 | response.header("Access-Control-Allow-Origin", "*"); 20 | response.header("Access-Control-Request-Method", "*"); 21 | response.header("Access-Control-Allow-Headers", "*"); 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /proj2b/src/demo/DummyHistoryHandler.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import browser.NgordnetQuery; 4 | import browser.NgordnetQueryHandler; 5 | import ngrams.TimeSeries; 6 | import plotting.Plotter; 7 | import org.knowm.xchart.XYChart; 8 | 9 | import java.util.ArrayList; 10 | 11 | public class DummyHistoryHandler extends NgordnetQueryHandler { 12 | @Override 13 | public String handle(NgordnetQuery q) { 14 | System.out.println("Got query that looks like:"); 15 | System.out.println("Words: " + q.words()); 16 | System.out.println("Start Year: " + q.startYear()); 17 | System.out.println("End Year: " + q.endYear()); 18 | 19 | System.out.println("But I'm totally ignoring that and just plotting a parabola\n" + 20 | "and a sine wave, because your job will be to figure out how to\n" + 21 | "actually use the query data."); 22 | 23 | TimeSeries parabola = new TimeSeries(); 24 | for (int i = 0; i < 100; i += 1) { 25 | parabola.put(i, (i - 50.0) * (i - 50.0) + 3); 26 | } 27 | 28 | TimeSeries sinWave = new TimeSeries(); 29 | for (int i = 0; i < 100; i += 1) { 30 | sinWave.put(i, 1000 + 500 * Math.sin(i/100.0*2*Math.PI)); 31 | } 32 | 33 | ArrayList lts = new ArrayList<>(); 34 | ArrayList labels = new ArrayList<>(); 35 | 36 | labels.add("parabola"); 37 | labels.add("sine wave"); 38 | 39 | lts.add(parabola); 40 | lts.add(sinWave); 41 | 42 | XYChart chart = Plotter.generateTimeSeriesChart(labels, lts); 43 | String encodedImage = Plotter.encodeChartAsString(chart); 44 | 45 | return encodedImage; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /proj2b/src/demo/DummyHistoryTextHandler.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import browser.NgordnetQuery; 4 | import browser.NgordnetQueryHandler; 5 | 6 | import java.util.List; 7 | 8 | public class DummyHistoryTextHandler extends NgordnetQueryHandler { 9 | @Override 10 | public String handle(NgordnetQuery q) { 11 | List words = q.words(); 12 | int startYear = q.startYear(); 13 | int endYear = q.endYear(); 14 | 15 | String response = "You entered the following info into the browser:\n"; 16 | response += "Words: " + q.words() + "\n"; 17 | response += "Start Year: " + q.startYear() + "\n"; 18 | response += "End Year: " + q.endYear() + "\n"; 19 | return response; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /proj2b/src/demo/FileReadDemo.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import edu.princeton.cs.algs4.In; 4 | 5 | public class FileReadDemo { 6 | public static void main(String[] args) { 7 | In in = new In("./data/ngrams/very_short.csv"); 8 | int i = 0; 9 | 10 | while (!in.isEmpty()) { 11 | i += 1; 12 | String nextLine = in.readLine(); 13 | System.out.print("Line " + i + " is: "); 14 | System.out.println(nextLine); 15 | System.out.print("After splitting on tab characters, the first word is: "); 16 | String[] splitLine = nextLine.split("\t"); 17 | System.out.println(splitLine[0]); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /proj2b/src/demo/PlotDemo.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import ngrams.NGramMap; 4 | import ngrams.TimeSeries; 5 | import plotting.Plotter; 6 | import org.knowm.xchart.XYChart; 7 | 8 | import java.util.ArrayList; 9 | 10 | public class PlotDemo { 11 | public static void main(String[] args) { 12 | String wordFile = "./data/ngrams/top_14377_words.csv"; 13 | String countFile = "./data/ngrams/total_counts.csv"; 14 | 15 | NGramMap ngm = new NGramMap(wordFile, countFile); 16 | ArrayList words = new ArrayList<>(); 17 | words.add("cat"); 18 | words.add("dog"); 19 | 20 | ArrayList lts = new ArrayList<>(); 21 | for (String word : words) { 22 | lts.add(ngm.weightHistory(word, 1900, 1950)); 23 | } 24 | 25 | XYChart chart = Plotter.generateTimeSeriesChart(words, lts); 26 | String s = Plotter.encodeChartAsString(chart); 27 | System.out.println(s); 28 | 29 | // you can also do this to display locally: 30 | // Plotter.displayChart(chart); 31 | 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /proj2b/src/main/AutograderBuddy.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import browser.NgordnetQueryHandler; 4 | 5 | 6 | public class AutograderBuddy { 7 | /** Returns a HyponymHandler */ 8 | public static NgordnetQueryHandler getHyponymsHandler( 9 | String wordFile, String countFile, 10 | String synsetFile, String hyponymFile) { 11 | 12 | throw new RuntimeException("Please fill out AutograderBuddy.java!"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /proj2b/src/main/HyponymsHandler.java: -------------------------------------------------------------------------------- 1 | package main; 2 | public class HyponymsHandler { 3 | } 4 | -------------------------------------------------------------------------------- /proj2b/src/main/Main.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import browser.NgordnetServer; 4 | import demo.DummyHistoryHandler; 5 | import demo.DummyHistoryTextHandler; 6 | import org.slf4j.LoggerFactory; 7 | 8 | public class Main { 9 | // ngrams files 10 | public static final String VERY_SHORT_WORDS_FILE = "data/ngrams/very_short.csv"; 11 | public static final String TOTAL_COUNTS_FILE = "data/ngrams/total_counts.csv"; 12 | private static final String SMALL_WORDS_FILE = "data/ngrams/top_14377_words.csv"; 13 | private static final String WORDS_FILE = "data/ngrams/top_49887_words.csv"; 14 | 15 | // wordnet Files 16 | public static final String SMALL_SYNSET_FILE = "data/wordnet/synsets16.txt"; 17 | public static final String SMALL_HYPONYM_FILE = "data/wordnet/hyponyms16.txt"; 18 | public static final String LARGE_SYNSET_FILE = "data/wordnet/synsets.txt"; 19 | public static final String LARGE_HYPONYM_FILE = "data/wordnet/hyponyms.txt"; 20 | private static final String HYPONYMS_FILE_SUBSET = "data/wordnet/hyponyms1000-subgraph.txt"; 21 | private static final String SYNSETS_FILE_SUBSET = "data/wordnet/synsets1000-subgraph.txt"; 22 | 23 | // EECS files 24 | private static final String FREQUENCY_EECS_FILE = "data/ngrams/frequency-EECS.csv"; 25 | private static final String HYPONYMS_EECS_FILE = "data/wordnet/hyponyms-EECS.txt"; 26 | private static final String SYNSETS_EECS_FILE = "data/wordnet/synsets-EECS.txt"; 27 | 28 | static { 29 | LoggerFactory.getLogger(Main.class).info("\033[1;38mChanging text color to white"); 30 | } 31 | public static void main(String[] args) { 32 | NgordnetServer hns = new NgordnetServer(); 33 | 34 | hns.startUp(); 35 | hns.register("history", new DummyHistoryHandler()); 36 | hns.register("historytext", new DummyHistoryTextHandler()); 37 | hns.register("hyponyms", new HyponymsHandler()); 38 | 39 | System.out.println("Finished server startup! Visit http://localhost:4567/ngordnet.html"); 40 | } 41 | } -------------------------------------------------------------------------------- /proj2b/src/ngrams/NGramMap.java: -------------------------------------------------------------------------------- 1 | package ngrams; 2 | import edu.berkeley.eecs.inst.cs61b.ngrams.StaffNGramMap; 3 | 4 | import java.util.TreeMap; 5 | 6 | /** An object that provides utility methods for making queries on the 7 | * Google NGrams dataset (or a subset thereof). 8 | * 9 | * An NGramMap stores pertinent data from a "words file" and a "counts 10 | * file". It is not a map in the strict sense, but it does provide additional 11 | * functionality. 12 | * 13 | * This is a stripped-down version of the staff solution for 2A. Feel free 14 | * to replace this file with your own implementation. 15 | * 16 | * @author Josh Hug 17 | */ 18 | public class NGramMap extends StaffNGramMap { 19 | 20 | public static final int MIN_YEAR = 1400; 21 | public static final int MAX_YEAR = 2100; 22 | 23 | /** Constructs an NGramMap from WORDSFILENAME and COUNTSFILENAME. */ 24 | public NGramMap(String wordsFilename, String countsFilename) { 25 | super(wordsFilename, countsFilename); 26 | } 27 | 28 | /** Provides the history of WORD between STARTYEAR and ENDYEAR, inclusive. The returned TreeMap should be a copy, 29 | * not a link to the NGramMap's TreeMap. In other words, changes made 30 | * to the object returned by this function should not also affect the 31 | * NGramMap. This is also known as a "defensive copy". */ 32 | public TreeMap countHistory(String word, int startYear, int endYear) { 33 | return super.countHistory(word, startYear, endYear); 34 | } 35 | 36 | /** Provides the history of WORD. The returned TreeMap should be a copy, 37 | * not a link to the NGramMap's TreeMap. In other words, changes made 38 | * to the object returned by this function should not also affect the 39 | * NGramMap. This is also known as a "defensive copy". */ 40 | public TreeMap countHistory(String word) { 41 | return countHistory(word, MIN_YEAR, MAX_YEAR); 42 | } 43 | 44 | // TODO: Replace this file with your own implementation if you want all the methods of an NGramMap 45 | } 46 | -------------------------------------------------------------------------------- /proj2b/src/plotting/Plotter.java: -------------------------------------------------------------------------------- 1 | package plotting; 2 | 3 | import ngrams.TimeSeries; 4 | import org.knowm.xchart.BitmapEncoder; 5 | import org.knowm.xchart.SwingWrapper; 6 | import org.knowm.xchart.XYChart; 7 | 8 | import javax.imageio.ImageIO; 9 | import java.awt.image.BufferedImage; 10 | import java.io.ByteArrayOutputStream; 11 | import java.io.IOException; 12 | import java.util.Base64; 13 | import java.util.List; 14 | 15 | import java.util.TreeMap; 16 | import java.util.ArrayList; 17 | 18 | public class Plotter { 19 | 20 | public static XYChart generateTimeSeriesChart(List words, List lts) { 21 | if (words.size() != lts.size()) { 22 | throw new IllegalArgumentException("List of words and List of time series objects must be the same length"); 23 | } 24 | 25 | XYChart chart = new XYChart(800, 600); 26 | 27 | for (int i = 0; i < words.size(); i += 1) { 28 | TimeSeries ts = lts.get(i); 29 | String word = words.get(i); 30 | chart.addSeries(word, ts.years(), ts.data()); 31 | } 32 | 33 | return chart; 34 | } 35 | 36 | public static XYChart generateTreeMapChart(List words, List> lts) { 37 | if (words.size() != lts.size()) { 38 | throw new IllegalArgumentException("List of words and List of time series objects must be the same length"); 39 | } 40 | 41 | XYChart chart = new XYChart(800, 600); 42 | 43 | for (int i = 0; i < words.size(); i += 1) { 44 | TreeMap tm = lts.get(i); 45 | String word = words.get(i); 46 | chart.addSeries(word, new ArrayList<>(tm.keySet()), new ArrayList<>(tm.values())); 47 | } 48 | 49 | return chart; 50 | } 51 | 52 | public static void displayChart(XYChart chart) { 53 | new SwingWrapper(chart).displayChart(); 54 | } 55 | 56 | public static String encodeChartAsString(XYChart chart) { 57 | BufferedImage img = BitmapEncoder.getBufferedImage(chart); 58 | ByteArrayOutputStream os = new ByteArrayOutputStream(); 59 | 60 | try { 61 | ImageIO.write(img, "png", os); 62 | } catch (IOException e) { 63 | e.printStackTrace(); 64 | } 65 | 66 | String encodedImage = Base64.getEncoder().encodeToString(os.toByteArray()); 67 | return encodedImage; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /proj2b/static/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Berkeley-CS61B/skeleton-fa24/012edd4e7e18a896422cb6e2156c8cdbf00505be/proj2b/static/blank.png -------------------------------------------------------------------------------- /proj2b/static/ngordnet.css: -------------------------------------------------------------------------------- 1 | .textresult { 2 | overflow-y: scroll; 3 | height: 600px; 4 | width: 800px; 5 | resize: none; 6 | display: none; 7 | } 8 | 9 | .hiddentext { 10 | display: none; 11 | } 12 | .btn { 13 | text-decoration: none; 14 | color: #fff; 15 | background-color: #d14836; 16 | background-image: -webkit-linear-gradient(top,#dd4b39,#d14836); 17 | background-image: linear-gradient(top,#dd4b39,#d14836); 18 | color: #fff; 19 | border: 1px solid transparent; 20 | text-align: center; 21 | letter-spacing: .5px; 22 | transition: .2s ease-out; 23 | cursor: pointer; 24 | border: none; 25 | border-radius: 2px; 26 | display: inline-block; 27 | height: 36px; 28 | line-height: 36px; 29 | padding: 0 2rem; 30 | text-transform: uppercase; 31 | vertical-align: middle; 32 | -webkit-tap-highlight-color: transparent; 33 | } -------------------------------------------------------------------------------- /proj2b/static/ngordnet.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |

14 | 15 | 16 | 17 |

18 | 19 | 20 | 21 | 25 | 29 | 33 | 37 | 38 |
22 | words
23 |
24 |
26 | start
27 |
28 |
30 | end
31 |
32 |
34 | k
35 |
36 |
39 | 40 | 41 | 43 | 46 | 49 | 52 | 55 | 56 | 57 |
42 |
history
44 |
history (text)
45 |
47 |
hyponyms
48 |
50 |
hypohist
51 |
53 |
common ancestors
54 |
58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /proj2b/tests/TestMultiWordK0Hyponyms.java: -------------------------------------------------------------------------------- 1 | import browser.NgordnetQuery; 2 | import browser.NgordnetQueryHandler; 3 | import edu.princeton.cs.algs4.StdRandom; 4 | import main.AutograderBuddy; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | import static com.google.common.truth.Truth.assertThat; 11 | import static com.google.common.truth.Truth.assertWithMessage; 12 | 13 | /** Tests the case where the list of words is length greater than 1, but k is still zero. */ 14 | public class TestMultiWordK0Hyponyms { 15 | // this case doesn't use the NGrams dataset at all, so the choice of files is irrelevant 16 | // ngrams files 17 | public static final String VERY_SHORT_WORDS_FILE = "data/ngrams/very_short.csv"; 18 | public static final String TOTAL_COUNTS_FILE = "data/ngrams/total_counts.csv"; 19 | private static final String SMALL_WORDS_FILE = "data/ngrams/top_14377_words.csv"; 20 | private static final String WORDS_FILE = "data/ngrams/top_49887_words.csv"; 21 | 22 | // wordnet Files 23 | public static final String SMALL_SYNSET_FILE = "data/wordnet/synsets16.txt"; 24 | public static final String SMALL_HYPONYM_FILE = "data/wordnet/hyponyms16.txt"; 25 | public static final String LARGE_SYNSET_FILE = "data/wordnet/synsets.txt"; 26 | public static final String LARGE_HYPONYM_FILE = "data/wordnet/hyponyms.txt"; 27 | private static final String HYPONYMS_FILE_SUBSET = "data/wordnet/hyponyms1000-subgraph.txt"; 28 | private static final String SYNSETS_FILE_SUBSET = "data/wordnet/synsets1000-subgraph.txt"; 29 | 30 | // EECS files 31 | private static final String FREQUENCY_EECS_FILE = "data/ngrams/frequency-EECS.csv"; 32 | private static final String HYPONYMS_EECS_FILE = "data/wordnet/hyponyms-EECS.txt"; 33 | private static final String SYNSETS_EECS_FILE = "data/wordnet/synsets-EECS.txt"; 34 | 35 | 36 | /** This is an example from the spec.*/ 37 | @Test 38 | public void testOccurrenceAndChangeK0() { 39 | NgordnetQueryHandler studentHandler = AutograderBuddy.getHyponymsHandler( 40 | VERY_SHORT_WORDS_FILE, TOTAL_COUNTS_FILE, SMALL_SYNSET_FILE, SMALL_HYPONYM_FILE); 41 | List words = new ArrayList<>(); 42 | words.add("occurrence"); 43 | words.add("change"); 44 | 45 | NgordnetQuery nq = new NgordnetQuery(words, 0, 0, 0); 46 | String actual = studentHandler.handle(nq); 47 | String expected = "[alteration, change, increase, jump, leap, modification, saltation, transition]"; 48 | assertThat(actual).isEqualTo(expected); 49 | } 50 | 51 | // TODO: Add more unit tests (including edge case tests) here. 52 | 53 | } 54 | -------------------------------------------------------------------------------- /proj2b/tests/TestOneWordK0Hyponyms.java: -------------------------------------------------------------------------------- 1 | import browser.NgordnetQuery; 2 | import browser.NgordnetQueryHandler; 3 | import org.junit.jupiter.api.Test; 4 | import main.AutograderBuddy; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import static com.google.common.truth.Truth.assertThat; 10 | 11 | /** Tests the most basic case for Hyponyms where the list of words is one word long, and k = 0.*/ 12 | public class TestOneWordK0Hyponyms { 13 | // this case doesn't use the NGrams dataset at all, so the choice of files is irrelevant 14 | // ngrams files 15 | public static final String VERY_SHORT_WORDS_FILE = "data/ngrams/very_short.csv"; 16 | public static final String TOTAL_COUNTS_FILE = "data/ngrams/total_counts.csv"; 17 | private static final String SMALL_WORDS_FILE = "data/ngrams/top_14377_words.csv"; 18 | private static final String WORDS_FILE = "data/ngrams/top_49887_words.csv"; 19 | 20 | // wordnet Files 21 | public static final String SMALL_SYNSET_FILE = "data/wordnet/synsets16.txt"; 22 | public static final String SMALL_HYPONYM_FILE = "data/wordnet/hyponyms16.txt"; 23 | public static final String LARGE_SYNSET_FILE = "data/wordnet/synsets.txt"; 24 | public static final String LARGE_HYPONYM_FILE = "data/wordnet/hyponyms.txt"; 25 | private static final String HYPONYMS_FILE_SUBSET = "data/wordnet/hyponyms1000-subgraph.txt"; 26 | private static final String SYNSETS_FILE_SUBSET = "data/wordnet/synsets1000-subgraph.txt"; 27 | 28 | // EECS files 29 | private static final String FREQUENCY_EECS_FILE = "data/ngrams/frequency-EECS.csv"; 30 | private static final String HYPONYMS_EECS_FILE = "data/wordnet/hyponyms-EECS.txt"; 31 | private static final String SYNSETS_EECS_FILE = "data/wordnet/synsets-EECS.txt"; 32 | 33 | @Test 34 | public void testActK0() { 35 | NgordnetQueryHandler studentHandler = AutograderBuddy.getHyponymsHandler( 36 | WORDS_FILE, TOTAL_COUNTS_FILE, SMALL_SYNSET_FILE, SMALL_HYPONYM_FILE); 37 | List words = new ArrayList<>(); 38 | words.add("act"); 39 | 40 | NgordnetQuery nq = new NgordnetQuery(words, 0, 0, 0); 41 | String actual = studentHandler.handle(nq); 42 | String expected = "[act, action, change, demotion, human_action, human_activity, variation]"; 43 | assertThat(actual).isEqualTo(expected); 44 | } 45 | 46 | // TODO: Add more unit tests (including edge case tests) here. 47 | } 48 | -------------------------------------------------------------------------------- /proj3/src/core/AutograderBuddy.java: -------------------------------------------------------------------------------- 1 | package core; 2 | 3 | import tileengine.TETile; 4 | import tileengine.Tileset; 5 | 6 | public class AutograderBuddy { 7 | 8 | /** 9 | * Simulates a game, but doesn't render anything or call any StdDraw 10 | * methods. Instead, returns the world that would result if the input string 11 | * had been typed on the keyboard. 12 | * 13 | * Recall that strings ending in ":q" should cause the game to quit and 14 | * save. To "quit" in this method, save the game to a file, then just return 15 | * the TETile[][]. Do not call System.exit(0) in this method. 16 | * 17 | * @param input the input string to feed to your program 18 | * @return the 2D TETile[][] representing the state of the world 19 | */ 20 | public static TETile[][] getWorldFromInput(String input) { 21 | 22 | // Optional: Complete this method if you are submitting to the autograder 23 | 24 | throw new RuntimeException("Please fill out AutograderBuddy!"); 25 | } 26 | 27 | 28 | /** 29 | * Used to tell the autograder which tiles are the floor/ground (including 30 | * any lights/items resting on the ground). Change this 31 | * method if you add additional tiles. 32 | */ 33 | public static boolean isGroundTile(TETile t) { 34 | return t.character() == Tileset.FLOOR.character() 35 | || t.character() == Tileset.AVATAR.character() 36 | || t.character() == Tileset.FLOWER.character(); 37 | } 38 | 39 | /** 40 | * Used to tell the autograder while tiles are the walls/boundaries. Change 41 | * this method if you add additional tiles. 42 | */ 43 | public static boolean isBoundaryTile(TETile t) { 44 | return t.character() == Tileset.WALL.character() 45 | || t.character() == Tileset.LOCKED_DOOR.character() 46 | || t.character() == Tileset.UNLOCKED_DOOR.character(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /proj3/src/core/Main.java: -------------------------------------------------------------------------------- 1 | package core; 2 | 3 | public class Main { 4 | public static void main(String[] args) { 5 | 6 | // build your own world! 7 | 8 | 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /proj3/src/core/World.java: -------------------------------------------------------------------------------- 1 | package core; 2 | 3 | public class World { 4 | 5 | // build your own world! 6 | 7 | } 8 | -------------------------------------------------------------------------------- /proj3/src/demo/BoringWorldDemo.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import tileengine.TERenderer; 4 | import tileengine.TETile; 5 | import tileengine.Tileset; 6 | 7 | /** 8 | * Draws a world that is mostly empty except for a small region. 9 | */ 10 | public class BoringWorldDemo { 11 | 12 | private static final int WIDTH = 60; 13 | private static final int HEIGHT = 30; 14 | 15 | public static void main(String[] args) { 16 | // initialize the tile rendering engine with a window of size WIDTH x HEIGHT 17 | TERenderer ter = new TERenderer(); 18 | ter.initialize(WIDTH, HEIGHT); 19 | 20 | // initialize tiles 21 | TETile[][] world = new TETile[WIDTH][HEIGHT]; 22 | for (int x = 0; x < WIDTH; x++) { 23 | for (int y = 0; y < HEIGHT; y++) { 24 | world[x][y] = Tileset.NOTHING; 25 | } 26 | } 27 | 28 | // fills in a block 15 tiles wide by 5 tiles tall 29 | for (int x = 20; x < 35; x++) { 30 | for (int y = 5; y < 10; y++) { 31 | world[x][y] = Tileset.WALL; 32 | } 33 | } 34 | 35 | // draws the world to the screen 36 | ter.renderFrame(world); 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /proj3/src/demo/RandomWorldDemo.java: -------------------------------------------------------------------------------- 1 | package demo; 2 | 3 | import tileengine.TERenderer; 4 | import tileengine.TETile; 5 | import tileengine.Tileset; 6 | 7 | import java.util.Random; 8 | 9 | /** 10 | * Draws a world that contains RANDOM tiles. 11 | */ 12 | public class RandomWorldDemo { 13 | private static final int WIDTH = 50; 14 | private static final int HEIGHT = 50; 15 | 16 | private static final long SEED = 2873123; 17 | private static final Random RANDOM = new Random(SEED); 18 | 19 | /** 20 | * Fills the given 2D array of tiles with RANDOM tiles. 21 | * @param tiles 22 | */ 23 | public static void fillWithRandomTiles(TETile[][] tiles) { 24 | int height = tiles[0].length; 25 | int width = tiles.length; 26 | for (int x = 0; x < width; x++) { 27 | for (int y = 0; y < height; y++) { 28 | tiles[x][y] = randomTile(); 29 | } 30 | } 31 | } 32 | 33 | /** Picks a RANDOM tile with a 33% change of being 34 | * a wall, 33% chance of being a flower, and 33% 35 | * chance of being empty space. 36 | */ 37 | private static TETile randomTile() { 38 | // The following call to nextInt() uses a bound of 3 (this is not a seed!) so 39 | // the result is bounded between 0, inclusive, and 3, exclusive. (0, 1, or 2) 40 | int tileNum = RANDOM.nextInt(3); 41 | return switch (tileNum) { 42 | case 0 -> Tileset.WALL; 43 | case 1 -> Tileset.FLOWER; 44 | default -> Tileset.NOTHING; 45 | }; 46 | } 47 | 48 | public static void main(String[] args) { 49 | TERenderer ter = new TERenderer(); 50 | ter.initialize(WIDTH, HEIGHT); 51 | 52 | TETile[][] randomTiles = new TETile[WIDTH][HEIGHT]; 53 | fillWithRandomTiles(randomTiles); 54 | 55 | ter.renderFrame(randomTiles); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /proj3/src/tileengine/Tileset.java: -------------------------------------------------------------------------------- 1 | package tileengine; 2 | 3 | import java.awt.Color; 4 | 5 | /** 6 | * Contains constant tile objects, to avoid having to remake the same tiles in different parts of 7 | * the code. 8 | * 9 | * You are free to (and encouraged to) create and add your own tiles to this file. This file will 10 | * be turned in with the rest of your code. 11 | * 12 | * Ex: 13 | * world[x][y] = Tileset.FLOOR; 14 | * 15 | * The style checker may crash when you try to style check this file due to use of unicode 16 | * characters. This is OK. 17 | */ 18 | 19 | public class Tileset { 20 | public static final TETile AVATAR = new TETile('@', Color.white, Color.black, "you", 0); 21 | public static final TETile WALL = new TETile('#', new Color(216, 128, 128), Color.darkGray, 22 | "wall", 1); 23 | public static final TETile FLOOR = new TETile('·', new Color(128, 192, 128), Color.black, "floor", 2); 24 | public static final TETile NOTHING = new TETile(' ', Color.black, Color.black, "nothing", 3); 25 | public static final TETile GRASS = new TETile('"', Color.green, Color.black, "grass", 4); 26 | public static final TETile WATER = new TETile('≈', Color.blue, Color.black, "water", 5); 27 | public static final TETile FLOWER = new TETile('❀', Color.magenta, Color.pink, "flower", 6); 28 | public static final TETile LOCKED_DOOR = new TETile('█', Color.orange, Color.black, 29 | "locked door", 7); 30 | public static final TETile UNLOCKED_DOOR = new TETile('▢', Color.orange, Color.black, 31 | "unlocked door", 8); 32 | public static final TETile SAND = new TETile('▒', Color.yellow, Color.black, "sand", 9); 33 | public static final TETile MOUNTAIN = new TETile('▲', Color.gray, Color.black, "mountain", 10); 34 | public static final TETile TREE = new TETile('♠', Color.green, Color.black, "tree", 11); 35 | 36 | public static final TETile CELL = new TETile('█', Color.white, Color.black, "cell", 12); 37 | } 38 | 39 | 40 | -------------------------------------------------------------------------------- /proj3/src/utils/FileUtils.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.io.File; 4 | import java.io.IOException; 5 | import java.nio.file.Files; 6 | 7 | /** 8 | * A library of simple file operations. Feel free to modify this file. 9 | */ 10 | public class FileUtils { 11 | /** 12 | * Writes the specified contents to a file with the given filename. 13 | * 14 | * @param filename The name of the file to write to. 15 | * @param contents The contents to write to the file. 16 | * @throws RuntimeException if an IOException occurs during the write operation. 17 | */ 18 | public static void writeFile(String filename, String contents) { 19 | try { 20 | Files.writeString(new File(filename).toPath(), contents); 21 | } catch (IOException ex) { 22 | throw new RuntimeException(ex); 23 | } 24 | } 25 | 26 | /** 27 | * Reads the contents of a file with the given filename. 28 | * 29 | * @param filename The name of the file to read from. 30 | * @return The contents of the file as a String. 31 | * @throws RuntimeException if an IOException occurs during the read operation. 32 | */ 33 | public static String readFile(String filename) { 34 | try { 35 | return Files.readString(new File(filename).toPath()); 36 | } catch (IOException ex) { 37 | throw new RuntimeException(ex); 38 | } 39 | } 40 | 41 | /** 42 | * Checks if a file with the given filename exists. 43 | * 44 | * @param filename The name of the file to check for existence. 45 | * @return true if the file exists, false otherwise. 46 | */ 47 | public static boolean fileExists(String filename) { 48 | return new File(filename).exists(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /proj3/tests/WorldGenTests.java: -------------------------------------------------------------------------------- 1 | import core.AutograderBuddy; 2 | import edu.princeton.cs.algs4.StdDraw; 3 | import org.junit.jupiter.api.Test; 4 | import tileengine.TERenderer; 5 | import tileengine.TETile; 6 | 7 | public class WorldGenTests { 8 | @Test 9 | public void basicTest() { 10 | // put different seeds here to test different worlds 11 | TETile[][] tiles = AutograderBuddy.getWorldFromInput("n1234567890123456789s"); 12 | 13 | TERenderer ter = new TERenderer(); 14 | ter.initialize(tiles.length, tiles[0].length); 15 | ter.renderFrame(tiles); 16 | StdDraw.pause(5000); // pause for 5 seconds so you can see the output 17 | } 18 | 19 | @Test 20 | public void basicInteractivityTest() { 21 | // TODO: write a test that uses an input like "n123swasdwasd" 22 | } 23 | 24 | @Test 25 | public void basicSaveTest() { 26 | // TODO: write a test that calls getWorldFromInput twice, with "n123swasd:q" and with "lwasd" 27 | } 28 | } 29 | --------------------------------------------------------------------------------