├── .github └── workflows │ └── ci.yml ├── .gitignore ├── LICENSE ├── README.md ├── docs ├── exams │ ├── exam_example_0.docx │ ├── exam_example_0.pdf │ ├── exam_example_1.docx │ └── exam_example_1.pdf ├── exercises │ ├── ex01.md │ ├── ex02.md │ ├── ex03.md │ ├── ex04.md │ ├── ex05.md │ ├── ex06.md │ ├── ex07.md │ ├── ex08.md │ ├── ex09.md │ ├── ex10.md │ ├── ex11.md │ └── ex12.md └── slides │ ├── 10 │ ├── 10_optimization.pdf │ └── 10_optimization.pptx │ ├── 11 │ ├── 11_genetic.pdf │ └── 11_genetic.pptx │ ├── 12 │ ├── 12_compression.pdf │ └── 12_compression.pptx │ ├── 01 │ ├── 01_intro.pdf │ └── 01_intro.pptx │ ├── 02 │ ├── 02_stack_queue.pdf │ └── 02_stack_queue.pptx │ ├── 03 │ ├── 03_analysis_sort.pdf │ └── 03_analysis_sort.pptx │ ├── 04 │ ├── 04_recursion_tdd.pdf │ └── 04_recursion_tdd.pptx │ ├── 05 │ ├── 05_tree_maps.pdf │ └── 05_tree_maps.pptx │ ├── 06 │ ├── 06_hash_maps.pdf │ └── 06_hash_maps.pptx │ ├── 07 │ ├── 07_streams.pdf │ └── 07_streams.pptx │ ├── 08 │ ├── 08_graphs.pdf │ └── 08_graphs.pptx │ └── 09 │ ├── 09_regex.pdf │ └── 09_regex.pptx ├── exercises ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── pg4200 │ │ ├── ex01 │ │ ├── ArrayUtils.java │ │ └── TriangleClassification.java │ │ ├── ex03 │ │ ├── GameUser.java │ │ └── SortChecker.java │ │ ├── ex04 │ │ └── Fibonacci.java │ │ ├── ex06 │ │ ├── Author.java │ │ ├── Book.java │ │ ├── ImmutableAuthor.java │ │ └── ImmutableBook.java │ │ ├── ex07 │ │ ├── AnotherStream.java │ │ ├── ComputationExample.java │ │ ├── ComputationExampleTraditional.java │ │ └── ExtendedList.java │ │ ├── ex09 │ │ └── PatternExamples.java │ │ └── ex12 │ │ └── GradeCompressor.java │ └── test │ └── java │ └── org │ └── pg4200 │ ├── ex01 │ └── ArrayUtilsTestTemplate.java │ ├── ex03 │ └── SortCheckerTestTemplate.java │ ├── ex04 │ └── FibonacciTestTemplate.java │ ├── ex06 │ └── ImmutableBookAndAuthorTestTemplate.java │ ├── ex07 │ ├── ComputationExampleTestTemplate.java │ ├── ComputationExampleTraditionalTest.java │ └── ExtendedListTestTemplate.java │ ├── ex09 │ └── PatternExamplesTestTemplate.java │ └── ex12 │ └── GradeCompressorTestTemplate.java ├── lessons ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── pg4200 │ │ ├── les01 │ │ ├── ArrayExample.java │ │ ├── MyListString.java │ │ ├── arraylist │ │ │ └── MyArrayListString.java │ │ └── linkedlist │ │ │ ├── MyDelegateListString.java │ │ │ ├── MyLinkedListString.java │ │ │ └── MyNaiveLinkedListString.java │ │ ├── les02 │ │ ├── generic │ │ │ └── GenericExample.java │ │ ├── list │ │ │ ├── MyArrayList.java │ │ │ ├── MyLinkedList.java │ │ │ └── MyList.java │ │ ├── queue │ │ │ ├── MyQueue.java │ │ │ ├── MyQueueArray.java │ │ │ └── MyQueueLinkedList.java │ │ └── stack │ │ │ ├── MyStack.java │ │ │ ├── MyStackArray.java │ │ │ ├── MyStackDelegate.java │ │ │ ├── MyStackLinkedList.java │ │ │ └── StackOverflow.java │ │ ├── les03 │ │ ├── analysis │ │ │ └── Sum.java │ │ └── sort │ │ │ ├── BubbleSort.java │ │ │ ├── InsertionSort.java │ │ │ ├── MySort.java │ │ │ ├── Song.java │ │ │ └── SortExample.java │ │ ├── les04 │ │ ├── recursion │ │ │ ├── RecursiveSumArray.java │ │ │ └── RecursiveSumOfN.java │ │ └── sort │ │ │ ├── MergeSort.java │ │ │ └── QuickSort.java │ │ ├── les05 │ │ ├── MyMap.java │ │ ├── MyMapBinarySearchArray.java │ │ ├── MyMapBinarySearchTree.java │ │ ├── MyMapLinearSearchArray.java │ │ ├── MyMapRedBlackTree.java │ │ ├── MyMapTreeBased.java │ │ └── Search.java │ │ ├── les06 │ │ ├── copy │ │ │ └── CopyExample.java │ │ ├── hash │ │ │ ├── HashFunctions.java │ │ │ ├── MyHashMap.java │ │ │ └── MyHashMapWithLists.java │ │ ├── immutability │ │ │ ├── User.java │ │ │ ├── UserCorrectHash.java │ │ │ ├── UserImmutable.java │ │ │ └── UserWrongHash.java │ │ └── set │ │ │ ├── MySet.java │ │ │ └── MySetHashMap.java │ │ ├── les07 │ │ ├── iterator │ │ │ ├── MyIterableHashMap.java │ │ │ └── MyIterableLinkedList.java │ │ ├── lambda │ │ │ └── LambdaExamples.java │ │ └── stream │ │ │ ├── MyStream.java │ │ │ ├── MyStreamCollection.java │ │ │ ├── MyStreamCollectionHashMap.java │ │ │ ├── MyStreamCollectionList.java │ │ │ └── MyStreamSupport.java │ │ ├── les08 │ │ ├── DirectedGraph.java │ │ ├── Graph.java │ │ └── UndirectedGraph.java │ │ ├── les09 │ │ ├── regex │ │ │ └── Matcher.java │ │ └── search │ │ │ ├── TextSearch.java │ │ │ ├── TextSearchBruteForce.java │ │ │ └── TextSearchKMP.java │ │ ├── les10 │ │ ├── knapsack │ │ │ ├── BruteForceForKnapsack.java │ │ │ ├── GreedyForKnapsack.java │ │ │ ├── KnapsackInstanceWithSolution.java │ │ │ ├── KnapsackProblem.java │ │ │ └── RandomForKnapsack.java │ │ └── queens │ │ │ ├── HillClimbingForQueens.java │ │ │ ├── QueensProblem.java │ │ │ └── RandomForQueens.java │ │ ├── les11 │ │ ├── ea │ │ │ ├── GeneticAlgorithmForKnapsack.java │ │ │ └── OnePlusOneEAForKnapsack.java │ │ └── randomness │ │ │ ├── ArrayRandom.java │ │ │ ├── LcgRandom.java │ │ │ └── MyRandom.java │ │ └── les12 │ │ ├── BitReader.java │ │ ├── BitWriter.java │ │ ├── DnaCompressor.java │ │ ├── Huffman.java │ │ ├── TextCompression.java │ │ └── lzw │ │ ├── LZW.java │ │ ├── MyTernarySearchTrie.java │ │ └── Pair.java │ └── test │ ├── java │ └── org │ │ └── pg4200 │ │ ├── les01 │ │ ├── ArrayExampleTest.java │ │ ├── MyListStringTestTemplate.java │ │ ├── arraylist │ │ │ ├── MyArrayListStringTest.java │ │ │ └── MyArrayListStringTestFailing.java │ │ └── linkedlist │ │ │ ├── MyDelegateListStringTest.java │ │ │ ├── MyLinkedListStringTest.java │ │ │ └── MyNaiveLinkedListStringTest.java │ │ ├── les02 │ │ ├── generic │ │ │ └── GenericExampleTest.java │ │ ├── list │ │ │ ├── MyArrayListTest.java │ │ │ ├── MyLinkedListTest.java │ │ │ └── MyListTestTemplate.java │ │ ├── queue │ │ │ ├── MyQueueArrayTest.java │ │ │ ├── MyQueueLinkedListTest.java │ │ │ └── MyQueueTestTemplate.java │ │ └── stack │ │ │ ├── MyStackArrayTest.java │ │ │ ├── MyStackDelegateArrayListTest.java │ │ │ ├── MyStackDelegateLinkedListTest.java │ │ │ ├── MyStackLinkedListTest.java │ │ │ └── MyStackTestTemplate.java │ │ ├── les03 │ │ └── sort │ │ │ ├── BubbleSortTest.java │ │ │ ├── InsertionSortTest.java │ │ │ ├── SongTest.java │ │ │ └── SortTestTemplate.java │ │ ├── les04 │ │ ├── recursion │ │ │ ├── RecursiveSumArrayTest.java │ │ │ └── RecursiveSumTest.java │ │ └── sort │ │ │ ├── MergeSortTest.java │ │ │ └── QuickSortTest.java │ │ ├── les05 │ │ ├── MyMapBinarySearchArrayTest.java │ │ ├── MyMapBinarySearchTreeTest.java │ │ ├── MyMapLinearSearchArrayTest.java │ │ ├── MyMapRedBlackTreeTest.java │ │ ├── MyMapTestTemplate.java │ │ └── SearchTest.java │ │ ├── les06 │ │ ├── copy │ │ │ └── CopyExampleTest.java │ │ ├── hash │ │ │ ├── HashFunctionsTest.java │ │ │ ├── MyHashMapTestTemplate.java │ │ │ └── MyHashMapWithListsTest.java │ │ ├── immutability │ │ │ └── UserTest.java │ │ └── set │ │ │ └── MySetHashMapTest.java │ │ ├── les07 │ │ ├── iterator │ │ │ ├── MyIterableHashMapTest.java │ │ │ └── MyIterableLinkedListTest.java │ │ ├── lambda │ │ │ └── LambdaExamplesTest.java │ │ └── stream │ │ │ └── MyStreamTest.java │ │ ├── les08 │ │ ├── DirectedGraphTest.java │ │ └── UndirectedGraphTest.java │ │ ├── les09 │ │ ├── regex │ │ │ ├── JavaMatcherTest.java │ │ │ └── MatcherTest.java │ │ └── search │ │ │ ├── TextSearchBruteForceTest.java │ │ │ ├── TextSearchKMPTest.java │ │ │ └── TextSearchTestTemplate.java │ │ ├── les10 │ │ ├── knapsack │ │ │ ├── BruteForceForKnapsackTest.java │ │ │ ├── GreedyForKnapsackTest.java │ │ │ └── RandomForKnapsackTest.java │ │ └── queens │ │ │ └── QueensProblemTest.java │ │ ├── les11 │ │ ├── GeneticAlgorithmForKnapsackCheck.java │ │ └── OnePlusOneEAForKnapsackCheck.java │ │ └── les12 │ │ ├── BitReaderTest.java │ │ ├── BitWriterTest.java │ │ ├── DnaCompressorTest.java │ │ ├── HuffmanTest.java │ │ ├── TextCompressionTestTemplate.java │ │ └── lzw │ │ ├── LZWTest.java │ │ └── MyTernarySearchTrieTest.java │ └── resources │ └── compression │ └── odyssey.mb.txt ├── pom.xml ├── scripts └── growth.R └── solutions ├── pom.xml └── src ├── main └── java │ └── org │ └── pg4200 │ ├── sol01 │ ├── ArrayUtilsImp.java │ └── MyArrayListInteger.java │ ├── sol02 │ ├── MyArrayListResizable.java │ ├── MyBidirectionalLinkedList.java │ ├── MyMiddleBidirectionalLinkedList.java │ └── MyRingArrayQueue.java │ ├── sol03 │ ├── GameUserComparator.java │ ├── OptimizedBubbleSort.java │ └── SortCheckerImp.java │ ├── sol04 │ ├── FibonacciImpl.java │ ├── FibonacciImplMemoized.java │ ├── MixedSort.java │ └── TriangleClassification.java │ ├── sol05 │ ├── BinaryTreeLeftMaxDelete.java │ ├── DrawRedBlackTreeMap.java │ └── TernaryTreeMap.java │ ├── sol06 │ ├── HashMapLinearProbe.java │ ├── ImmutableAuthorImp.java │ └── ImmutableBookImp.java │ ├── sol07 │ ├── AnotherStreamList.java │ ├── AnotherStreamSupport.java │ ├── ComputationExampleStream.java │ └── ExtendedListImpl.java │ ├── sol08 │ └── AllPathsGraph.java │ ├── sol09 │ ├── PatternExamplesImp.java │ └── TextSearchKMPCached.java │ ├── sol10 │ ├── RandomForKnapsackOptimized.java │ └── SteepestAscentHCforQueens.java │ ├── sol11 │ └── OnePlusOneEAForQueens.java │ └── sol12 │ ├── GradeCompressorImp.java │ └── HuffmanIso.java └── test └── java └── org └── pg4200 ├── sol01 ├── ArrayUtilsImpTest.java ├── MyArrayListIntegerTest.java └── TriangleClassificationTest.java ├── sol02 ├── MyArrayListResizableTest.java ├── MyBidirectionalLinkedListTest.java ├── MyMiddleBidirectionalLinkedListTest.java └── MyRingArrayQueueTest.java ├── sol03 ├── OptimizedBubbleSortTest.java └── SortCheckerImpTest.java ├── sol04 ├── FibonacciImplMemoizedTest.java ├── FibonacciImplTestNot.java ├── MixedSortTest.java └── TriangleClassificationTest.java ├── sol05 ├── BinaryTreeLeftMaxDeleteTest.java └── TernaryTreeMapTest.java ├── sol06 ├── HashMapLinearProbeTest.java └── ImmutableBookAndAuthorTest.java ├── sol07 ├── AnotherStreamTest.java ├── ComputationExampleStreamTest.java └── ExtendedListImplTest.java ├── sol08 └── AllPathsGraphTest.java ├── sol09 ├── PatternExamplesImpTest.java └── TextSearchKMPCachedTest.java ├── sol10 ├── RandomForKnapsackOptimizedTest.java └── SteepestAscentHCforQueensTest.java ├── sol11 └── OnePlusOneEAForQueensTest.java └── sol12 ├── GradeCompressorTest.java └── HuffmanIsoTest.java /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | - name: Setup JDK 11 12 | uses: actions/setup-java@v1 13 | with: 14 | java-version: 11 15 | - name: Cache Maven packages 16 | uses: actions/cache@v2 17 | with: 18 | path: ~/.m2 19 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} 20 | restore-keys: ${{ runner.os }}-m2 21 | - name: Build with Maven 22 | run: mvn clean verify -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | *.iml 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | /.idea/ 25 | target/ -------------------------------------------------------------------------------- /docs/exams/exam_example_0.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/exams/exam_example_0.docx -------------------------------------------------------------------------------- /docs/exams/exam_example_0.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/exams/exam_example_0.pdf -------------------------------------------------------------------------------- /docs/exams/exam_example_1.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/exams/exam_example_1.docx -------------------------------------------------------------------------------- /docs/exams/exam_example_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/exams/exam_example_1.pdf -------------------------------------------------------------------------------- /docs/exercises/ex01.md: -------------------------------------------------------------------------------- 1 | # Exercise 01 2 | 3 | ## Part A 4 | 5 | Develop a class called `ArrayUtilsImp` that 6 | implements the interface `org.pg4200.ex01.ArrayUtils` in 7 | the `exercises` module. 8 | 9 | Create a concrete test class called `ArrayUtilsImpTest` that 10 | does extend the abstract test class `org.pg4200.ex01.ArrayUtilsTestTemplate`. 11 | Recall that test classes are under the `src/test/java` folder. 12 | If your implementation of `ArrayUtilsImp` is correct, 13 | then all tests should pass. 14 | 15 | 16 | ## Part B 17 | 18 | Using `org.pg4200.les01.array.MyArrayListString` as a 19 | reference, implement a class called `MyArrayListInteger` 20 | which rather works on `Integer` objects instead of `String`. 21 | Such class does not need to implement any interface. 22 | 23 | Using `org.pg4200.les01.MyListStringTestTemplate` 24 | as a reference, develop a concrete (not abstract) test class 25 | called `MyArrayListIntegerTest`, with the same kind 26 | of tests, buf for `MyArrayListInteger`. 27 | Here you need to use `Integer` inputs instead of `String`. 28 | All tests should pass. 29 | 30 | 31 | ## Part C 32 | 33 | Consider the class `org.pg4200.ex01.TriangleClassification`. 34 | Write a test class called `TriangleClassificationTest` for it. 35 | You need to write enough tests to achieve 100% line coverage. 36 | 37 | Note: by default in IntelliJ, when running tests with 38 | `Run 'X' with Coverage`, coverage is calculated only on the 39 | same package. If your tests are not in `org.pg4200.ex01`, 40 | then you need to set the `Edit Configurations`, in particular 41 | the options in the `Code Coverage` tab. 42 | 43 | 44 | 45 | ## Solutions 46 | 47 | Solutions to this exercise can be found in the `solutions` 48 | module, under the `org.pg4200.sol01` package. 49 | 50 | -------------------------------------------------------------------------------- /docs/exercises/ex03.md: -------------------------------------------------------------------------------- 1 | # Exercise 03 2 | 3 | ## Part A 4 | 5 | Write a class called `OptimizedBubbleSort` with the following method: 6 | 7 | `public int sort(T[] array, Comparator comparator, boolean optimized)` 8 | 9 | The method should sort the input array based on a given `Comparator`. 10 | The method should return the number of times the method `Comparator#compare` is called. 11 | 12 | If `optimized` is `true`, then instead of a naive bubble sort, you should run a better version. 13 | For example, one fact that can be exploited is that, if the last swap is done at position `i`, then 14 | all elements after `i` are necessarily sorted. 15 | So, in the next iteration, you do not need to check elements after `i`. 16 | 17 | 18 | Write a class called `OptimizedBubbleSortTest` in which you test your implementation. 19 | You need at least one test with the following input array `["c", "b", "a", "d", "e", "f"]`. 20 | On such array, you need to verify that your optimized bubble sort version should do less than 21 | half the comparisons than a non-optimized version. 22 | Note: be careful to do not call sorting twice on the same array, but rather create a new one. 23 | Add enough unit tests until your reach 100% statement coverage. 24 | 25 | 26 | ## Part B 27 | 28 | Consider the class `org.pg4200.ex03.GameUser`. 29 | Write a class called `GameUserComparator` that does 30 | implement `Comparator`. 31 | A `GameUser` is "larger" if it has more points. 32 | If points are the same, should consider alphabetic sorting 33 | based on the user id. 34 | 35 | Add a new test in `OptimizedBubbleSortTest` in which you 36 | sort an array of `GameUser` using `GameUserComparator`. 37 | 38 | ## Part C 39 | 40 | Develop a class called `SortCheckerImp` and that implements 41 | the interface `org.pg4200.ex03.SortChecker`. 42 | Develop a test class called `SortCheckerImpTest` that 43 | does extend `org.pg4200.ex03.SortCheckerTestTemplate`, 44 | in which you test your `SortCheckerImp` implementation. 45 | If it is correct, all tests should pass. 46 | 47 | ## Part D 48 | 49 | Study the source code of `BubbleSort` and `InsertionSort`. 50 | Once you think you fully understand them, write their implementation 51 | on paper (e.g., using a pen), without looking at the source code. 52 | Once done, compare what you wrote with the actual implementations. 53 | 54 | 55 | 56 | ## Solutions 57 | 58 | Solutions to this exercise can be found in the `solutions` 59 | module, under the `org.pg4200.sol03` package. 60 | -------------------------------------------------------------------------------- /docs/exercises/ex08.md: -------------------------------------------------------------------------------- 1 | # Exercise 08 2 | 3 | ## Part A 4 | 5 | Create a class `AllPathsGraph` that extends `UndirectedGraph`. 6 | In such class, create a method with the following signature: 7 | 8 | public List> findAllPaths(V start, V end) 9 | 10 | Such method should return all possible paths from `start` to `end` that 11 | are not cyclic. 12 | 13 | Write a test class called `AllPathsGraphTest` in which you recreate the graph 14 | shown in class in the slides, ie with edges: 15 | 16 | graph.addEdge("0","X"); 17 | graph.addEdge("X","1"); 18 | graph.addEdge("X","Y"); 19 | graph.addEdge("1","2"); 20 | graph.addEdge("2","Y"); 21 | graph.addEdge("1","3"); 22 | graph.addEdge("3","4"); 23 | graph.addEdge("3","5"); 24 | graph.addEdge("4","5"); 25 | 26 | Call `findAllPaths` on such graph with input `start=X` and `end=5`. 27 | Verify that the method returns 4 paths, with lengths 4, 5, 6 and 7. 28 | 29 | 30 | ## Part B 31 | 32 | Study the source code of `UndirectedGraph`. 33 | Once you think you fully understand it, write its implementation 34 | on paper (e.g., using a pen), without looking at the source code. 35 | Once done, compare what you wrote with the actual implementation. 36 | 37 | ## Solutions 38 | 39 | Solutions to this exercise can be found in the `solutions` 40 | module, under the `org.pg4200.sol08` package. 41 | -------------------------------------------------------------------------------- /docs/exercises/ex09.md: -------------------------------------------------------------------------------- 1 | # Exercise 09 2 | 3 | ## Part A 4 | 5 | Implement a class `TextSearchKMPCached` that extends `TextSearchKMP`. 6 | You need to override the method `findFirst(String text, String target)` to 7 | be more efficient. 8 | Instead of recomputing the needed data structures for each `target` input, 9 | those should be internally "cached", e.g., in a map. 10 | This means that each single `token` would be computed only once. 11 | If `findFirst` is called a second time with the same `target` input (but possibly 12 | different `text`), then the computation 13 | would be speeded up by re-using the data structures from the cache. 14 | 15 | Implement a test class `TextSearchKMPCachedTest` that extends `TextSearchTestTemplate`. 16 | If your implementation of `TextSearchKMPCached` is "functionally" correct, then all tests 17 | should pass. 18 | 19 | ## Part B 20 | 21 | Write a class `PatternExamplesImp` that implements the interface 22 | `org.pg4200.ex09.PatternExamples`. 23 | 24 | Implement a test class `PatternExamplesImpTest` that extends 25 | `org.pg4200.ex09.PatternExamplesTestTemplate`. 26 | If your implementation of `PatternExamplesImp` is correct, 27 | then all tests should pass. 28 | 29 | 30 | ## Part C 31 | 32 | Study the source code of `TextSearchKMP`. 33 | Once you think you fully understand it, write its implementation 34 | on paper (e.g., using a pen), without looking at the source code. 35 | Once done, compare what you wrote with the actual implementation. 36 | 37 | 38 | ## Solutions 39 | 40 | Solutions to this exercise can be found in the `solutions` 41 | module, under the `org.pg4200.sol09` package. 42 | 43 | -------------------------------------------------------------------------------- /docs/exercises/ex10.md: -------------------------------------------------------------------------------- 1 | # Exercise 10 2 | 3 | ## Part A 4 | 5 | The code of `RandomForKnapsack` is not particularly good, as it creates 6 | new arrays on the heap at each step. 7 | Write a new `RandomForKnapsackOptimized` class, in which __ONLY 2__ arrays 8 | are instantiated: one to keep the best solution seen so far, and one as 9 | a buffer to randomize at each step to evaluate a new configuration. 10 | When a new, better configuration is found, just swap the two array pointers. 11 | 12 | Create a new `RandomForKnapsackOptimizedTest`, based on `RandomForKnapsackTest`, 13 | to test this new implementation. 14 | 15 | ## Part B 16 | 17 | Consider the class `HillClimbingForQueens`. 18 | Modify the Hill Climbing algorithm to use *Steepest Ascent*: 19 | instead of climbing to the first better element in the neighbourhood, 20 | first look at all the candidate solutions in the neighbourhood, and 21 | then move toward the best. 22 | Implement such new variant in a class called `SteepestAscentHCforQueens`. 23 | 24 | Write a test class `SteepestAscentHCforQueensTest` in which you test your 25 | steepest ascent version on boards of size 8, 16, 20 and 100. 26 | 27 | ## Solutions 28 | 29 | Solutions to this exercise can be found in the `solutions` 30 | module, under the `org.pg4200.sol10` package. -------------------------------------------------------------------------------- /docs/exercises/ex11.md: -------------------------------------------------------------------------------- 1 | # Exercise 11 2 | 3 | "Inspired" by the code of `OnePlusOneEAForKnapsack` and `HillClimbingForQueens`, 4 | write a (1+1)EA implementation `OnePlusOneEAForQueens` for the Queens problem. 5 | Make particular attention on how to implement the mutation operator, as you 6 | cannot use a simple bit flip. 7 | 8 | Write a test suite `OnePlusOneEAForQueensTest` similarly to what done in 9 | `QueensProblemTest` for the HC algorithm, i.e., write tests for boards of 10 | followings sizes: 8, 16, 20 and 100. 11 | If your implementation of (1+1)EA is correct, those board sizes should be very quick 12 | to solve. 13 | 14 | ## Solutions 15 | 16 | Solutions to this exercise can be found in the `solutions` 17 | module, under the `org.pg4200.sol11` package. -------------------------------------------------------------------------------- /docs/exercises/ex12.md: -------------------------------------------------------------------------------- 1 | # Exercise 12 2 | 3 | ## Part A 4 | 5 | Implement a class `HuffmanIso` that extends `Huffman`. 6 | In such class, override the methods `writeTrie` and `readTrie`. 7 | When writing/reading a char for a given leaf node, use the charset ISO-8859-1 instead 8 | of the current UTF-16 in `Huffman`. 9 | 10 | Note 0: you would lose Unicode support by doing it. 11 | 12 | Note 1: for coding/decoding, you can use the method `getBytes` in `String` with 13 | charset `StandardCharsets.ISO_8859_1`. 14 | 15 | Write a test class `HuffmanIsoTest` with the following two tests: 16 | 17 | * `testCompareOnShortNorwegianSentence` in which you compare both `HuffmanIso` and 18 | `Huffman` on the text string "Jeg ønsker å få en god karakter i denne eksamenen" 19 | encoded in UTF-8. 20 | Verify that `HuffmanIso` can compress it, whereas `Huffman` actually makes it bigger. 21 | Explain why. 22 | 23 | * `testCompareOnBook` in which you compare both `HuffmanIso` and 24 | `Huffman` on the text of the Odyssey book encoded in UTF-8. 25 | Verify that both `HuffmanIso` and `Huffman` do compress it, but their difference 26 | in compression ratio is minimal (i.e., less than 0.001). 27 | Explain why. 28 | 29 | 30 | ## Part B 31 | 32 | Consider a string representation for exam grades, in the format of ``, where `id` is a number starting from 0 (can assume __NO MORE__ than 500 students in an exam, and there can be exams with just a couple of students), and grades in the range `A-F`. 33 | A valid string would be for example: `0A1F2F3C12F13B14B27A201B497A`. 34 | You can assume that the ids are sorted, but there can be holes in the sequence (e.g., representing students that did not submit). 35 | 36 | Write a class `GradeCompressorImp` that implements the given `GradeCompressor` interface. 37 | 38 | You __MUST__ come up with an efficient compression algorithm which is specialized and customized for this problem domain (i.e., do not use either `Huffman` nor `LZW`, but rather use `DnaCompressor` as inspiration). 39 | For example, if there is just 1 student, you should not use more than 2 bytes in total for the compression. 40 | If there are 100 students, should not use more than 150 bytes. 41 | In your implementation, you can rely on and use the classes `BitWriter` and `BitReader`. 42 | 43 | Write a test class `GradeCompressorTest` that extends the given `GradeCompressorTestTemplate` test suite. 44 | If your implementation of `GradeCompressorImp` is correct, all tests should pass. 45 | 46 | 47 | ## Solutions 48 | 49 | Solutions to this exercise can be found in the `solutions` 50 | module, under the `org.pg4200.sol12` package. -------------------------------------------------------------------------------- /docs/slides/01/01_intro.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/01/01_intro.pdf -------------------------------------------------------------------------------- /docs/slides/01/01_intro.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/01/01_intro.pptx -------------------------------------------------------------------------------- /docs/slides/02/02_stack_queue.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/02/02_stack_queue.pdf -------------------------------------------------------------------------------- /docs/slides/02/02_stack_queue.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/02/02_stack_queue.pptx -------------------------------------------------------------------------------- /docs/slides/03/03_analysis_sort.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/03/03_analysis_sort.pdf -------------------------------------------------------------------------------- /docs/slides/03/03_analysis_sort.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/03/03_analysis_sort.pptx -------------------------------------------------------------------------------- /docs/slides/04/04_recursion_tdd.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/04/04_recursion_tdd.pdf -------------------------------------------------------------------------------- /docs/slides/04/04_recursion_tdd.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/04/04_recursion_tdd.pptx -------------------------------------------------------------------------------- /docs/slides/05/05_tree_maps.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/05/05_tree_maps.pdf -------------------------------------------------------------------------------- /docs/slides/05/05_tree_maps.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/05/05_tree_maps.pptx -------------------------------------------------------------------------------- /docs/slides/06/06_hash_maps.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/06/06_hash_maps.pdf -------------------------------------------------------------------------------- /docs/slides/06/06_hash_maps.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/06/06_hash_maps.pptx -------------------------------------------------------------------------------- /docs/slides/07/07_streams.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/07/07_streams.pdf -------------------------------------------------------------------------------- /docs/slides/07/07_streams.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/07/07_streams.pptx -------------------------------------------------------------------------------- /docs/slides/08/08_graphs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/08/08_graphs.pdf -------------------------------------------------------------------------------- /docs/slides/08/08_graphs.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/08/08_graphs.pptx -------------------------------------------------------------------------------- /docs/slides/09/09_regex.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/09/09_regex.pdf -------------------------------------------------------------------------------- /docs/slides/09/09_regex.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/09/09_regex.pptx -------------------------------------------------------------------------------- /docs/slides/10/10_optimization.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/10/10_optimization.pdf -------------------------------------------------------------------------------- /docs/slides/10/10_optimization.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/10/10_optimization.pptx -------------------------------------------------------------------------------- /docs/slides/11/11_genetic.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/11/11_genetic.pdf -------------------------------------------------------------------------------- /docs/slides/11/11_genetic.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/11/11_genetic.pptx -------------------------------------------------------------------------------- /docs/slides/12/12_compression.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/12/12_compression.pdf -------------------------------------------------------------------------------- /docs/slides/12/12_compression.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arcuri82/algorithms/9aacad422e066d612b16ffceed81b247532d105c/docs/slides/12/12_compression.pptx -------------------------------------------------------------------------------- /exercises/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | pg4200-exercises 6 | jar 7 | 8 | 9 | org.pg4200 10 | pg4200-root 11 | 0.0.1-SNAPSHOT 12 | 13 | 14 | 15 | 16 | org.pg4200 17 | pg4200-lessons 18 | ${project.version} 19 | 20 | 21 | org.pg4200 22 | pg4200-lessons 23 | ${project.version} 24 | tests 25 | test-jar 26 | test 27 | 28 | 29 | 30 | org.junit.jupiter 31 | junit-jupiter-api 32 | 33 | 34 | org.junit.jupiter 35 | junit-jupiter-engine 36 | 37 | 38 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex01/ArrayUtils.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex01; 2 | 3 | public interface ArrayUtils { 4 | 5 | /** 6 | * 7 | * @param array 8 | * @return the minimum value in the array 9 | * @throws IllegalArgumentException if input is null or empty 10 | */ 11 | int min(int[] array) throws IllegalArgumentException; 12 | 13 | /** 14 | * 15 | * @param array 16 | * @return the maximum value in the array 17 | * @throws IllegalArgumentException if input is null or empty 18 | */ 19 | int max(int[] array) throws IllegalArgumentException; 20 | 21 | /** 22 | * 23 | * @param array 24 | * @return the arithmetic average of the values in the array 25 | * @throws IllegalArgumentException if input is null or empty 26 | */ 27 | double mean(int[] array) throws IllegalArgumentException; 28 | } 29 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex01/TriangleClassification.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex01; 2 | 3 | import static org.pg4200.ex01.TriangleClassification.Classification.*; 4 | 5 | public class TriangleClassification { 6 | 7 | public enum Classification {NOT_A_TRIANGLE, ISOSCELES, SCALENE, EQUILATERAL} 8 | 9 | /** 10 | * Take as input 3 integer values representing 3 edges of a triangle. 11 | * 12 | * @param a 13 | * @param b 14 | * @param c 15 | * @return the classification of the triangle type 16 | */ 17 | public static Classification classify(int a, int b, int c) { 18 | 19 | if (a <= 0 || b <= 0 || c <= 0) { 20 | return NOT_A_TRIANGLE; 21 | } 22 | 23 | if (a == b && b == c) { 24 | return EQUILATERAL; 25 | } 26 | 27 | int max = Math.max(a, Math.max(b, c)); 28 | 29 | if ((max == a && max - b - c >= 0) || 30 | (max == b && max - a - c >= 0) || 31 | (max == c && max - a - b >= 0)) { 32 | return NOT_A_TRIANGLE; 33 | } 34 | 35 | if (a == b || b == c || a == c) { 36 | return ISOSCELES; 37 | } else { 38 | return SCALENE; 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex03/GameUser.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex03; 2 | 3 | import java.util.Objects; 4 | 5 | public class GameUser { 6 | 7 | private String userId; 8 | 9 | private int points; 10 | 11 | public GameUser(String userId, int points) { 12 | this.userId = Objects.requireNonNull(userId); 13 | this.points = points; 14 | } 15 | 16 | public String getUserId() { 17 | return userId; 18 | } 19 | 20 | public void setUserId(String userId) { 21 | this.userId = userId; 22 | } 23 | 24 | public int getPoints() { 25 | return points; 26 | } 27 | 28 | public void setPoints(int points) { 29 | this.points = points; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex03/SortChecker.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex03; 2 | 3 | public interface SortChecker { 4 | 5 | /** 6 | * Check if "sorted" is a sorted copy of the 7 | * "original" array. 8 | * 9 | * Sorting is undefined for "null" elements. 10 | * Therefore, if any of the input array contains null values, 11 | * this method returns false. 12 | */ 13 | > boolean isSortedCopy(T[] original, T[] sorted); 14 | } 15 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex04/Fibonacci.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex04; 2 | 3 | /** 4 | * Created by arcuri82 on 07-Jun-19. 5 | */ 6 | public interface Fibonacci { 7 | 8 | /** 9 | * Compute the Fibonacci number f(n) = f(n-2) + f(n-1). 10 | * 11 | * @throws IllegalArgumentException if n is negative 12 | */ 13 | int compute(int n) throws IllegalArgumentException; 14 | } 15 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex06/Author.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex06; 2 | 3 | import java.util.Objects; 4 | 5 | /** 6 | * Created by arcuri82 on 02-May-18. 7 | */ 8 | public class Author { 9 | 10 | private String name; 11 | 12 | private String surname; 13 | 14 | public Author(){ 15 | } 16 | 17 | public Author(String name, String surname) { 18 | this.name = name; 19 | this.surname = surname; 20 | } 21 | 22 | public String getName() { 23 | return name; 24 | } 25 | 26 | public void setName(String name) { 27 | this.name = name; 28 | } 29 | 30 | public String getSurname() { 31 | return surname; 32 | } 33 | 34 | public void setSurname(String surname) { 35 | this.surname = surname; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object o) { 40 | if (this == o) return true; 41 | if (o == null || getClass() != o.getClass()) return false; 42 | Author author = (Author) o; 43 | return Objects.equals(name, author.name) && 44 | Objects.equals(surname, author.surname); 45 | } 46 | 47 | @Override 48 | public int hashCode() { 49 | 50 | return Objects.hash(name, surname); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex06/Book.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex06; 2 | 3 | import java.util.List; 4 | import java.util.Objects; 5 | 6 | /** 7 | * Created by arcuri82 on 02-May-18. 8 | */ 9 | public class Book { 10 | 11 | private String title; 12 | 13 | private int year; 14 | 15 | private List authors; 16 | 17 | public Book(){ 18 | } 19 | 20 | public Book(String title, int year, List authors) { 21 | this.title = title; 22 | this.year = year; 23 | this.authors = authors; 24 | } 25 | 26 | public String getTitle() { 27 | return title; 28 | } 29 | 30 | public void setTitle(String title) { 31 | this.title = title; 32 | } 33 | 34 | public int getYear() { 35 | return year; 36 | } 37 | 38 | public void setYear(int year) { 39 | this.year = year; 40 | } 41 | 42 | public List getAuthors() { 43 | return authors; 44 | } 45 | 46 | public void setAuthors(List authors) { 47 | this.authors = authors; 48 | } 49 | 50 | @Override 51 | public boolean equals(Object o) { 52 | if (this == o) return true; 53 | if (o == null || getClass() != o.getClass()) return false; 54 | Book book = (Book) o; 55 | return year == book.year && 56 | Objects.equals(title, book.title) && 57 | Objects.equals(authors, book.authors); 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | 63 | return Objects.hash(title, year, authors); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex06/ImmutableAuthor.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex06; 2 | 3 | /** 4 | * Created by arcuri82 on 02-May-18. 5 | */ 6 | public interface ImmutableAuthor { 7 | 8 | /** 9 | * @return a copy of this Author, but with different name 10 | */ 11 | ImmutableAuthor withName(String name); 12 | 13 | /** 14 | * @return a copy of this Author, but with different surname 15 | */ 16 | ImmutableAuthor withSurname(String surname); 17 | 18 | String getName(); 19 | 20 | String getSurname(); 21 | } 22 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex06/ImmutableBook.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex06; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by arcuri82 on 02-May-18. 7 | */ 8 | public interface ImmutableBook { 9 | 10 | /** 11 | * @return a copy of this Book, but with different title 12 | */ 13 | ImmutableBook withTitle(String title); 14 | 15 | /** 16 | * @return a copy of this Book, but with different year 17 | */ 18 | ImmutableBook withYear(int year); 19 | 20 | /** 21 | * @return a copy of this Book, but with different authors 22 | */ 23 | ImmutableBook withAuthors(List authors); 24 | 25 | /** 26 | * @return a copy of this Book, but with different authors 27 | */ 28 | ImmutableBook withAuthors(ImmutableAuthor... authors); 29 | 30 | String getTitle(); 31 | 32 | int getYear(); 33 | 34 | List getAuthors(); 35 | } 36 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex07/AnotherStream.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex07; 2 | 3 | import java.util.Optional; 4 | import java.util.function.BinaryOperator; 5 | import java.util.function.Predicate; 6 | 7 | /** 8 | * Created by arcuri82 on 04-Oct-17. 9 | */ 10 | public interface AnotherStream { 11 | 12 | /** 13 | * Terminal operation. Count number 14 | * of elements in the stream. 15 | */ 16 | int count(); 17 | 18 | /** 19 | * On each object, its String representation is computed with toString(). 20 | * A null value will be considered as an empty string. 21 | * All those strings are joined together into a single one, with "separator" 22 | * between each of them (but not before the first, and not after the last). 23 | * 24 | * For example, if the stream has x, y=null and z, and separator=",", then the final result 25 | * would be the output of: 26 | * x.toString()+","+""+","+z.toString() 27 | */ 28 | String joinToString(String separator); 29 | 30 | /** 31 | * Check if the given predicate is true for any element in the stream. 32 | */ 33 | boolean any(Predicate predicate); 34 | 35 | /** 36 | * Performs a reduction on the elements of this stream, using an associative accumulation function, 37 | * and returns an Optional describing the reduced value, if any (ie, if the stream as at least one element). 38 | * This is equivalent to take the first element, apply accumulator with second element, get result 39 | * and apply accumulator with 3rd element, then take this result and accumulate with 4th element, and so on. 40 | */ 41 | Optional reduce(BinaryOperator accumulator); 42 | 43 | /** 44 | * Filtering operation that only let pass an element 45 | * once. Ie, if an element in the stream is 46 | * present more than once, it will be propagated to 47 | * the stream only once, the first time it is seen. 48 | */ 49 | AnotherStream distinct(); 50 | 51 | /** 52 | * Filtering operation that does ignore and skip 53 | * the first n elements coming from the stream. 54 | */ 55 | AnotherStream skip(int n); 56 | 57 | /** 58 | * Sort the whole incoming stream, and propagate each value to the 59 | * downstream in such order. 60 | * Will throw an exception if elements are not implementing {@code Comparable} 61 | */ 62 | AnotherStream sorted(); 63 | } 64 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex07/ComputationExample.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex07; 2 | 3 | import org.pg4200.ex06.Book; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by arcuri82 on 02-May-18. 9 | */ 10 | public interface ComputationExample { 11 | 12 | List compute(List books); 13 | } 14 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex07/ComputationExampleTraditional.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex07; 2 | 3 | import org.pg4200.ex06.Author; 4 | import org.pg4200.ex06.Book; 5 | 6 | import java.util.ArrayList; 7 | import java.util.HashSet; 8 | import java.util.List; 9 | import java.util.Set; 10 | 11 | /** 12 | * Created by arcuri82 on 02-May-18. 13 | */ 14 | public class ComputationExampleTraditional implements ComputationExample{ 15 | 16 | 17 | @Override 18 | public List compute(List books) { 19 | 20 | Set results = new HashSet<>(); 21 | 22 | for(Book book : books){ 23 | int year = book.getYear(); 24 | if(year < 2010 || year > 2015){ 25 | continue; 26 | } 27 | 28 | List authors = book.getAuthors(); 29 | if(authors.size() < 2){ 30 | continue; 31 | } 32 | 33 | for(Author author : authors){ 34 | if(author.getName() == null || author.getSurname()==null){ 35 | continue; 36 | } 37 | 38 | String value = author.getName() + " " + author.getSurname(); 39 | results.add(value); 40 | } 41 | } 42 | 43 | return new ArrayList<>(results); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex07/ExtendedList.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex07; 2 | 3 | /** 4 | * Created by arcuri82 on 07-Jun-19. 5 | */ 6 | 7 | import org.pg4200.les02.list.MyList; 8 | import org.pg4200.les06.set.MySet; 9 | 10 | import java.util.function.Consumer; 11 | import java.util.function.Function; 12 | import java.util.function.Predicate; 13 | 14 | public interface ExtendedList extends MyList { 15 | 16 | /** 17 | * Return a new list which contains all the values of the current 18 | * list for which predicate is true 19 | */ 20 | ExtendedList filter(Predicate predicate); 21 | 22 | /** 23 | * Return a new list whose content is the result of the mapping function 24 | * on each element of the current list, in order 25 | */ 26 | ExtendedList map(Function mapper); 27 | 28 | /** 29 | * Return a new list whose content is the merging of all the lists coming from the results 30 | * of the mapping function applied on each element of the current list. 31 | */ 32 | ExtendedList flatMap(Function> mapper); 33 | 34 | /** 35 | * On each element in the list, do apply the given action 36 | */ 37 | void forEach(Consumer action); 38 | 39 | /** 40 | * Create a new set with the values contained in this list 41 | */ 42 | MySet toSet(); 43 | } 44 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex09/PatternExamples.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex09; 2 | 3 | /** 4 | * Created by arcuri82 on 07-May-18. 5 | */ 6 | public interface PatternExamples { 7 | 8 | /** 9 | * Any sequence of letters C, G, A and T. 10 | * (cytosine [C], guanine [G], adenine [A] or thymine [T]) 11 | * Should be at least one value. 12 | */ 13 | String dnaRegex(); 14 | 15 | /** 16 | * 8 digit number. 17 | * Might be preceded by a country code, which 18 | * is either a + or 00 followed by 2 digits 19 | */ 20 | String telephoneNumberRegex(); 21 | 22 | 23 | /** 24 | * An email is composed of, in order: 25 | * - a non-empty word (letters from a to z, upper and lower case, plus digits) 26 | * - followed by zero or more non-empty words, each one separated by a "." 27 | * - symbol @ 28 | * - a non-empty word 29 | * - followed by zero or more non-empty words, each one separated by a "." 30 | * - a final domain code, which is at least 2 letters (upper or lower case), and no digits 31 | */ 32 | String emailRegex(); 33 | 34 | /** 35 | * Need match the following sentence: 36 | * 37 | * Is this an out of season april fools joke? 38 | * 39 | * However, the regex should be general enough to also match for further string variants following these properties: 40 | * a) there can be any number of spaces between the words 41 | * b) each letter can be either in lower or upper case 42 | */ 43 | String isItAJoke(); 44 | } 45 | -------------------------------------------------------------------------------- /exercises/src/main/java/org/pg4200/ex12/GradeCompressor.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex12; 2 | 3 | public interface GradeCompressor { 4 | 5 | /** 6 | * 7 | * @param idsAndGrades string list in the form id:grade, eg, 0A1F2C 8 | * @return compressed bytes 9 | */ 10 | byte[] compress(String idsAndGrades); 11 | 12 | String decompress(byte[] data); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /exercises/src/test/java/org/pg4200/ex01/ArrayUtilsTestTemplate.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex01; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | public abstract class ArrayUtilsTestTemplate { 9 | 10 | protected abstract ArrayUtils getNewInstance(); 11 | 12 | protected ArrayUtils utils; 13 | 14 | @BeforeEach 15 | public void init(){ 16 | utils = getNewInstance(); 17 | } 18 | 19 | @Test 20 | public void testEmptyArray(){ 21 | 22 | assertThrows(IllegalArgumentException.class, 23 | () -> utils.min(null)); 24 | assertThrows(IllegalArgumentException.class, 25 | () -> utils.max(null)); 26 | assertThrows(IllegalArgumentException.class, 27 | () -> utils.mean(null)); 28 | 29 | assertThrows(IllegalArgumentException.class, 30 | () -> utils.min(new int[]{})); 31 | assertThrows(IllegalArgumentException.class, 32 | () -> utils.max(new int[]{})); 33 | assertThrows(IllegalArgumentException.class, 34 | () -> utils.mean(new int[]{})); 35 | } 36 | 37 | @Test 38 | public void testMinPositive(){ 39 | 40 | int[] array = {5,4,1,7}; 41 | 42 | int res = utils.min(array); 43 | 44 | assertEquals(1, res); 45 | } 46 | 47 | @Test 48 | public void testMinNegative(){ 49 | 50 | int[] array = {5,-4,1,-7,0}; 51 | 52 | int res = utils.min(array); 53 | 54 | assertEquals(-7, res); 55 | } 56 | 57 | @Test 58 | public void testMaxPositive(){ 59 | 60 | int[] array = {5,4,1,7,0}; 61 | 62 | int res = utils.max(array); 63 | 64 | assertEquals(7, res); 65 | } 66 | 67 | @Test 68 | public void testMaxNegative(){ 69 | 70 | int[] array = {-5,-4,-1,-7}; 71 | 72 | int res = utils.max(array); 73 | 74 | assertEquals(-1, res); 75 | } 76 | 77 | @Test 78 | public void testMeanPositive(){ 79 | 80 | int[] array = {2,3,4,3}; 81 | 82 | double res = utils.mean(array); 83 | 84 | assertEquals(3d, res); 85 | } 86 | 87 | @Test 88 | public void testMeanNegative(){ 89 | 90 | int[] array = {-2,3,4,-3,3,-11}; 91 | 92 | double res = utils.mean(array); 93 | 94 | assertEquals(-1d, res); 95 | } 96 | 97 | } -------------------------------------------------------------------------------- /exercises/src/test/java/org/pg4200/ex04/FibonacciTestTemplate.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex04; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | /** 8 | * Created by arcuri82 on 07-Jun-19. 9 | */ 10 | public abstract class FibonacciTestTemplate { 11 | 12 | 13 | protected abstract Fibonacci getInstance(); 14 | 15 | 16 | @Test 17 | public void testInvalid(){ 18 | assertThrows(IllegalArgumentException.class,() -> 19 | getInstance().compute(-1)); 20 | } 21 | 22 | @Test 23 | public void testCompute00(){ 24 | assertEquals(0, getInstance().compute(0)); 25 | } 26 | 27 | @Test 28 | public void testCompute01(){ 29 | assertEquals(1, getInstance().compute(1)); 30 | } 31 | 32 | @Test 33 | public void testCompute02(){ 34 | assertEquals(1, getInstance().compute(2)); 35 | } 36 | 37 | @Test 38 | public void testCompute03(){ 39 | assertEquals(2, getInstance().compute(3)); 40 | } 41 | 42 | @Test 43 | public void testCompute04(){ 44 | assertEquals(3, getInstance().compute(4)); 45 | } 46 | 47 | @Test 48 | public void testCompute05(){ 49 | assertEquals(5, getInstance().compute(5)); 50 | } 51 | 52 | @Test 53 | public void testCompute06(){ 54 | assertEquals(8, getInstance().compute(6)); 55 | } 56 | 57 | @Test 58 | public void testCompute07(){ 59 | assertEquals(13, getInstance().compute(7)); 60 | } 61 | 62 | @Test 63 | public void testCompute08(){ 64 | assertEquals(21, getInstance().compute(8)); 65 | } 66 | 67 | @Test 68 | public void testCompute09(){ 69 | assertEquals(34, getInstance().compute(9)); 70 | } 71 | 72 | 73 | @Test 74 | public void testComputeHighValueNoException(){ 75 | //just check it is not throwing any exception 76 | getInstance().compute(100); 77 | } 78 | } -------------------------------------------------------------------------------- /exercises/src/test/java/org/pg4200/ex06/ImmutableBookAndAuthorTestTemplate.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex06; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | /** 8 | * Created by arcuri82 on 02-May-18. 9 | */ 10 | public abstract class ImmutableBookAndAuthorTestTemplate { 11 | 12 | protected abstract ImmutableBook getNewEmptyInstanceOfBook(); 13 | 14 | protected abstract ImmutableAuthor getNewEmptyInstanceOfAuthor(); 15 | 16 | 17 | @Test 18 | public void testModifyAuthor() { 19 | 20 | String n = "a name"; 21 | String s = "a surname"; 22 | 23 | ImmutableAuthor author = getNewEmptyInstanceOfAuthor() 24 | .withName(n) 25 | .withSurname(s); 26 | 27 | assertEquals(n, author.getName()); 28 | assertEquals(s, author.getSurname()); 29 | 30 | String foo = "foo"; 31 | ImmutableAuthor copy = author.withName(foo).withSurname("bar"); 32 | assertEquals(foo, copy.getName()); 33 | 34 | //not modified 35 | assertEquals(n, author.getName()); 36 | assertEquals(s, author.getSurname()); 37 | } 38 | 39 | @Test 40 | public void testModifyBook(){ 41 | 42 | String title = "Algorithms"; 43 | int year = 2018; 44 | 45 | ImmutableBook book = getNewEmptyInstanceOfBook() 46 | .withTitle(title) 47 | .withYear(year); 48 | 49 | assertEquals(title, book.getTitle()); 50 | assertEquals(year, book.getYear()); 51 | 52 | 53 | String foo = "foo"; 54 | ImmutableBook copy = book.withTitle(foo).withYear(0); 55 | assertEquals(foo, copy.getTitle()); 56 | 57 | //not modified 58 | assertEquals(title, book.getTitle()); 59 | assertEquals(year, book.getYear()); 60 | } 61 | 62 | @Test 63 | public void testModifyAuthorsInBook(){ 64 | 65 | String foo = "foo"; 66 | String bar = "bar"; 67 | 68 | ImmutableAuthor first = getNewEmptyInstanceOfAuthor().withName(foo); 69 | ImmutableAuthor second = getNewEmptyInstanceOfAuthor().withName(bar); 70 | 71 | ImmutableBook book = getNewEmptyInstanceOfBook() 72 | .withAuthors(first, second); 73 | 74 | assertEquals(2, book.getAuthors().size()); 75 | 76 | try{ 77 | book.getAuthors().clear(); 78 | }catch (Exception e){ 79 | //might or might not happen 80 | } 81 | 82 | assertEquals(2, book.getAuthors().size()); 83 | } 84 | } -------------------------------------------------------------------------------- /exercises/src/test/java/org/pg4200/ex07/ComputationExampleTraditionalTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex07; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | public class ComputationExampleTraditionalTest extends ComputationExampleTestTemplate{ 6 | 7 | @Override 8 | protected ComputationExample getNewInstance() { 9 | return new ComputationExampleTraditional(); 10 | } 11 | } -------------------------------------------------------------------------------- /exercises/src/test/java/org/pg4200/ex12/GradeCompressorTestTemplate.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.ex12; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.assertEquals; 6 | import static org.junit.jupiter.api.Assertions.assertTrue; 7 | 8 | public abstract class GradeCompressorTestTemplate { 9 | 10 | protected abstract GradeCompressor getNewInstance(); 11 | 12 | @Test 13 | public void testOne(){ 14 | 15 | GradeCompressor gc = getNewInstance(); 16 | 17 | String data = "0A"; 18 | byte[] compressed = gc.compress(data); 19 | assertTrue(compressed.length <= 2); 20 | 21 | String decompressed = gc.decompress(compressed); 22 | assertEquals(data, decompressed); 23 | } 24 | 25 | @Test 26 | public void testSeveral(){ 27 | 28 | GradeCompressor gc = getNewInstance(); 29 | 30 | String data = "0A1F2F3C12F13B14B27A201B497A"; 31 | byte[] compressed = gc.compress(data); 32 | String decompressed = gc.decompress(compressed); 33 | assertEquals(data, decompressed); 34 | } 35 | 36 | @Test 37 | public void test100(){ 38 | 39 | GradeCompressor gc = getNewInstance(); 40 | 41 | String data = ""; 42 | for(int i=0; i<100; i++){ 43 | data += (i + "A"); 44 | } 45 | 46 | byte[] compressed = gc.compress(data); 47 | assertTrue(compressed.length <= 150); 48 | 49 | String decompressed = gc.decompress(compressed); 50 | assertEquals(data, decompressed); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /lessons/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | pg4200-lessons 6 | jar 7 | 8 | 9 | org.pg4200 10 | pg4200-root 11 | 0.0.1-SNAPSHOT 12 | 13 | 14 | 15 | 16 | org.junit.jupiter 17 | junit-jupiter-api 18 | 19 | 20 | org.junit.jupiter 21 | junit-jupiter-engine 22 | 23 | 24 | org.junit.jupiter 25 | junit-jupiter-params 26 | 27 | 28 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les01/ArrayExample.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les01; 2 | 3 | /** 4 | * Created by arcuri82 on 14-Aug-17. 5 | */ 6 | public class ArrayExample { 7 | 8 | /** 9 | * Given an array as input, return the sum of all its elements inside. 10 | * 11 | * @return 0 if the array is empty 12 | */ 13 | public static int sum(int[] array){ 14 | 15 | /* 16 | The variable called "array" does not contain any element itself. 17 | It is actually a pointer (a 64-bit number) to the memory where the data 18 | is stored. 19 | */ 20 | 21 | if(array == null){ 22 | return 0; 23 | } 24 | 25 | int sum = 0; 26 | 27 | /* 28 | How long is the array in input? We do not know, it could 29 | be anything, and the algorithm should still work regardless. 30 | So, we need to use "array.length" to get such value. 31 | */ 32 | 33 | for(int i=0; i< array.length; i++){ 34 | 35 | /* 36 | "array[i]" means: 37 | go to the position in memory with location "array + i", 38 | read the next 4 bytes, and return those interpreted as 39 | a "int" value. 40 | 41 | IMPORTANT: in Java you cannot manipulate object pointers 42 | directly, eg "array + i" will give you a compilation error. 43 | However, other languages (eg C/C++) allow it. 44 | */ 45 | 46 | sum += array[i]; 47 | } 48 | 49 | return sum; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les01/MyListString.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les01; 2 | 3 | /** 4 | * In most programs, we need to store data, and then being able to retrieve it later on. 5 | * For example, we could need to store info about which items we selected in a shopping cart (eg Amazon), 6 | * preferred songs in a play list, etc. 7 | * 8 | * Why using an interface? Because there can be many different ways to implement such functionalities, but 9 | * for the client that uses such class, the implementation details are not important from the functionality 10 | * point of view. 11 | * But then, why having different implementations? 12 | * Reason: PERFORMANCE!!! 13 | * Based on how it is implemented, each operation will have a different cost (e.g., running time 14 | * and memory consumption). 15 | * So when you choose a specific implementation to use, such choice would be based 16 | * on which operations are expected to be used most. 17 | * 18 | * There are different kinds of containers. Containers in which stored elements are laid 19 | * out in a precise, consecutive order are usually called "List". 20 | * 21 | * A container could contain different kinds of data, e.g., strings, numbers, song objects, etc. 22 | * For now, we just consider storing String objects. 23 | * 24 | * For the moment, we do not handle yet the more complex functionality of deleting elements 25 | * and insertions at any position in the list 26 | */ 27 | public interface MyListString { 28 | 29 | /** 30 | * Get the string stored in position defined by "index". 31 | * Indices starts at 0, and consecutive with no gaps, i.e., 0, 1, 2, 3, ... 32 | * like in an array 33 | * 34 | * Return "null" if index is invalid 35 | */ 36 | String get(int index); 37 | 38 | /** 39 | * Add a new value to the list, in the smaller available index (starting from 0). 40 | * Ie, append the value at the end of the list. 41 | */ 42 | void add(String value); 43 | 44 | /** 45 | * Get how many elements this list has. 46 | */ 47 | int size(); 48 | } 49 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les01/arraylist/MyArrayListString.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les01.arraylist; 2 | 3 | import org.pg4200.les01.MyListString; 4 | 5 | /** 6 | * Created by arcuri82 on 14-Aug-17. 7 | */ 8 | public class MyArrayListString implements MyListString { 9 | 10 | /** 11 | * Here we use an array to backup the data we insert in the container. 12 | */ 13 | private String[] data; 14 | 15 | /** 16 | * The "size" of the container is not going to be necessarily equal to the length 17 | * of the "data" array. 18 | */ 19 | private int size = 0; 20 | 21 | public MyArrayListString(){ 22 | //call the other constructor with "10" as default max size. 23 | this(10); 24 | } 25 | 26 | public MyArrayListString(int maxSize){ 27 | data = new String[maxSize]; 28 | } 29 | 30 | @Override 31 | public String get(int index) { 32 | if(index < 0 || index >= size){ 33 | //some input validation 34 | return null; 35 | } 36 | return data[index]; 37 | } 38 | 39 | @Override 40 | public void add(String value) { 41 | data[size] = value; 42 | size++; 43 | } 44 | 45 | @Override 46 | public int size() { 47 | return size; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les01/linkedlist/MyDelegateListString.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les01.linkedlist; 2 | 3 | import org.pg4200.les01.MyListString; 4 | 5 | import java.util.LinkedList; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by arcuri82 on 15-Aug-17. 10 | */ 11 | public class MyDelegateListString implements MyListString { 12 | 13 | /* 14 | The Java API provides many implementations for containers, eg in 15 | the "java.util.*" package. 16 | It is unlikely that you will ever need to implement your own containers, 17 | as we do here in this course. 18 | The point is that, to properly choose which container to use, you need 19 | to understand how they work internally. 20 | 21 | Technically, to fulfil the contract of the MyListString interface, 22 | I could use internally an actual list from the Java API, and "delegate" all the 23 | methods on such list. 24 | 25 | It is technically correct, although quite pointless: why not using the Java API directly? 26 | In the exercises in this course (and the exam), you are NOT allowed to write this kind 27 | of delegate code, unless otherwise specified. 28 | Even worse, do NOT do it in a job interview... 29 | Note: we will looking into "Generics" (eg, "") next class. 30 | */ 31 | private List delegate = new LinkedList<>(); 32 | 33 | @Override 34 | public String get(int index) { 35 | 36 | try { 37 | return delegate.get(index); 38 | } catch (Exception e){ 39 | /* 40 | The Java API has different semantics regarding how to 41 | handle invalid inputs, ie it throws an exception 42 | */ 43 | return null; 44 | } 45 | } 46 | 47 | @Override 48 | public void add(String value) { 49 | delegate.add(value); 50 | } 51 | 52 | @Override 53 | public int size() { 54 | return delegate.size(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les02/list/MyList.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.list; 2 | 3 | /** 4 | * Before we defined a list interface to hold String objects. 5 | * But what if I need to store more complex objects, like an hypothetical 6 | * Song, PurchaseOrder, etc? 7 | * 8 | * As the "type" of what we store is not important, we use Java "Generics" 9 | * 10 | * Furthermore, now we also consider operations like delete and insertions in 11 | * any position. 12 | * 13 | * Created by arcuri82 on 15-Aug-17. 14 | */ 15 | public interface MyList { 16 | 17 | /** 18 | * Delete the element at position "index". 19 | * 20 | * Throw an exception if index is invalid 21 | */ 22 | void delete(int index); 23 | 24 | /* 25 | Interface can have code, but no state. 26 | Here, we use the "size()" method. 27 | How to use "size()" to implement "isEmpty()" 28 | is independent of how size itself is implemented. 29 | 30 | Note: the implementing class could override this 31 | method if there is a more efficient way to check 32 | for emptiness (eg if "size()" is expensive) 33 | */ 34 | default boolean isEmpty(){ 35 | return size() == 0; 36 | } 37 | 38 | /** 39 | * Get the value stored in position defined by "index". 40 | * 41 | * Throw an exception if index is invalid 42 | */ 43 | T get(int index); 44 | 45 | 46 | /** 47 | * Add a new value to the list, in the smaller available index (starting from 0). 48 | * Ie, append the value at the end of the list. 49 | */ 50 | default void add(T value){ 51 | /* 52 | Although an interface cannot have instance state, it can have implementation 53 | of methods. Those need to be declared with "default", and can call the other 54 | methods in this interface. 55 | In this particular example, adding at the end of the list is equivalent to 56 | add at position equal to the size of list itself. 57 | For example, appending to an empty list is the same as adding at position 0. 58 | */ 59 | add(size(), value); 60 | } 61 | 62 | 63 | /** 64 | * Add a new value to the list, at the specified index position. 65 | * 66 | * Throw an exception if index is invalid 67 | */ 68 | void add(int index, T value); 69 | 70 | /** 71 | * Get how many elements this collection has. 72 | */ 73 | int size(); 74 | } 75 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les02/queue/MyQueue.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.queue; 2 | 3 | /** 4 | * Queues are FIFO: First in, First out 5 | * 6 | * Note: "queue" (British English) is the same as "line" (American English) 7 | * 8 | * Created by arcuri82 on 16-Aug-17. 9 | */ 10 | public interface MyQueue { 11 | 12 | /** 13 | * Insert a new element at the tail of the queue/line 14 | */ 15 | void enqueue(T value); 16 | 17 | /** 18 | * Remove and return the element at the head of the queue/line 19 | */ 20 | T dequeue(); 21 | 22 | /** 23 | * Look at the head of the queue/line, without removing it 24 | */ 25 | T peek(); 26 | 27 | int size(); 28 | 29 | default boolean isEmpty(){ 30 | return size() == 0; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les02/queue/MyQueueLinkedList.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.queue; 2 | 3 | import org.pg4200.les02.list.MyLinkedList; 4 | 5 | /** 6 | * Created by arcuri82 on 16-Aug-17. 7 | */ 8 | public class MyQueueLinkedList extends MyLinkedList implements MyQueue { 9 | 10 | /* 11 | Here, we can simply extend MyLinkedList, and define the queue methods using it. 12 | This is not inefficient, in contrast to MyArrayList which would have awful performance. 13 | */ 14 | 15 | @Override 16 | public void enqueue(T value) { 17 | add(value); 18 | } 19 | 20 | @Override 21 | public T dequeue() { 22 | if(isEmpty()){ 23 | throw new RuntimeException(); 24 | } 25 | 26 | T value = get(0); 27 | delete(0); 28 | 29 | return value; 30 | } 31 | 32 | @Override 33 | public T peek() { 34 | if(isEmpty()){ 35 | throw new RuntimeException(); 36 | } 37 | 38 | return get(0); 39 | } 40 | 41 | @Override 42 | public boolean isEmpty() { 43 | return size() == 0; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les02/stack/MyStack.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.stack; 2 | 3 | /** 4 | * Stacks ar LIFO: Last In, First Out. 5 | */ 6 | public interface MyStack { 7 | 8 | /** 9 | * Add the value on top of the stack 10 | */ 11 | void push(T value); 12 | 13 | /** 14 | * Retrieve the value on top of the stack, 15 | * but do not alter the stack itself. 16 | * 17 | * Throw an exception if the stack is empty 18 | */ 19 | T peek(); 20 | 21 | /** 22 | * Remove and return the value on top of the stack. 23 | * 24 | * Throw an exception if the stack is empty. 25 | */ 26 | T pop(); 27 | 28 | 29 | int size(); 30 | 31 | 32 | default boolean isEmpty(){ 33 | return size() == 0; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les02/stack/MyStackArray.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.stack; 2 | 3 | import org.pg4200.les02.list.MyArrayList; 4 | 5 | public class MyStackArray extends MyArrayList implements MyStack{ 6 | 7 | public MyStackArray() { 8 | } 9 | 10 | public MyStackArray(int capacity) { 11 | super(capacity); 12 | } 13 | 14 | /* 15 | Here, we can simply extend MyArrayList, and define the stack operations 16 | based on the methods in the list 17 | */ 18 | 19 | @Override 20 | public void push(T value) { 21 | //pushing is like adding at the end 22 | add(value); 23 | } 24 | 25 | @Override 26 | public T peek() { 27 | if(isEmpty()){ 28 | throw new RuntimeException(); 29 | } 30 | return get(size()-1); 31 | } 32 | 33 | @Override 34 | public T pop() { 35 | if(isEmpty()){ 36 | throw new RuntimeException(); 37 | } 38 | T value = get(size()-1); 39 | delete(size()-1); 40 | return value; 41 | } 42 | 43 | @Override 44 | public boolean isEmpty() { 45 | return size() == 0; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les02/stack/MyStackDelegate.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.stack; 2 | 3 | import org.pg4200.les02.list.MyArrayList; 4 | import org.pg4200.les02.list.MyList; 5 | import org.pg4200.les02.list.MyLinkedList; 6 | 7 | public class MyStackDelegate implements MyStack { 8 | 9 | private MyList delegate; 10 | 11 | /** 12 | * Use private constructor to prevent clients from 13 | * directly instantiate this class. 14 | * 15 | * New instances will be returned ONLY via static methods. 16 | */ 17 | private MyStackDelegate(){ 18 | } 19 | 20 | /** 21 | * Return a new instance of this class, where the internal delegate list 22 | * is of type MyArrayList 23 | */ 24 | public static MyStackDelegate backedByArrayList(Class klass){ 25 | MyStackDelegate container = new MyStackDelegate<>(); 26 | container.delegate = new MyArrayList<>(); 27 | return container; 28 | } 29 | 30 | /** 31 | * Return a new instance of this class, where the internal delegate list 32 | * is of type MyLinkedList 33 | */ 34 | public static MyStackDelegate backedByLinkedList(Class klass){ 35 | MyStackDelegate container = new MyStackDelegate<>(); 36 | container.delegate = new MyLinkedList<>(); 37 | return container; 38 | } 39 | 40 | @Override 41 | public void push(T value) { 42 | delegate.add(value); 43 | } 44 | 45 | @Override 46 | public T peek() { 47 | if(isEmpty()){ 48 | throw new RuntimeException(); 49 | } 50 | return delegate.get(size()-1); 51 | } 52 | 53 | @Override 54 | public T pop() { 55 | if(isEmpty()){ 56 | throw new RuntimeException(); 57 | } 58 | T value = delegate.get(size()-1); 59 | delegate.delete(size()-1); 60 | return value; 61 | } 62 | 63 | @Override 64 | public int size() { 65 | return delegate.size(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les02/stack/MyStackLinkedList.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.stack; 2 | 3 | // WARNING: this is one of the 12 classes you need to study and know by heart 4 | 5 | 6 | public class MyStackLinkedList implements MyStack{ 7 | 8 | private class StackNode { 9 | T value; 10 | StackNode previous; 11 | } 12 | 13 | /* 14 | We could extend MyLinkedList (which would had been fine). 15 | But, for a stack, we don't need a head. 16 | So, here we just implement it directly. 17 | */ 18 | private StackNode tail; 19 | 20 | private int size; 21 | 22 | @Override 23 | public void push(T value) { 24 | 25 | StackNode node = new StackNode(); 26 | node.value = value; 27 | size++; 28 | 29 | if(tail == null){ 30 | //first element to insert in empty list 31 | tail = node; 32 | return; 33 | } 34 | 35 | node.previous = tail; 36 | tail = node; 37 | } 38 | 39 | @Override 40 | public T peek() { 41 | if(tail == null){ 42 | throw new RuntimeException(); 43 | } 44 | 45 | return tail.value; 46 | } 47 | 48 | @Override 49 | public T pop() { 50 | if(tail == null){ 51 | throw new RuntimeException(); 52 | } 53 | 54 | T value = tail.value; 55 | tail = tail.previous; 56 | 57 | size--; 58 | 59 | return value; 60 | } 61 | 62 | @Override 63 | public int size() { 64 | return size; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les03/sort/BubbleSort.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les03.sort; 2 | 3 | // WARNING: this is one of the 12 classes you need to study and know by heart 4 | 5 | 6 | /** 7 | * Created by arcuri82 on 21-Aug-17. 8 | */ 9 | public class BubbleSort implements MySort { 10 | 11 | 12 | @Override 13 | public > void sort(T[] array) { 14 | 15 | if (array == null) { 16 | return; 17 | } 18 | 19 | //make sure we enter into first loop of the "while" 20 | boolean swapped = true; 21 | 22 | while (swapped) { 23 | 24 | /* 25 | if there is not going to be any swapping, then the 26 | array is sorted, and we do not need to recheck 27 | */ 28 | 29 | swapped = false; 30 | 31 | for (int i = 0; i < array.length - 1; i++) { 32 | int j = i + 1; 33 | /* 34 | if current element is greater than next, 35 | then swap them. 36 | Like a bubble, the highest value will fly up. 37 | */ 38 | 39 | if (array[i].compareTo(array[j]) > 0) { 40 | T tmp = array[i]; 41 | array[i] = array[j]; 42 | array[j] = tmp; 43 | 44 | swapped = true; 45 | } 46 | } 47 | } 48 | 49 | /* 50 | In best case, we still need to traverse the array once: Omega(n) 51 | 52 | Worst case (inverted array), we need an iteration for each element 53 | at least once: O(n^2) 54 | */ 55 | } 56 | } 57 | 58 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les03/sort/InsertionSort.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les03.sort; 2 | 3 | // WARNING: this is one of the 12 classes you need to study and know by heart 4 | 5 | 6 | 7 | public class InsertionSort implements MySort { 8 | 9 | @Override 10 | public > void sort(T[] array) { 11 | 12 | if (array == null) { 13 | return; 14 | } 15 | 16 | /* 17 | We start from 1 (2nd element), as an array of length 0 18 | or 1 is sorted by definition 19 | */ 20 | for(int i=1; i=0; j--){ 33 | if (array[j].compareTo(array[j+1]) > 0) { 34 | T tmp = array[j+1]; 35 | array[j+1] = array[j]; 36 | array[j] = tmp; 37 | } else { 38 | break; 39 | } 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les03/sort/MySort.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les03.sort; 2 | 3 | /** 4 | * Created by arcuri82 on 21-Aug-17. 5 | */ 6 | public interface MySort { 7 | 8 | /** 9 | * Sort the input array in ascending order. 10 | * The array can be of any type, as long as such 11 | * type implements the interface java.land.Comparable 12 | * 13 | * Note that Comparable use Generics, as it defines a method 14 | * (called compareTo) used to compare with other instances. 15 | * If you need to compare an object of (generic) type T with 16 | * another instance of same type T, then you need Comparable < T >. 17 | * So you want a class of type T that does implement the interface Comparable < T >. 18 | */ 19 | > void sort(T[] array); 20 | } 21 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les03/sort/Song.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les03.sort; 2 | 3 | /** 4 | * Created by arcuri82 on 21-Aug-17. 5 | */ 6 | public class Song implements Comparable { 7 | 8 | private final String artist; 9 | private final String title; 10 | private final int popularity; 11 | 12 | public Song(String artist, String title, int popularity) { 13 | this.artist = artist; 14 | this.title = title; 15 | this.popularity = popularity; 16 | } 17 | 18 | /* 19 | You might need to sort complex objects. 20 | But you need to define how an element X 21 | is compared to another Y. 22 | If same, the comparison should return 0. 23 | Otherwise a negative number (eg -1) if lower, 24 | or positive if higher. 25 | */ 26 | @Override 27 | public int compareTo(Song other) { 28 | 29 | int comp = other.popularity - popularity; 30 | if (comp != 0) { 31 | return comp; 32 | } 33 | 34 | comp = artist.compareTo(other.artist); 35 | if (comp != 0) { 36 | return comp; 37 | } 38 | 39 | return title.compareTo(other.title); 40 | } 41 | 42 | public String getArtist() { 43 | return artist; 44 | } 45 | 46 | public String getTitle() { 47 | return title; 48 | } 49 | 50 | public int getPopularity() { 51 | return popularity; 52 | } 53 | } 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les03/sort/SortExample.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les03.sort; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * Created by arcuri82 on 21-Aug-17. 7 | */ 8 | public class SortExample { 9 | 10 | public static void main(String[] args){ 11 | 12 | String[] names = { 13 | "Sara", 14 | "Jack", 15 | "Robert", 16 | "John", 17 | "Elisabeth", 18 | "Per", 19 | "Erik", 20 | "Richard", 21 | "Maria", 22 | "Bob" 23 | }; 24 | 25 | /* 26 | * Practically all languages have built-in APIs to sort 27 | * collections, like arrays. 28 | * You will not need to implement sorting in your programs, 29 | * but need to understand how it works. 30 | * 31 | * How is sorting implemented? What is its complexity? 32 | * Ie, if I double the size, will it take twice as long to sort? 33 | * (Answer: no, likely it will take more than twice as long) 34 | */ 35 | Arrays.sort(names); 36 | 37 | for(String s : names){ 38 | System.out.println(s); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les04/recursion/RecursiveSumArray.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les04.recursion; 2 | 3 | /** 4 | * Created by arcuri82 on 07-Jun-19. 5 | */ 6 | public class RecursiveSumArray { 7 | 8 | public static int sumSingleCall(int[] array){ 9 | return sumSingleCall(array, 0, array.length-1); 10 | } 11 | 12 | private static int sumSingleCall(int[] array, int start, int end){ 13 | 14 | if(start == end){ 15 | //only 1 value 16 | return array[start]; 17 | } 18 | 19 | if(start > end){ 20 | //invalid indices 21 | return 0; 22 | } 23 | 24 | /* 25 | to sum all values between start and end, we can take the current 26 | array[start] value and add it the sum of start+1 till end 27 | */ 28 | return array[start] + sumSingleCall(array, start+1, end); 29 | } 30 | 31 | 32 | public static int sumTwoCalls(int[] array){ 33 | return sumTwoCalls(array, 0, array.length-1); 34 | } 35 | 36 | private static int sumTwoCalls(int[] array, int start, int end){ 37 | 38 | if(start == end){ 39 | //only 1 value 40 | return array[start]; 41 | } 42 | 43 | if(start > end){ 44 | //invalid indices 45 | return 0; 46 | } 47 | 48 | int middle = (int)((double) (start + end) / 2d); 49 | 50 | /* 51 | The sum of all values in an array is equal to the sum in its left-half 52 | plus the sum in its right-half 53 | */ 54 | return sumTwoCalls(array, start, middle) + sumTwoCalls(array, middle + 1, end); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les04/recursion/RecursiveSumOfN.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les04.recursion; 2 | 3 | /** 4 | * Created by arcuri82 on 06-Jun-19. 5 | */ 6 | public class RecursiveSumOfN { 7 | 8 | 9 | /* 10 | Return the sum of all values from 1 to n, ie 11 | 1 + 2 + ... + (n-2) + (n-1) + n 12 | */ 13 | public static int sumOfAllValues(int n){ 14 | 15 | if(n < 0){ 16 | throw new IllegalArgumentException("Invalid negative value: " + n); 17 | } 18 | 19 | /* 20 | Always remember the stopping condition! 21 | */ 22 | if(n==0 || n==1){ 23 | return n; 24 | } 25 | 26 | /* 27 | Recursion calls are often done on "smaller" inputs. 28 | The keep calling and decreasing until a stopping condition is met. 29 | */ 30 | return n + sumOfAllValues(n-1); 31 | } 32 | 33 | 34 | public static int sumOfAllValuesNoStopping(int n){ 35 | 36 | /* 37 | This keep on calling itself, with no stopping criterion 38 | */ 39 | return n + sumOfAllValuesNoStopping(n-1); 40 | } 41 | 42 | 43 | 44 | } 45 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les04/sort/QuickSort.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les04.sort; 2 | 3 | // WARNING: this is one of the 12 classes you need to study and know by heart 4 | 5 | 6 | import org.pg4200.les03.sort.MySort; 7 | 8 | /** 9 | * Created by arcuri82 on 21-Aug-17. 10 | */ 11 | public class QuickSort implements MySort { 12 | 13 | 14 | @Override 15 | public > void sort(T[] array) { 16 | if(array == null || array.length <= 1){ 17 | return; 18 | } 19 | 20 | quicksort(0, array.length-1, array); 21 | } 22 | 23 | private > void quicksort(int low, int high, T[] array) { 24 | 25 | int i = low; 26 | int j = high; 27 | 28 | /* 29 | Choice of pivot is critical for the performance 30 | of the algorithm. 31 | Another option here would be to take it at random. 32 | */ 33 | T pivot = array[low + (high-low)/2]; 34 | 35 | while (i <= j) { 36 | 37 | while (array[i].compareTo(pivot) < 0) { 38 | i++; 39 | } 40 | 41 | while (array[j].compareTo(pivot) > 0) { 42 | j--; 43 | } 44 | 45 | if (i <= j) { 46 | T tmp = array[i]; 47 | array[i] = array[j]; 48 | array[j] = tmp; 49 | i++; 50 | j--; 51 | } 52 | } 53 | 54 | if (j > low) { 55 | quicksort(low, j, array); 56 | } 57 | 58 | if (i < high) { 59 | quicksort(i, high, array); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les05/MyMap.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les05; 2 | 3 | /** 4 | * Created by arcuri82 on 21-Aug-17. 5 | */ 6 | public interface MyMap, V> { 7 | 8 | /** 9 | * Create a mapping from the given Key to the given Value. 10 | * If a mapping for Key already exists, replace the old 11 | * value with this new one 12 | * 13 | * @throws NullPointerException if the {@code key} is null 14 | */ 15 | void put(K key, V value); 16 | 17 | /** 18 | * Remove the given key from the container. 19 | * 20 | * @throws NullPointerException if the {@code key} is null 21 | */ 22 | void delete(K key); 23 | 24 | /** 25 | * Return the value in the container mapped by the given key 26 | * 27 | * @throws NullPointerException if the {@code key} is null 28 | */ 29 | V get(K key); 30 | 31 | /** 32 | * The number of elements in the container 33 | */ 34 | int size(); 35 | 36 | /** 37 | * Check if there is no element in the container 38 | */ 39 | default boolean isEmpty(){ 40 | return size() == 0; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les05/MyMapLinearSearchArray.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les05; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Objects; 6 | 7 | /** 8 | * Created by arcuri82 on 21-Aug-17. 9 | */ 10 | public class MyMapLinearSearchArray,V> implements MyMap{ 11 | 12 | private class Entry,V> implements Comparable>{ 13 | K key; 14 | V value; 15 | 16 | public Entry(K key, V value) { 17 | this.key = key; 18 | this.value = value; 19 | } 20 | 21 | @Override 22 | public int compareTo(Entry o) { 23 | //Note that here we ignore the "value" 24 | return key.compareTo(o.key); 25 | } 26 | } 27 | 28 | private List> data = new ArrayList<>(); 29 | 30 | 31 | @Override 32 | public void put(K key, V value) { 33 | 34 | Objects.requireNonNull(key); 35 | 36 | Entry entry = new Entry<>(key, value); 37 | 38 | int index = Search.findInNonSorted(data, entry); 39 | 40 | if(index < 0){ 41 | data.add(entry); 42 | } else { 43 | data.get(index).value = value; 44 | } 45 | } 46 | 47 | @Override 48 | public void delete(K key) { 49 | 50 | Objects.requireNonNull(key); 51 | 52 | int index = Search.findInNonSorted(data, new Entry<>(key, null)); 53 | 54 | if(index >= 0){ 55 | data.remove(index); 56 | } 57 | } 58 | 59 | @Override 60 | public V get(K key) { 61 | 62 | Objects.requireNonNull(key); 63 | 64 | int index = Search.findInNonSorted(data, new Entry<>(key, null)); 65 | 66 | if(index < 0){ 67 | return null; 68 | } 69 | 70 | return data.get(index).value; 71 | } 72 | 73 | @Override 74 | public int size() { 75 | return data.size(); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les05/MyMapTreeBased.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les05; 2 | 3 | /** 4 | * We are going to show a few implementations of maps using trees. 5 | * An important aspect of a tree that does impact its performance is 6 | * its maximum depth. 7 | * 8 | * As this info has no meaning for the other kinds of maps, here we 9 | * create a sub-interface. 10 | * 11 | * Created by arcuri82 on 22-Aug-17. 12 | */ 13 | public interface MyMapTreeBased, V> extends MyMap { 14 | 15 | int getMaxTreeDepth(); 16 | 17 | } 18 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les05/Search.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les05; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by arcuri82 on 21-Aug-17. 7 | */ 8 | public class Search { 9 | 10 | 11 | public static > int findInNonSorted(List list, T element){ 12 | 13 | if(list == null || list.isEmpty() || element == null){ 14 | return -1; 15 | } 16 | 17 | for(int i=0; i> int findInSorted(List list, T element){ 29 | 30 | if(list == null || list.isEmpty() || element == null){ 31 | return -1; 32 | } 33 | 34 | return binarySearch(0, list.size()-1, list, element); 35 | } 36 | 37 | private static > int binarySearch(int low, int high, List list, T element){ 38 | 39 | if(low > high){ 40 | return -1; 41 | } 42 | 43 | /* 44 | middle = low + (high - low) / 2 45 | = (2low + high - low) / 2 46 | = (low + high) / 2 47 | */ 48 | 49 | int middle = (low + high) / 2; 50 | T value = list.get(middle); 51 | 52 | int comp = element.compareTo(value); 53 | 54 | if(comp == 0){ 55 | return middle; 56 | } else if(comp < 0){ 57 | return binarySearch(low, middle-1, list, element); 58 | } else { 59 | return binarySearch(middle+1, high, list, element); 60 | } 61 | 62 | /* 63 | What is the complexity of this algorithm??? 64 | Informally, at each step we only consider half of input range. 65 | The recursion ends when low>high, ie when range is 0. 66 | 67 | Given a value N, how many times x can we divide it by 2 before 68 | we get a value <=1 ??? 69 | 70 | N = 2^x 71 | 2^x = N 72 | x = log(N) 73 | 74 | So we can say that binary search is upper-bounded by O(log n), which 75 | is much, much better than O(n) 76 | */ 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les06/copy/CopyExample.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les06.copy; 2 | 3 | public class CopyExample { 4 | 5 | public static String[] copyWrong(String[] input){ 6 | if(input == null){ 7 | return null; 8 | } 9 | /* 10 | We have a new variable, pointing to same array. 11 | Any change in this array will be seen by the input one as well. 12 | */ 13 | String[] output = input; 14 | return output; 15 | } 16 | 17 | public static String[] copy(String[] input){ 18 | if(input == null){ 19 | return null; 20 | } 21 | 22 | //create a new array 23 | String[] output = new String[input.length]; 24 | for(int i=0; i { 15 | 16 | void put(K key, V value); 17 | 18 | void delete(K key); 19 | 20 | V get(K key); 21 | 22 | int size(); 23 | 24 | default boolean isEmpty(){ 25 | return size() == 0; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les06/immutability/User.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les06.immutability; 2 | 3 | /** 4 | * Created by arcuri82 on 14-Sep-17. 5 | */ 6 | public class User { 7 | 8 | private String name; 9 | private String surname; 10 | private int id; 11 | 12 | /* 13 | NOTE: ALL the code from this point on was AUTOMATICALLY generated in 14 | IntelliJ. 15 | You can right-click, select "Generate...", and then: 16 | - Constructor 17 | - equals() and hashCode() 18 | - Getter and Setter 19 | */ 20 | 21 | public User(String name, String surname, int id) { 22 | this.name = name; 23 | this.surname = surname; 24 | this.id = id; 25 | } 26 | 27 | @Override 28 | public boolean equals(Object o) { 29 | if (this == o) return true; 30 | if (o == null || getClass() != o.getClass()) return false; 31 | 32 | User user = (User) o; 33 | 34 | if (id != user.id) return false; 35 | if (name != null ? !name.equals(user.name) : user.name != null) return false; 36 | return surname != null ? surname.equals(user.surname) : user.surname == null; 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | int result = name != null ? name.hashCode() : 0; 42 | result = 31 * result + (surname != null ? surname.hashCode() : 0); 43 | result = 31 * result + id; 44 | return result; 45 | } 46 | 47 | public String getName() { 48 | return name; 49 | } 50 | 51 | public void setName(String name) { 52 | this.name = name; 53 | } 54 | 55 | public String getSurname() { 56 | return surname; 57 | } 58 | 59 | public void setSurname(String surname) { 60 | this.surname = surname; 61 | } 62 | 63 | public int getId() { 64 | return id; 65 | } 66 | 67 | public void setId(int id) { 68 | this.id = id; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les06/immutability/UserCorrectHash.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les06.immutability; 2 | 3 | /** 4 | * Created by arcuri82 on 14-Sep-17. 5 | */ 6 | public class UserCorrectHash extends UserWrongHash { 7 | 8 | public UserCorrectHash(String name, String surname, int id) { 9 | super(name, surname, id); 10 | } 11 | 12 | /* 13 | As "equals()" is based only on the state of "id", then we 14 | must do the same as well for hashCode 15 | */ 16 | 17 | @Override 18 | public int hashCode() { 19 | return getId(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les06/immutability/UserImmutable.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les06.immutability; 2 | 3 | /** 4 | * If for any reason you use an object in a set, or as a key in a map, 5 | * it MUST be IMMUTABLE. 6 | * 7 | * Note: String and Integer are immutable. 8 | * For example, when you call String#toLowerCase that does not change 9 | * the current string, but rather create a new one with all chars in lower case. 10 | * 11 | * Created by arcuri82 on 14-Sep-17. 12 | */ 13 | public class UserImmutable { 14 | 15 | private final String name; 16 | private final String surname; 17 | private final int id; 18 | 19 | 20 | public UserImmutable(String name, String surname, int id) { 21 | this.name = name; 22 | this.surname = surname; 23 | this.id = id; 24 | } 25 | 26 | /* 27 | Instead of changing the values of an object, we create 28 | a new copy with that new value overriding the current one 29 | */ 30 | 31 | public UserImmutable withName(String s){ 32 | return new UserImmutable(s, surname, id); 33 | } 34 | 35 | public UserImmutable withSurname(String s){ 36 | return new UserImmutable(name, s, id); 37 | } 38 | 39 | public UserImmutable withId(int x){ 40 | return new UserImmutable(name, surname, x); 41 | } 42 | 43 | /* 44 | We can have getters, but no setters, as all fields are final 45 | */ 46 | 47 | public String getName() { 48 | return name; 49 | } 50 | 51 | public String getSurname() { 52 | return surname; 53 | } 54 | 55 | public int getId() { 56 | return id; 57 | } 58 | 59 | 60 | @Override 61 | public boolean equals(Object o) { 62 | if (this == o) return true; 63 | if (o == null || getClass() != o.getClass()) return false; 64 | 65 | UserImmutable that = (UserImmutable) o; 66 | 67 | if (id != that.id) return false; 68 | if (name != null ? !name.equals(that.name) : that.name != null) return false; 69 | return surname != null ? surname.equals(that.surname) : that.surname == null; 70 | } 71 | 72 | @Override 73 | public int hashCode() { 74 | int result = name != null ? name.hashCode() : 0; 75 | result = 31 * result + (surname != null ? surname.hashCode() : 0); 76 | result = 31 * result + id; 77 | return result; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les06/immutability/UserWrongHash.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les06.immutability; 2 | 3 | /** 4 | * Created by arcuri82 on 14-Sep-17. 5 | */ 6 | public class UserWrongHash extends User{ 7 | 8 | public UserWrongHash(String name, String surname, int id) { 9 | super(name, surname, id); 10 | } 11 | 12 | /* 13 | If A.equals(B), then it MUST happen that A.hashCode() == B.hashCode(). 14 | If not, then it is going to be BIG problems... 15 | 16 | Let's say we want to change the behavior of User by looking for 17 | equality only if the id is the same. 18 | This might for example be done to save time on comparing name/surname 19 | if anyway the ids are unique. 20 | However, assume that we forget to change hashCode(), which would 21 | still be based on all 3 parameters... this would break the constrain above :( 22 | */ 23 | 24 | @Override 25 | public boolean equals(Object o) { 26 | if (this == o) return true; 27 | if (o == null || getClass() != o.getClass()) return false; 28 | 29 | User user = (User) o; 30 | 31 | return getId() == user.getId(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les06/set/MySet.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les06.set; 2 | 3 | /** 4 | * In mathematics, a Set is a collection of unique elements, 5 | * for which there is no ordering defined, ie no positions 6 | * like in a List. 7 | * 8 | * Created by arcuri82 on 14-Sep-17. 9 | */ 10 | public interface MySet { 11 | 12 | void add(E element); 13 | 14 | void remove(E element); 15 | 16 | boolean isPresent(E element); 17 | 18 | int size(); 19 | 20 | default boolean isEmpty(){ 21 | return size() == 0; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les06/set/MySetHashMap.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les06.set; 2 | 3 | import org.pg4200.les06.hash.MyHashMapWithLists; 4 | import org.pg4200.les06.hash.MyHashMap; 5 | 6 | /** 7 | * Created by arcuri82 on 14-Sep-17. 8 | */ 9 | public class MySetHashMap implements MySet { 10 | 11 | /* 12 | We use a map to represent a set. 13 | */ 14 | private MyHashMap map = new MyHashMapWithLists<>(); 15 | 16 | /** 17 | * We do not care about the values in the map. 18 | * So, let's create a single object, and re-use it for 19 | * all insertions. 20 | */ 21 | private static final Object PRESENCE = new Object(); 22 | 23 | @Override 24 | public void add(E element) { 25 | map.put(element, PRESENCE); 26 | } 27 | 28 | @Override 29 | public void remove(E element) { 30 | map.delete(element); 31 | } 32 | 33 | @Override 34 | public boolean isPresent(E element) { 35 | return map.get(element) != null; 36 | } 37 | 38 | @Override 39 | public int size() { 40 | return map.size(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les07/lambda/LambdaExamples.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les07.lambda; 2 | 3 | import java.util.function.Consumer; 4 | import java.util.function.Function; 5 | import java.util.function.Predicate; 6 | 7 | /** 8 | * Created by arcuri82 on 02-May-18. 9 | */ 10 | public class LambdaExamples { 11 | 12 | public static void useRunnable(Runnable runnable){ 13 | 14 | System.out.println("Before runnable"); 15 | runnable.run(); 16 | System.out.println("After runnable"); 17 | } 18 | 19 | public static void useConsumer(Consumer consumer){ 20 | 21 | String foo = "foo"; 22 | 23 | System.out.println("Before consumer"); 24 | consumer.accept(foo); 25 | System.out.println("After consumer"); 26 | } 27 | 28 | public static String usePredicate(Predicate predicate){ 29 | 30 | String foo = "foo"; 31 | 32 | if(predicate.test(foo)){ 33 | return foo; 34 | } else { 35 | return null; 36 | } 37 | } 38 | 39 | public static int useFunction(Function function){ 40 | 41 | String input = "foo"; 42 | 43 | return function.apply(input); 44 | } 45 | 46 | 47 | } 48 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les07/stream/MyStream.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les07.stream; 2 | 3 | import java.util.Iterator; 4 | import java.util.function.Consumer; 5 | import java.util.function.Function; 6 | import java.util.function.Predicate; 7 | 8 | /** 9 | * Think about "streams" like enhanced iterators over a collection. 10 | *

11 | * On a stream, we can apply transformation that can alter the data 12 | * in the stream, and how we retrieve such data. 13 | * This is achieved by pipelining different stream together. 14 | *

15 | * A stream will be closed by a terminal operation, which will 16 | * specify what to do with the values coming from the stream. 17 | * 18 | * Note: here we are only having a few examples of methods available 19 | * for streams. The collections in the JDK API have many more. 20 | * 21 | * Created by arcuri82 on 03-Oct-17. 22 | */ 23 | public interface MyStream { 24 | 25 | /** 26 | * Pipeline current stream into a new stream where elements are skipped 27 | * if they do not satisfy the given predicate 28 | */ 29 | MyStream filter(Predicate predicate); 30 | 31 | /** 32 | * Pipeline current stream into a new stream where the input values of 33 | * type T are transformed into new values of type R, according to the 34 | * given mapping function. 35 | * 36 | * Note: the term "map" here is NOT related to the Map collection type. 37 | */ 38 | MyStream map(Function mapper); 39 | 40 | /** 41 | * Pipeline current stream into a new stream where, for each input x 42 | * coming from the current stream, a new stream of type R is opened, 43 | * and all elements from such stream are propagated into the current 44 | * stream. 45 | * In other words, this is a way to flatten/combine k different streams 46 | * into a single one. 47 | * 48 | * Note: this is a bit tricky to grasp at first. Easier to understand 49 | * it with some working examples. 50 | */ 51 | MyStream flatMap(Function> mapper); 52 | 53 | /* 54 | Terminal Operations are what start the stream and retrieve 55 | all values from it. 56 | */ 57 | 58 | /** 59 | * For each value coming from the stream, execute the given action. 60 | */ 61 | void forEach(Consumer action); 62 | 63 | /** 64 | * Create a list. Add all elements coming from the stream 65 | * into this list. 66 | */ 67 | MyStreamCollectionList collectToList(); 68 | } 69 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les07/stream/MyStreamCollection.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les07.stream; 2 | 3 | /** 4 | * Just define an interface for classes on which we can open streams. 5 | * 6 | * Created by arcuri82 on 03-Oct-17. 7 | */ 8 | public interface MyStreamCollection extends Iterable { 9 | 10 | MyStream stream(); 11 | } 12 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les07/stream/MyStreamCollectionHashMap.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les07.stream; 2 | 3 | import org.pg4200.les07.iterator.MyIterableHashMap; 4 | 5 | /** 6 | * Created by arcuri82 on 03-Oct-17. 7 | */ 8 | public class MyStreamCollectionHashMap extends MyIterableHashMap implements MyStreamCollection { 9 | 10 | @Override 11 | public MyStream stream() { 12 | return MyStreamSupport.createStream(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les07/stream/MyStreamCollectionList.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les07.stream; 2 | 3 | import org.pg4200.les07.iterator.MyIterableLinkedList; 4 | 5 | /** 6 | * Created by arcuri82 on 03-Oct-17. 7 | */ 8 | public class MyStreamCollectionList extends MyIterableLinkedList implements MyStreamCollection { 9 | 10 | @Override 11 | public MyStream stream() { 12 | return MyStreamSupport.createStream(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les08/DirectedGraph.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les08; 2 | 3 | import java.util.Objects; 4 | import java.util.Set; 5 | 6 | /** 7 | * Created by arcuri82 on 26-Oct-17. 8 | */ 9 | public class DirectedGraph extends UndirectedGraph { 10 | 11 | /* 12 | We extend UndirectedGraph, as most of the code would be 13 | similar. 14 | However, we still have to override some methods. 15 | */ 16 | 17 | @Override 18 | public void addEdge(V from, V to) { 19 | Objects.requireNonNull(from); 20 | Objects.requireNonNull(to); 21 | 22 | addVertex(from); 23 | addVertex(to); 24 | 25 | graph.get(from).add(to); 26 | 27 | // note here we don't have "graph.get(to).add(from)" 28 | } 29 | 30 | @Override 31 | public int getNumberOfEdges() { 32 | return graph.values().stream() 33 | .mapToInt(s -> s.size()) 34 | .sum(); 35 | } 36 | 37 | 38 | @Override 39 | public void removeEdge(V from, V to) { 40 | 41 | Objects.requireNonNull(from); 42 | Objects.requireNonNull(to); 43 | 44 | Set connectedFrom = graph.get(from); 45 | 46 | if(connectedFrom != null){ 47 | connectedFrom.remove(to); 48 | } 49 | } 50 | 51 | @Override 52 | public void removeVertex(V vertex) { 53 | 54 | Objects.requireNonNull(vertex); 55 | 56 | if(! graph.containsKey(vertex)){ 57 | //nothing to do 58 | return; 59 | } 60 | 61 | graph.values().forEach(c -> c.remove(vertex)); 62 | 63 | graph.remove(vertex); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les08/Graph.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les08; 2 | 3 | import java.util.Collection; 4 | import java.util.List; 5 | import java.util.Set; 6 | 7 | /** 8 | * A graph is composed of vertices and edges. 9 | *

10 | * A vertex can be considered as a node. 11 | *

12 | * An edge connect a vertex X to another vertex Y. 13 | * Note, if Y==X, then it is a self-connection. 14 | *

15 | * Created by arcuri82 on 25-Oct-17. 16 | */ 17 | public interface Graph { 18 | 19 | void addVertex(V vertex); 20 | 21 | /** 22 | * Create edge from "from" to "to". 23 | * If either of them does not exist, create 24 | * those vertices. 25 | */ 26 | void addEdge(V from, V to); 27 | 28 | int getNumberOfVertices(); 29 | 30 | int getNumberOfEdges(); 31 | 32 | void removeEdge(V from, V to); 33 | 34 | /** 35 | * Besides removing the vertex, also remove 36 | * all edges in which it is involved. 37 | */ 38 | void removeVertex(V vertex); 39 | 40 | /** 41 | * Given a vertex X, return a collection of all 42 | * other vertices that can be reached from X. 43 | */ 44 | Collection getAdjacents(V vertex); 45 | 46 | /** 47 | * Use Depth First Search (DFS) to find a path (if any) 48 | * from a "start" vertex to a "end" vertex. 49 | */ 50 | List findPathDFS(V start, V end); 51 | 52 | /** 53 | * Use Breadth First Search (BFS) to find path 54 | */ 55 | List findPathBFS(V start, V end); 56 | 57 | default boolean hasPath(V start, V end) { 58 | return findPathDFS(start, end) != null; 59 | } 60 | 61 | /** 62 | * Given a vertex X, return all vertices that have a path reaching them from X. 63 | */ 64 | Set findConnected(V vertex); 65 | 66 | /** 67 | * Given a collection of vertices, return all vertices that have a path reaching 68 | * them from any vertex in the input collection 69 | */ 70 | Set findConnected(Iterable vertices); 71 | } 72 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les09/search/TextSearch.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les09.search; 2 | 3 | /** 4 | * Created by arcuri82 on 04-May-18. 5 | */ 6 | public interface TextSearch { 7 | 8 | /** 9 | * Find if given target is in the text 10 | * 11 | * @param text the String text to search in 12 | * @param target the String that we want to check if contained in the text 13 | * @return the index of first character starting the target inside the text, 14 | * otherwise a negative number if target is not present. 15 | */ 16 | int findFirst(String text, String target); 17 | 18 | /** 19 | * Find if the default target for this class is in the text. 20 | * As the code can do specific optimizations on the target, it could 21 | * do some pre-computation when this class is instantiated. 22 | * 23 | * @param text the String text to search in 24 | * @return the index of first character starting the default target inside the text, 25 | * otherwise a negative number if target is not present. 26 | * @throws IllegalStateException if no default target was defined 27 | */ 28 | int findFirst(String text) throws IllegalStateException; 29 | } 30 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les09/search/TextSearchBruteForce.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les09.search; 2 | 3 | /** 4 | * Created by arcuri82 on 04-May-18. 5 | */ 6 | public class TextSearchBruteForce implements TextSearch { 7 | 8 | private final String defaultToken; 9 | 10 | public TextSearchBruteForce() { 11 | defaultToken = null; 12 | } 13 | 14 | public TextSearchBruteForce(String defaultToken) { 15 | this.defaultToken = defaultToken; 16 | } 17 | 18 | @Override 19 | public int findFirst(String text) throws IllegalStateException{ 20 | if(defaultToken == null){ 21 | throw new IllegalStateException("No default target specified"); 22 | } 23 | 24 | return findFirst(text, defaultToken); 25 | } 26 | 27 | @Override 28 | public int findFirst(String text, String target) { 29 | 30 | if (text == null || target == null || target.isEmpty()) { 31 | throw new IllegalArgumentException("Invalid input"); 32 | } 33 | 34 | if (target.length() > text.length()) { 35 | //simple case 36 | return -1; 37 | } 38 | 39 | //check each position in text as starting point for target 40 | outer: for (int i = 0; i < text.length(); i++) { 41 | 42 | //check chars of target based on current starting point in text 43 | for (int j = 0; j < target.length(); j++) { 44 | if (text.charAt(i + j) != target.charAt(j)) { 45 | /* 46 | this will jump out of this "for", 47 | and continue to the next step in the 48 | "for" labelled with "outer" 49 | */ 50 | continue outer; 51 | } 52 | } 53 | 54 | return i; 55 | } 56 | 57 | //found nothing 58 | return -1; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les10/knapsack/BruteForceForKnapsack.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les10.knapsack; 2 | 3 | /** 4 | * Created by arcuri82 on 09-Oct-17. 5 | */ 6 | public class BruteForceForKnapsack { 7 | 8 | 9 | /** 10 | * Enumerate all possible combinations of 0/1, and 11 | * return best among them. 12 | */ 13 | public static boolean[] solve(KnapsackProblem problem){ 14 | 15 | boolean[] buffer = new boolean[problem.getSize()]; 16 | 17 | //start from index 0, return the best in the whole enumeration 18 | return recursive(problem, 0, buffer); 19 | } 20 | 21 | private static boolean[] recursive(KnapsackProblem problem, int index, boolean[] buffer){ 22 | 23 | if(index >= buffer.length){ 24 | //the index has reached the length of the array, so we are on a leaf 25 | return buffer.clone(); 26 | } 27 | 28 | //on the left-subtree recursion, consider "true" 29 | buffer[index] = true; 30 | /* 31 | this is a cloned array, which is the best among all the arrays 32 | that share exactly the same prefix of 0/1 up to position index, 33 | with value at index being 1 (ie "true"). 34 | 35 | Note: at each recursive call we increase the index by 1 36 | */ 37 | boolean[] withTrue = recursive(problem, index+1, buffer); 38 | 39 | //on the right-subtree recursion, consider "false" 40 | buffer[index] = false; 41 | /* 42 | this is a cloned array, which is the best among all the arrays 43 | that share exactly the same prefix of 0/1 up to position index, 44 | with value at index being 0 (ie "false") 45 | */ 46 | boolean[] withFalse = recursive(problem, index+1, buffer); 47 | 48 | /* 49 | so, we have 2 leaves: the best of the left-subtree, and 50 | the best on the right-subtree. 51 | based on their fitness, we return to the caller the best of 52 | these 2. 53 | */ 54 | if(problem.evaluate(withTrue) > problem.evaluate(withFalse)){ 55 | return withTrue; 56 | } else { 57 | return withFalse; 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les10/knapsack/RandomForKnapsack.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les10.knapsack; 2 | 3 | import java.util.Objects; 4 | import java.util.Random; 5 | 6 | /** 7 | * Created by arcuri82 on 09-Oct-17. 8 | */ 9 | public class RandomForKnapsack { 10 | 11 | 12 | public static boolean[] solve(int maxIterations, KnapsackProblem problem){ 13 | 14 | if(maxIterations < 1){ 15 | throw new IllegalArgumentException("Invalid number of iterations"); 16 | } 17 | Objects.requireNonNull(problem); 18 | 19 | Random random = new Random(); 20 | 21 | boolean[] solution = null; 22 | 23 | /* 24 | Just sample at random, and keep track of best 25 | solution found so far 26 | */ 27 | 28 | for(int i=0; i problem.evaluate(solution)){ 33 | solution = sampled; 34 | } 35 | } 36 | 37 | return solution; 38 | } 39 | 40 | private static boolean[] sample(int n, Random random){ 41 | 42 | /* 43 | Note: the code here is not particularly good... as we are 44 | instantiating a new array on the heap at each step. 45 | Even if we store only the best array, we are still polluting 46 | the heap, increasing the number of invocations of the 47 | JVM Garbage Collector. 48 | How to fix is given as exercise. 49 | */ 50 | boolean[] solution = new boolean[n]; 51 | for(int i=0; i 0; i--) 72 | { 73 | index = random.nextInt(i + 1); 74 | temp = array[index]; 75 | array[index] = array[i]; 76 | array[i] = temp; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les10/queens/RandomForQueens.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les10.queens; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * Created by arcuri82 on 09-Oct-17. 7 | */ 8 | public class RandomForQueens { 9 | 10 | public static int[] solve(int n){ 11 | 12 | if(n < 4){ 13 | throw new IllegalArgumentException("Too small board"); 14 | } 15 | 16 | int[] solution = new int[n]; 17 | for(int i=0; i 0; i--) 39 | { 40 | index = random.nextInt(i + 1); 41 | temp = array[index]; 42 | array[index] = array[i]; 43 | array[i] = temp; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lessons/src/main/java/org/pg4200/les11/ea/OnePlusOneEAForKnapsack.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les11.ea; 2 | 3 | import org.pg4200.les10.knapsack.KnapsackProblem; 4 | 5 | import java.util.Objects; 6 | import java.util.Random; 7 | 8 | public class OnePlusOneEAForKnapsack { 9 | 10 | public static boolean[] solve(int maxIterations, KnapsackProblem problem){ 11 | 12 | if(maxIterations < 1){ 13 | throw new IllegalArgumentException("Invalid number of iterations"); 14 | } 15 | Objects.requireNonNull(problem); 16 | 17 | Random random = new Random(); 18 | 19 | final int n = problem.getSize(); 20 | final double p = 1d / (double) n; 21 | 22 | boolean[] solution = sample(n, random); 23 | 24 | 25 | for(int i=1; i=" instead of 46 | ">". This is to allow "random walks" on "fitness plateaus", 47 | ie still explore the search space as long as individual does 48 | not get worse. 49 | */ 50 | 51 | if(problem.evaluate(offspring) >= problem.evaluate(solution)){ 52 | solution = offspring; 53 | } 54 | } 55 | 56 | return solution; 57 | } 58 | 59 | private static boolean[] sample(int n, Random random){ 60 | 61 | boolean[] solution = new boolean[n]; 62 | for(int i=0; i { 7 | 8 | private final K key; 9 | private final V value; 10 | 11 | public Pair(K key, V value) { 12 | this.key = key; 13 | this.value = value; 14 | } 15 | 16 | public K getKey() { 17 | return key; 18 | } 19 | 20 | public V getValue() { 21 | return value; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les01/ArrayExampleTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les01; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.pg4200.les01.ArrayExample; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertTrue; 8 | 9 | /** 10 | * Created by arcuri82 on 14-Aug-17. 11 | */ 12 | 13 | public class ArrayExampleTest { 14 | 15 | @Test 16 | public void testBase(){ 17 | 18 | //values initialized when array is created 19 | int[] array = {1, 2, 3}; 20 | 21 | int res = ArrayExample.sum(array); 22 | 23 | assertEquals(6, res); 24 | } 25 | 26 | @Test 27 | public void testNegative(){ 28 | 29 | //first create array, then populate it 30 | int[] array = new int[3]; 31 | array[0] = -2; 32 | array[1] = -1; 33 | //array[2] = 0; // default is 0 34 | 35 | int res = ArrayExample.sum(array); 36 | 37 | assertEquals(-3, res); 38 | } 39 | 40 | @Test 41 | public void testLarge(){ 42 | 43 | int x = 1_000_000_000; //1 billion 44 | 45 | int[] array = {x, x, x}; 46 | 47 | int res = ArrayExample.sum(array); 48 | 49 | /* 50 | Why the sum of 3 positive values end up becoming negative? 51 | */ 52 | assertTrue(res < 0); 53 | 54 | /* 55 | "int" in Java are signed 32 bits, which means highest value is (2^31)-1 ~= 2 billions. 56 | So end up with so called "overflow" 57 | */ 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les01/arraylist/MyArrayListStringTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les01.arraylist; 2 | 3 | import org.pg4200.les01.MyListString; 4 | import org.pg4200.les01.MyListStringTestTemplate; 5 | 6 | /** 7 | * Created by arcuri82 on 14-Aug-17. 8 | */ 9 | public class MyArrayListStringTest extends MyListStringTestTemplate { 10 | 11 | @Override 12 | protected MyListString getNewInstance() { 13 | return new MyArrayListString(10); 14 | } 15 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les01/arraylist/MyArrayListStringTestFailing.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les01.arraylist; 2 | 3 | import org.pg4200.les01.MyListString; 4 | import org.pg4200.les01.MyListStringTestTemplate; 5 | 6 | /** 7 | * Created by arcuri82 on 14-Aug-17. 8 | */ 9 | public class MyArrayListStringTestFailing extends MyListStringTestTemplate { 10 | 11 | @Override 12 | protected MyListString getNewInstance() { 13 | return new MyArrayListString(4); 14 | } 15 | 16 | /* 17 | When this test suite is run, at least one test fail. 18 | Why? 19 | Because we have one test in which we try to add 5 elements, but here we chose that the backing array 20 | has size 4. 21 | 22 | So, couldn't we just choose a starting size of 1_000_000_000 to solve this problem??? 23 | Of course we could, but then this trivial example would take 1GB of RAM for each single 24 | container class... 25 | */ 26 | } 27 | -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les01/linkedlist/MyDelegateListStringTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les01.linkedlist; 2 | 3 | import org.pg4200.les01.MyListString; 4 | import org.pg4200.les01.MyListStringTestTemplate; 5 | 6 | /** 7 | * Created by arcuri82 on 15-Aug-17. 8 | */ 9 | public class MyDelegateListStringTest extends MyListStringTestTemplate { 10 | 11 | @Override 12 | protected MyListString getNewInstance() { 13 | return new MyDelegateListString(); 14 | } 15 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les01/linkedlist/MyLinkedListStringTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les01.linkedlist; 2 | 3 | import org.pg4200.les01.MyListString; 4 | import org.pg4200.les01.MyListStringTestTemplate; 5 | 6 | /** 7 | * Created by arcuri82 on 15-Aug-17. 8 | */ 9 | public class MyLinkedListStringTest extends MyListStringTestTemplate { 10 | 11 | @Override 12 | protected MyListString getNewInstance() { 13 | return new MyLinkedListString(); 14 | } 15 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les01/linkedlist/MyNaiveLinkedListStringTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les01.linkedlist; 2 | 3 | import org.pg4200.les01.MyListString; 4 | import org.pg4200.les01.MyListStringTestTemplate; 5 | 6 | /** 7 | * Created by arcuri82 on 15-Aug-17. 8 | */ 9 | public class MyNaiveLinkedListStringTest extends MyListStringTestTemplate { 10 | 11 | @Override 12 | protected MyListString getNewInstance() { 13 | return new MyNaiveLinkedListString(); 14 | } 15 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les02/list/MyArrayListTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.list; 2 | 3 | /** 4 | * Created by arcuri82 on 15-Aug-17. 5 | */ 6 | public class MyArrayListTest extends MyListTestTemplate { 7 | 8 | @Override 9 | protected MyList getNewInstance(Class klass) { 10 | return new MyArrayList<>(10); 11 | } 12 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les02/list/MyLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.list; 2 | 3 | /** 4 | * Created by arcuri82 on 15-Aug-17. 5 | */ 6 | public class MyLinkedListTest extends MyListTestTemplate { 7 | 8 | @Override 9 | protected MyList getNewInstance(Class klass) { 10 | return new MyLinkedList<>(); 11 | } 12 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les02/queue/MyQueueArrayTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.queue; 2 | 3 | /** 4 | * Created by arcuri82 on 16-Aug-17. 5 | */ 6 | public class MyQueueArrayTest extends MyQueueTestTemplate{ 7 | 8 | @Override 9 | protected MyQueue getNewInstance(Class klass) { 10 | return new MyQueueArray<>(); 11 | } 12 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les02/queue/MyQueueLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.queue; 2 | 3 | /** 4 | * Created by arcuri82 on 16-Aug-17. 5 | */ 6 | public class MyQueueLinkedListTest extends MyQueueTestTemplate{ 7 | 8 | @Override 9 | protected MyQueue getNewInstance(Class klass) { 10 | return new MyQueueLinkedList<>(); 11 | } 12 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les02/stack/MyStackArrayTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.stack; 2 | 3 | public class MyStackArrayTest extends MyStackTestTemplate{ 4 | 5 | 6 | @Override 7 | protected MyStack getInstance(Class klass) { 8 | return new MyStackArray<>(); 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les02/stack/MyStackDelegateArrayListTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.stack; 2 | 3 | public class MyStackDelegateArrayListTest extends MyStackTestTemplate{ 4 | 5 | @Override 6 | protected MyStack getInstance(Class klass) { 7 | return MyStackDelegate.backedByArrayList(klass); 8 | } 9 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les02/stack/MyStackDelegateLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.stack; 2 | 3 | public class MyStackDelegateLinkedListTest extends MyStackTestTemplate{ 4 | 5 | @Override 6 | protected MyStack getInstance(Class klass) { 7 | return MyStackDelegate.backedByLinkedList(klass); 8 | } 9 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les02/stack/MyStackLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.stack; 2 | 3 | public class MyStackLinkedListTest extends MyStackTestTemplate{ 4 | 5 | @Override 6 | protected MyStack getInstance(Class klass) { 7 | return new MyStackLinkedList<>(); 8 | } 9 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les02/stack/MyStackTestTemplate.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les02.stack; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.assertEquals; 7 | import static org.junit.jupiter.api.Assertions.assertThrows; 8 | import static org.junit.jupiter.api.Assertions.assertTrue; 9 | 10 | 11 | public abstract class MyStackTestTemplate { 12 | 13 | protected abstract MyStack getInstance(Class klass); 14 | 15 | private MyStack stack; 16 | 17 | @BeforeEach 18 | public void init(){ 19 | stack = getInstance(Integer.class); 20 | } 21 | 22 | @Test 23 | public void testEmpty(){ 24 | 25 | assertTrue(stack.isEmpty()); 26 | } 27 | 28 | @Test 29 | public void testFailToPopOnEmpty(){ 30 | 31 | assertThrows(RuntimeException.class, 32 | () -> stack.pop()); 33 | } 34 | 35 | @Test 36 | public void testPush(){ 37 | 38 | assertEquals(0, stack.size()); 39 | 40 | stack.push(5); 41 | 42 | assertEquals(1, stack.size()); 43 | } 44 | 45 | 46 | @Test 47 | public void testPushAndPeek(){ 48 | 49 | int n = 42; 50 | 51 | stack.push(n); 52 | 53 | int res = stack.peek(); 54 | 55 | assertEquals(n, res); 56 | } 57 | 58 | 59 | @Test 60 | public void testPushAndPop(){ 61 | 62 | int n = 42; 63 | 64 | assertEquals(0, stack.size()); 65 | 66 | stack.push(n); 67 | 68 | assertEquals(1, stack.size()); 69 | 70 | int res = stack.pop(); 71 | 72 | assertEquals(n, res); 73 | assertEquals(0, stack.size()); 74 | } 75 | 76 | 77 | @Test 78 | public void testPushAndPopThreeTimes(){ 79 | 80 | stack.push(0); 81 | stack.push(1); 82 | stack.push(2); 83 | 84 | assertEquals(2, stack.pop().intValue()); 85 | assertEquals(1, stack.pop().intValue()); 86 | assertEquals(0, stack.pop().intValue()); 87 | } 88 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les03/sort/BubbleSortTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les03.sort; 2 | 3 | /** 4 | * Created by arcuri82 on 21-Aug-17. 5 | */ 6 | public class BubbleSortTest extends SortTestTemplate{ 7 | 8 | @Override 9 | protected MySort getInstance() { 10 | return new BubbleSort(); 11 | } 12 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les03/sort/InsertionSortTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les03.sort; 2 | 3 | import org.pg4200.les03.sort.InsertionSort; 4 | import org.pg4200.les03.sort.MySort; 5 | import org.pg4200.les03.sort.SortTestTemplate; 6 | 7 | public class InsertionSortTest extends SortTestTemplate { 8 | 9 | @Override 10 | protected MySort getInstance() { 11 | return new InsertionSort(); 12 | } 13 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les04/recursion/RecursiveSumArrayTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les04.recursion; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | /** 8 | * Created by arcuri82 on 07-Jun-19. 9 | */ 10 | public class RecursiveSumArrayTest { 11 | 12 | private static int sumIterative(int[] array){ 13 | 14 | int sum = 0; 15 | 16 | for(int value : array){ 17 | sum += value; 18 | } 19 | 20 | return sum; 21 | } 22 | 23 | 24 | @Test 25 | public void testCompare(){ 26 | 27 | int[] array = {5, 2, 7, -4, 3, 1, 1, 2, 1234, -56, 5, 3, 4}; 28 | int expected = sumIterative(array); 29 | 30 | int single = RecursiveSumArray.sumSingleCall(array); 31 | int two = RecursiveSumArray.sumTwoCalls(array); 32 | 33 | assertEquals(expected, single); 34 | assertEquals(expected, two); 35 | } 36 | 37 | 38 | @Test 39 | public void testLargeArray(){ 40 | 41 | //large array, but containing only 0s, which is default value 42 | int[] array = new int[100_000]; 43 | array[1234] = 234325; 44 | 45 | int expected = sumIterative(array); 46 | 47 | //can't handle with single-call recursion 48 | assertThrows(StackOverflowError.class, () -> 49 | RecursiveSumArray.sumSingleCall(array)) 50 | ; 51 | 52 | /* 53 | as the log2(100_000)=16.6, no problems with two-call recursion in which 54 | input is halved at each call 55 | */ 56 | int two = RecursiveSumArray.sumTwoCalls(array); 57 | 58 | 59 | assertEquals(expected, two); 60 | } 61 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les04/recursion/RecursiveSumTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les04.recursion; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | /** 8 | * Created by arcuri82 on 06-Jun-19. 9 | */ 10 | public class RecursiveSumTest { 11 | 12 | 13 | private static int sumIterative(int n) { 14 | 15 | int sum = 0; 16 | 17 | for (int i = 1; i <= n; i++) { 18 | sum += i; 19 | } 20 | 21 | return sum; 22 | } 23 | 24 | @Test 25 | public void testSum() { 26 | assertEquals(0, RecursiveSumOfN.sumOfAllValues(0)); 27 | assertEquals(1, RecursiveSumOfN.sumOfAllValues(1)); 28 | assertEquals(3, RecursiveSumOfN.sumOfAllValues(2)); 29 | assertEquals(6, RecursiveSumOfN.sumOfAllValues(3)); 30 | assertEquals(10, RecursiveSumOfN.sumOfAllValues(4)); 31 | } 32 | 33 | @Test 34 | public void testSumComparedToIterative() { 35 | 36 | for (int i = 0; i < 100; i++) { 37 | assertEquals(sumIterative(i), RecursiveSumOfN.sumOfAllValues(i)); 38 | } 39 | } 40 | 41 | @Test 42 | public void testSumNoStopping(){ 43 | 44 | /* 45 | The function will not run forever, as it keeps pushing new frames 46 | on the function call stack before popping any of them 47 | */ 48 | assertThrows(StackOverflowError.class, () -> 49 | RecursiveSumOfN.sumOfAllValuesNoStopping(1) 50 | ); 51 | } 52 | 53 | 54 | @Test 55 | public void testStackOverflow() { 56 | 57 | int n = 100_000; 58 | 59 | //no problem in running this iterative function, as only 1 frame on the call stack 60 | sumIterative(n); 61 | 62 | /* 63 | but we do not have enough space on the call stack for a recursive version, 64 | as it tries to push n frames before popping any of them 65 | */ 66 | 67 | assertThrows(StackOverflowError.class, () -> 68 | RecursiveSumOfN.sumOfAllValues(n) 69 | ); 70 | } 71 | 72 | 73 | 74 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les04/sort/MergeSortTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les04.sort; 2 | 3 | import org.pg4200.les03.sort.MySort; 4 | import org.pg4200.les03.sort.SortTestTemplate; 5 | import org.pg4200.les04.sort.MergeSort; 6 | 7 | /** 8 | * Created by arcuri82 on 21-Aug-17. 9 | */ 10 | public class MergeSortTest extends SortTestTemplate { 11 | 12 | @Override 13 | protected MySort getInstance() { 14 | return new MergeSort(); 15 | } 16 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les04/sort/QuickSortTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les04.sort; 2 | 3 | import org.pg4200.les03.sort.MySort; 4 | import org.pg4200.les03.sort.SortTestTemplate; 5 | import org.pg4200.les04.sort.QuickSort; 6 | 7 | /** 8 | * Created by arcuri82 on 21-Aug-17. 9 | */ 10 | public class QuickSortTest extends SortTestTemplate { 11 | 12 | @Override 13 | protected MySort getInstance() { 14 | return new QuickSort(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les05/MyMapBinarySearchArrayTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les05; 2 | 3 | /** 4 | * Created by arcuri82 on 22-Aug-17. 5 | */ 6 | public class MyMapBinarySearchArrayTest extends MyMapTestTemplate{ 7 | 8 | @Override 9 | protected , V> MyMap getInstance() { 10 | return new MyMapBinarySearchArray<>(); 11 | } 12 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les05/MyMapLinearSearchArrayTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les05; 2 | 3 | /** 4 | * Created by arcuri82 on 22-Aug-17. 5 | */ 6 | public class MyMapLinearSearchArrayTest extends MyMapTestTemplate{ 7 | 8 | @Override 9 | protected , V> MyMap getInstance() { 10 | return new MyMapLinearSearchArray<>(); 11 | } 12 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les05/MyMapRedBlackTreeTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les05; 2 | 3 | /** 4 | * Created by arcuri82 on 06-Sep-17. 5 | */ 6 | public class MyMapRedBlackTreeTest extends MyMapTestTemplate { 7 | 8 | protected , V> MyMapTreeBased getTreeInstance() { 9 | return new MyMapRedBlackTree<>(); 10 | } 11 | 12 | @Override 13 | protected , V> MyMap getInstance() { 14 | return getTreeInstance(); 15 | } 16 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les05/SearchTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les05; 2 | 3 | 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.Arrays; 7 | import java.util.List; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | 11 | /** 12 | * Created by arcuri82 on 21-Aug-17. 13 | */ 14 | public class SearchTest { 15 | 16 | 17 | @Test 18 | public void testFind() throws Exception { 19 | 20 | List list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); 21 | 22 | for(int i=0; i MyHashMap getInstance() { 10 | return new MyHashMapWithLists<>(); 11 | } 12 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les09/search/TextSearchBruteForceTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les09.search; 2 | 3 | /** 4 | * Created by arcuri82 on 04-May-18. 5 | */ 6 | public class TextSearchBruteForceTest extends TextSearchTestTemplate{ 7 | 8 | 9 | @Override 10 | protected TextSearch getNewInstance() { 11 | return new TextSearchBruteForce(); 12 | } 13 | 14 | @Override 15 | protected TextSearch getNewInstance(String target) { 16 | return new TextSearchBruteForce(target); 17 | } 18 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les09/search/TextSearchKMPTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les09.search; 2 | 3 | /** 4 | * Created by arcuri82 on 04-May-18. 5 | */ 6 | public class TextSearchKMPTest extends TextSearchTestTemplate{ 7 | 8 | @Override 9 | protected TextSearch getNewInstance() { 10 | return new TextSearchKMP(); 11 | } 12 | 13 | @Override 14 | protected TextSearch getNewInstance(String target) { 15 | return new TextSearchKMP(target); 16 | } 17 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les09/search/TextSearchTestTemplate.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les09.search; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | /** 9 | * Created by arcuri82 on 04-May-18. 10 | */ 11 | public abstract class TextSearchTestTemplate { 12 | 13 | protected abstract TextSearch getNewInstance(); 14 | 15 | protected abstract TextSearch getNewInstance(String target); 16 | 17 | private TextSearch ts; 18 | 19 | @BeforeEach 20 | public void init(){ 21 | ts = getNewInstance(); 22 | } 23 | 24 | @Test 25 | public void testTooLong(){ 26 | int res = ts.findFirst("a", "ab"); 27 | 28 | assertTrue(res < 0); 29 | } 30 | 31 | @Test 32 | public void testSimpleMismatch(){ 33 | 34 | int res = ts.findFirst("a", "b"); 35 | 36 | assertTrue(res < 0); 37 | } 38 | 39 | @Test 40 | public void testSimpleMatch(){ 41 | 42 | int res = ts.findFirst("a", "a"); 43 | 44 | assertEquals(0, res); 45 | } 46 | 47 | @Test 48 | public void testRepetition(){ 49 | 50 | int res = ts.findFirst("caabab", "ab"); 51 | 52 | assertEquals(2, res); 53 | } 54 | 55 | @Test 56 | public void testPartialMatchWithShift(){ 57 | int res = ts.findFirst("aabaabaaaa", "aabaaa"); 58 | 59 | assertEquals(3, res); 60 | } 61 | 62 | @Test 63 | public void testSimplePartialMatchWithShift(){ 64 | int res = ts.findFirst("ababac", "abac"); 65 | 66 | assertEquals(2, res); 67 | } 68 | 69 | @Test 70 | public void testWorstCaseForBruteForceFound(){ 71 | int res = ts.findFirst("aaaaaaaaab", "aaab"); 72 | 73 | assertEquals(6, res); 74 | } 75 | 76 | @Test 77 | public void testWorstCaseForBruteForceFoundNot(){ 78 | int res = ts.findFirst("aaaaaaaaab", "aaac"); 79 | 80 | assertTrue(res < 0); 81 | } 82 | 83 | @Test 84 | public void testDefaultTarget(){ 85 | 86 | TextSearch x = getNewInstance("aacaa"); 87 | 88 | int res = x.findFirst("aabraacadabraacaadabra"); 89 | 90 | assertEquals(12, res); 91 | } 92 | 93 | @Test 94 | public void testSequenceOfCalls(){ 95 | 96 | assertEquals(0, ts.findFirst("aba", "a")); 97 | assertEquals(2, ts.findFirst("ababac", "abac")); 98 | assertEquals(1, ts.findFirst("cat", "a")); 99 | assertEquals(7, ts.findFirst("aaaaabcabacaaab", "abac")); 100 | } 101 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les10/knapsack/BruteForceForKnapsackTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les10.knapsack; 2 | 3 | 4 | import org.junit.jupiter.api.Disabled; 5 | import org.junit.jupiter.api.Test; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | /** 10 | * Created by arcuri82 on 09-Oct-17. 11 | */ 12 | public class BruteForceForKnapsackTest { 13 | 14 | private void test(KnapsackInstanceWithSolution p, double optimum){ 15 | 16 | boolean[] res = BruteForceForKnapsack.solve(p.getProblem()); 17 | 18 | double fitness = p.getProblem().evaluate(res); 19 | 20 | assertEquals(optimum, fitness, 0.001); 21 | 22 | double best = p.getBestFitness(); 23 | 24 | assertEquals(best, fitness, 0.001); 25 | } 26 | 27 | @Test 28 | public void testP05(){ 29 | 30 | test(KnapsackInstanceWithSolution.problemP05(), 51d); 31 | } 32 | 33 | @Test 34 | public void testP15(){ 35 | 36 | test(KnapsackInstanceWithSolution.problemP15(), 1458d); 37 | } 38 | 39 | @Test 40 | public void testP24(){ 41 | 42 | test(KnapsackInstanceWithSolution.problemP24(), 13549094d); 43 | } 44 | 45 | @Disabled 46 | @Test 47 | public void testP100(){ 48 | 49 | test(KnapsackInstanceWithSolution.problemP100(), 67165d); 50 | 51 | /* 52 | On a 2016 machine, P24 takes 1-2 seconds. 53 | How long will P100 take? 54 | Let's make some high level calculations... 55 | 56 | LOWER BOUND of 1 seconds per 2^24 57 | 58 | 2^100 / 2^24 seconds -> 2^76 seconds 59 | 60 | 2^76 / (60 * 60 * 24 * 365) years, ie 61 | 62 | 2,300,000,000,000,000 years 63 | 64 | ie you need to wait AT LEAST 2 Quadrillion years 65 | */ 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les10/knapsack/RandomForKnapsackTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les10.knapsack; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import static org.junit.jupiter.api.Assertions.*; 6 | 7 | class RandomForKnapsackTest { 8 | 9 | private void test(int iterations, KnapsackInstanceWithSolution p, double optimum){ 10 | 11 | boolean[] res = RandomForKnapsack.solve(iterations, p.getProblem()); 12 | 13 | double fitness = p.getProblem().evaluate(res); 14 | 15 | assertEquals(optimum, fitness, 0.001); 16 | 17 | double best = p.getBestFitness(); 18 | 19 | assertEquals(best, fitness, 0.001); 20 | } 21 | 22 | /* 23 | Note: here we put high enough number of iterations (compared to the size 24 | of search space) that it is more likely to be hit on the head by a meteor 25 | while reading this text than these tests will fail. 26 | */ 27 | 28 | @Test 29 | public void testP05(){ 30 | 31 | test(1000, KnapsackInstanceWithSolution.problemP05(), 51d); 32 | } 33 | 34 | @Test 35 | public void testP15(){ 36 | 37 | test(1_000_000, KnapsackInstanceWithSolution.problemP15(), 1458d); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les11/GeneticAlgorithmForKnapsackCheck.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les11; 2 | 3 | import org.pg4200.les10.knapsack.GreedyForKnapsack; 4 | import org.pg4200.les10.knapsack.KnapsackInstanceWithSolution; 5 | import org.pg4200.les11.ea.GeneticAlgorithmForKnapsack; 6 | 7 | /** 8 | * Created by arcuri82 on 25-Oct-17. 9 | */ 10 | public class GeneticAlgorithmForKnapsackCheck { 11 | 12 | private static void check(KnapsackInstanceWithSolution p, int iterations) { 13 | 14 | boolean[] greedy = GreedyForKnapsack.solveByBestRatioFirst(p.getProblem()); 15 | 16 | boolean[] ga = GeneticAlgorithmForKnapsack.solve(iterations, p.getProblem()); 17 | 18 | double fg = p.getProblem().evaluate(greedy); 19 | double og = p.getProblem().evaluate(ga); 20 | 21 | System.out.print("N=" + p.getProblem().getSize()); 22 | System.out.print(" , Greedy=" + fg); 23 | System.out.print(" , GA=" + og); 24 | 25 | String label; 26 | if (og == p.getBestFitness()) { 27 | label = "Optimal"; 28 | } else if (og > fg) { 29 | label = "Improved"; 30 | } else { 31 | label = "Worse"; 32 | } 33 | 34 | System.out.println(" -> " + label); 35 | } 36 | 37 | public static void main(String[] args) { 38 | 39 | int iterations = 100_000; 40 | 41 | check(KnapsackInstanceWithSolution.problemP05(), iterations); 42 | check(KnapsackInstanceWithSolution.problemP15(), iterations); 43 | check(KnapsackInstanceWithSolution.problemP24(), iterations); 44 | check(KnapsackInstanceWithSolution.problemP100(), iterations); 45 | } 46 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les11/OnePlusOneEAForKnapsackCheck.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les11; 2 | 3 | import org.pg4200.les10.knapsack.GreedyForKnapsack; 4 | import org.pg4200.les10.knapsack.KnapsackInstanceWithSolution; 5 | import org.pg4200.les11.ea.OnePlusOneEAForKnapsack; 6 | 7 | public class OnePlusOneEAForKnapsackCheck { 8 | 9 | 10 | private static void check(KnapsackInstanceWithSolution p, int iterations) { 11 | 12 | boolean[] greedy = GreedyForKnapsack.solveByBestRatioFirst(p.getProblem()); 13 | 14 | boolean[] opoea = OnePlusOneEAForKnapsack.solve(iterations, p.getProblem()); 15 | 16 | double fg = p.getProblem().evaluate(greedy); 17 | double og = p.getProblem().evaluate(opoea); 18 | 19 | System.out.print("N=" + p.getProblem().getSize()); 20 | System.out.print(" , Greedy=" + fg); 21 | System.out.print(" , (1+1)EA=" + og); 22 | 23 | String label; 24 | if (og == p.getBestFitness()) { 25 | label = "Optimal"; 26 | } else if (og > fg) { 27 | label = "Improved"; 28 | } else { 29 | label = "Worse"; 30 | } 31 | 32 | System.out.println(" -> " + label); 33 | } 34 | 35 | public static void main(String[] args) { 36 | 37 | int iterations = 100_000; 38 | 39 | check(KnapsackInstanceWithSolution.problemP05(), iterations); 40 | check(KnapsackInstanceWithSolution.problemP15(), iterations); 41 | check(KnapsackInstanceWithSolution.problemP24(), iterations); 42 | check(KnapsackInstanceWithSolution.problemP100(), iterations); 43 | } 44 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les12/DnaCompressorTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les12; 2 | 3 | 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.nio.charset.Charset; 7 | import java.nio.charset.StandardCharsets; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | 12 | 13 | /** 14 | * Created by arcuri82 on 30-Oct-17. 15 | */ 16 | public class DnaCompressorTest { 17 | 18 | 19 | /** 20 | * Having a compression "c" and a decompression "d", 21 | * then, whatever the input "x" is, the following should 22 | * always be true 23 | * 24 | * x = d(c(x)) 25 | * 26 | * ie, if we compress and then decompress, we should get 27 | * back the original input 28 | */ 29 | private void checkPreserveInformation(String dna ){ 30 | 31 | byte[] compressed = DnaCompressor.compress(dna); 32 | 33 | String decompressed = DnaCompressor.decompress(compressed); 34 | 35 | assertEquals(dna, decompressed); 36 | } 37 | 38 | @Test 39 | public void testPreserveInformation(){ 40 | checkPreserveInformation("AAAGTACCTGAGT"); 41 | } 42 | 43 | @Test 44 | public void testDecreaseSize(){ 45 | 46 | String dna = "AAAGTACCTGAGTAAAGTACCTGAGTAAAGTACCTGAGTTTTGCTGCTGCTGCTGCTGCTGCTGCTGCTGCTTTTTTT"; 47 | checkPreserveInformation(dna); 48 | 49 | int nonCompressedSize = dna.getBytes(StandardCharsets.UTF_8).length; 50 | 51 | byte[] compressed = DnaCompressor.compress(dna); 52 | 53 | assertTrue(compressed.length < nonCompressedSize); 54 | 55 | double ratio = (double) compressed.length / (double) nonCompressedSize; 56 | /* 57 | we get a good compression, which gets better for longer text, 58 | as the overhead of storing the trie has less impact 59 | */ 60 | 61 | assertTrue(ratio < 0.33); 62 | 63 | //can't beat 1/4 ratio 64 | assertTrue(ratio >= 0.25); 65 | } 66 | 67 | @Test 68 | public void testIncreaseSize(){ 69 | 70 | /* 71 | Compressing a single char make the data larger, as we still 72 | have to store at least 1 byte for the data plus 32 bits for the size "1" 73 | */ 74 | 75 | String dna = "A"; 76 | checkPreserveInformation(dna); 77 | 78 | int nonCompressedSize = dna.getBytes(StandardCharsets.UTF_8).length; 79 | 80 | byte[] compressed = DnaCompressor.compress(dna); 81 | 82 | assertTrue(compressed.length > nonCompressedSize); 83 | } 84 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les12/HuffmanTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les12; 2 | 3 | 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.nio.charset.Charset; 7 | import java.util.Scanner; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | 12 | 13 | /** 14 | * Created by arcuri82 on 01-Nov-17. 15 | */ 16 | public class HuffmanTest extends TextCompressionTestTemplate{ 17 | 18 | protected double checkCompressAndDecompress(String text, String charset){ 19 | return checkCompressAndDecompress(new Huffman(), text, charset); 20 | } 21 | 22 | 23 | @Test 24 | public void testSingleChar(){ 25 | double ratio = checkCompressAndDecompress("a","utf-16"); 26 | assertTrue(ratio > 1); 27 | } 28 | 29 | @Test 30 | public void testSingleWord(){ 31 | double ratio = checkCompressAndDecompress("foo","utf-16"); 32 | assertTrue(ratio > 1); 33 | } 34 | 35 | @Test 36 | public void testSentence(){ 37 | double ratio = checkCompressAndDecompress( 38 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ", 39 | "utf-16"); 40 | 41 | assertTrue(ratio > 0.4); 42 | assertTrue(ratio < 0.5); 43 | } 44 | 45 | @Test 46 | public void testBook(){ 47 | 48 | 49 | String text = getOdysseyText(); 50 | 51 | /* 52 | Note: as the text in that file does not have special characters, 53 | its utf-16 representation is twice as long as the utf-8 one. 54 | */ 55 | 56 | double ratio16 = checkCompressAndDecompress(text, "utf-16"); 57 | 58 | assertTrue(ratio16 > 0.25); 59 | assertTrue(ratio16 < 0.3); 60 | 61 | double ratio8 = checkCompressAndDecompress(text, "utf-8"); 62 | assertTrue(ratio8 < 0.6); 63 | } 64 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les12/TextCompressionTestTemplate.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les12; 2 | 3 | import java.nio.charset.Charset; 4 | import java.util.Scanner; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | /** 9 | * Created by arcuri82 on 03-May-18. 10 | */ 11 | public abstract class TextCompressionTestTemplate { 12 | 13 | private String odysseyText; 14 | 15 | protected String getOdysseyText(){ 16 | /* 17 | * The actual book on disk is in UTF-8. 18 | * We must read it in UTF-8. 19 | * However, once loaded, the JVM does convert it to UTF-16 20 | * to be able to store it in a String object. 21 | * 22 | * Note: the following code does read all the lines from the given file. 23 | */ 24 | 25 | if(odysseyText == null){ 26 | odysseyText = new Scanner(TextCompressionTestTemplate.class 27 | .getResourceAsStream("/compression/odyssey.mb.txt"), "UTF-8") 28 | .useDelimiter("\\A") 29 | .next(); 30 | } 31 | 32 | return odysseyText; 33 | } 34 | 35 | /** 36 | * Compress and decompress the text, checking that this works correctly, 37 | * and also printing stats. 38 | * Note: the string "text" is in UTF-16, but, when we consider its size 39 | * in bytes, we can choose different encodings. 40 | */ 41 | protected double checkCompressAndDecompress(TextCompression cmp, String text, String charset){ 42 | 43 | byte[] compressed = cmp.compress(text); 44 | 45 | String res = cmp.decompress(compressed); 46 | 47 | assertEquals(text, res); 48 | 49 | System.out.println(cmp.getStatistics(text)); 50 | 51 | int originalLength = text.getBytes(Charset.forName(charset)).length; 52 | 53 | double ratio = (double) compressed.length / (double) originalLength; 54 | 55 | System.out.println("Original size for "+charset+": " + originalLength); 56 | System.out.println("Compressed size: " + compressed.length); 57 | System.out.println("Ratio for "+charset+": " + ratio); 58 | 59 | return ratio; 60 | } 61 | } -------------------------------------------------------------------------------- /lessons/src/test/java/org/pg4200/les12/lzw/LZWTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.les12.lzw; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.pg4200.les12.Huffman; 5 | import org.pg4200.les12.TextCompressionTestTemplate; 6 | import org.pg4200.les12.lzw.LZW; 7 | 8 | import static org.junit.jupiter.api.Assertions.*; 9 | 10 | /** 11 | * Created by arcuri82 on 03-May-18. 12 | */ 13 | public class LZWTest extends TextCompressionTestTemplate { 14 | 15 | protected double checkCompressAndDecompress(String text, String charset){ 16 | return checkCompressAndDecompress(new LZW(), text, charset); 17 | } 18 | 19 | 20 | @Test 21 | public void testSingleChar(){ 22 | double ratio = checkCompressAndDecompress("a","utf-16"); 23 | 24 | //here only 3 bytes (24 bits) were written, 12 bits for "a", and 12 bits for EOF 25 | assertTrue(ratio < 1); 26 | } 27 | 28 | @Test 29 | public void testSingleWord(){ 30 | double ratio = checkCompressAndDecompress("foo","utf-16"); 31 | assertTrue(ratio < 1); 32 | } 33 | 34 | @Test 35 | public void testSentence(){ 36 | double ratio = checkCompressAndDecompress( 37 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ", 38 | "utf-16"); 39 | 40 | //here seems worse than Huffman 41 | assertTrue(ratio > 0.5); 42 | assertTrue(ratio < 0.6); 43 | } 44 | 45 | @Test 46 | public void testBook(){ 47 | 48 | String text = getOdysseyText(); 49 | 50 | double ratio16 = checkCompressAndDecompress(text, "utf-16"); 51 | 52 | assertTrue(ratio16 > 0.20); 53 | assertTrue(ratio16 < 0.25); 54 | 55 | double ratio8 = checkCompressAndDecompress(text, "utf-8"); 56 | assertTrue(ratio8 < 0.5); 57 | 58 | double huffman = checkCompressAndDecompress(new Huffman(), text, "utf-8"); 59 | assertTrue(ratio8 < huffman); 60 | } 61 | 62 | @Test 63 | public void testInvalid(){ 64 | 65 | String text = "私はアンドレアです"; 66 | 67 | assertThrows(IllegalArgumentException.class, () -> checkCompressAndDecompress(text, "utf-8")); 68 | } 69 | } -------------------------------------------------------------------------------- /solutions/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 4.0.0 5 | pg4200-solutions 6 | jar 7 | 8 | 9 | org.pg4200 10 | pg4200-root 11 | 0.0.1-SNAPSHOT 12 | 13 | 14 | 15 | 16 | 17 | org.pg4200 18 | pg4200-lessons 19 | ${project.version} 20 | 21 | 22 | org.pg4200 23 | pg4200-lessons 24 | ${project.version} 25 | tests 26 | test-jar 27 | test 28 | 29 | 30 | 31 | org.pg4200 32 | pg4200-exercises 33 | ${project.version} 34 | 35 | 36 | org.pg4200 37 | pg4200-exercises 38 | ${project.version} 39 | tests 40 | test-jar 41 | test 42 | 43 | 44 | 45 | 46 | org.junit.jupiter 47 | junit-jupiter-api 48 | 49 | 50 | org.junit.jupiter 51 | junit-jupiter-engine 52 | 53 | 54 | org.junit.jupiter 55 | junit-jupiter-params 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol01/ArrayUtilsImp.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol01; 2 | 3 | import org.pg4200.ex01.ArrayUtils; 4 | 5 | public class ArrayUtilsImp implements ArrayUtils { 6 | 7 | @Override 8 | public int min(int[] array) throws IllegalArgumentException { 9 | checkArray(array); 10 | 11 | int min = array[0]; 12 | 13 | for(int i=1; i max){ 31 | max = val; 32 | } 33 | } 34 | return max; 35 | } 36 | 37 | @Override 38 | public double mean(int[] array) throws IllegalArgumentException { 39 | checkArray(array); 40 | 41 | double sum = 0; 42 | 43 | for(int i=0; i= size){ 19 | //some input validation 20 | return null; 21 | } 22 | return data[index]; 23 | } 24 | 25 | public void add(Integer value) { 26 | data[size] = value; 27 | size++; 28 | } 29 | 30 | public int size() { 31 | return size; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol02/MyArrayListResizable.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol02; 2 | 3 | import org.pg4200.les02.list.MyArrayList; 4 | 5 | /** 6 | * Created by arcuri82 on 15-Aug-17. 7 | */ 8 | public class MyArrayListResizable extends MyArrayList { 9 | 10 | public MyArrayListResizable(){ 11 | super(); 12 | } 13 | 14 | public MyArrayListResizable(int capacity){ 15 | super(capacity); 16 | } 17 | 18 | @Override 19 | public void add(int index, T value) { 20 | 21 | if(size == data.length){ 22 | /* 23 | Array is full, need to create new, bigger one. 24 | Note: for simplicity I am not adding code to check 25 | if new size does not overflow. 26 | If you want to see how to do it properly, look at the source 27 | code of java.lang.ArrayList 28 | */ 29 | 30 | Object[] bigger = new Object[data.length * 2]; 31 | for(int i=0; i { 8 | 9 | @Override 10 | public int compare(GameUser a, GameUser b) { 11 | 12 | int pointDiff = a.getPoints() - b.getPoints(); 13 | 14 | if(pointDiff == 0){ 15 | return a.getUserId().compareTo(b.getUserId()); 16 | } 17 | 18 | return pointDiff; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol03/OptimizedBubbleSort.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol03; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * Created by arcuri82 on 21-Aug-17. 7 | */ 8 | public class OptimizedBubbleSort { 9 | 10 | 11 | public int sort(T[] array, Comparator comparator, boolean optimized) { 12 | 13 | if (array == null) { 14 | return 0; 15 | } 16 | 17 | int counter = 0; 18 | 19 | //make sure we enter into first loop of the "while" 20 | boolean swapped = true; 21 | int lastSwap = array.length-1; 22 | 23 | while (swapped) { 24 | 25 | /* 26 | if there is not going to be any swapping, then the 27 | array is sorted, and we do not need to recheck 28 | */ 29 | 30 | swapped = false; 31 | 32 | int limit = array.length - 1; 33 | 34 | if(optimized){ 35 | limit = lastSwap; 36 | } 37 | 38 | for (int i = 0; i < limit; i++) { 39 | int j = i + 1; 40 | /* 41 | if current element is greater than next, 42 | then swap them. 43 | Like a bubble, the highest value will fly up. 44 | */ 45 | 46 | counter++; 47 | 48 | if (comparator.compare(array[i], array[j]) > 0) { 49 | T tmp = array[i]; 50 | array[i] = array[j]; 51 | array[j] = tmp; 52 | 53 | swapped = true; 54 | lastSwap = i; 55 | } 56 | } 57 | } 58 | 59 | return counter; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol03/SortCheckerImp.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol03; 2 | 3 | import org.pg4200.ex03.SortChecker; 4 | 5 | public class SortCheckerImp implements SortChecker { 6 | 7 | @Override 8 | public > boolean isSortedCopy(T[] original, T[] sorted) { 9 | 10 | if(original == null && sorted == null){ 11 | return true; 12 | } 13 | 14 | if(original == null || sorted == null){ 15 | return false; 16 | } 17 | 18 | if(original.length != sorted.length){ 19 | return false; 20 | } 21 | 22 | //null elements? 23 | for(int i=0; i 0){ 32 | return false; 33 | } 34 | } 35 | 36 | //is it a permutation? 37 | for(int i=0; i= 0) || 26 | (max == b && max - a - c >= 0) || 27 | (max == c && max - a - b >= 0)) { 28 | return NOT_A_TRIANGLE; 29 | } 30 | 31 | if(a==b || a==c || b==c){ 32 | return ISOSCELES; 33 | } else { 34 | return SCALENE; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol05/BinaryTreeLeftMaxDelete.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol05; 2 | 3 | import org.pg4200.les05.MyMapBinarySearchTree; 4 | 5 | /** 6 | * Created by arcuri82 on 30-Apr-18. 7 | */ 8 | public class BinaryTreeLeftMaxDelete, V> extends MyMapBinarySearchTree { 9 | 10 | @Override 11 | protected TreeNode delete(K key, TreeNode subtreeRoot) { 12 | 13 | if (subtreeRoot == null) { 14 | return null; 15 | } 16 | 17 | int cmp = key.compareTo(subtreeRoot.key); 18 | 19 | if (cmp < 0) { 20 | subtreeRoot.left = delete(key, subtreeRoot.left); 21 | return subtreeRoot; 22 | } 23 | 24 | if (cmp > 0) { 25 | subtreeRoot.right = delete(key, subtreeRoot.right); 26 | return subtreeRoot; 27 | } 28 | 29 | /* 30 | Here, we are done with the recursion. 31 | How to delete this node will depend on 32 | how many children it has 33 | */ 34 | 35 | assert cmp == 0; 36 | 37 | size--; 38 | 39 | if (subtreeRoot.left == null) { 40 | return subtreeRoot.right; 41 | } 42 | 43 | if (subtreeRoot.right == null) { 44 | return subtreeRoot.left; 45 | } 46 | 47 | /* 48 | Both children are present 49 | */ 50 | 51 | TreeNode tmp = subtreeRoot; 52 | subtreeRoot = max(tmp.left); 53 | subtreeRoot.left = deleteMax(tmp.left); 54 | subtreeRoot.right = tmp.right; 55 | 56 | return subtreeRoot; 57 | } 58 | 59 | private TreeNode max(TreeNode subtreeRoot) { 60 | if (subtreeRoot.right == null) { 61 | return subtreeRoot; 62 | } 63 | return max(subtreeRoot.right); 64 | } 65 | 66 | private TreeNode deleteMax(TreeNode subtreeRoot) { 67 | 68 | if (subtreeRoot.right == null) { 69 | return subtreeRoot.left; 70 | } 71 | 72 | subtreeRoot.right = deleteMax(subtreeRoot.right); 73 | 74 | return subtreeRoot; 75 | } 76 | 77 | 78 | } 79 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol06/ImmutableAuthorImp.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol06; 2 | 3 | import org.pg4200.ex06.ImmutableAuthor; 4 | 5 | /** 6 | * Created by arcuri82 on 02-May-18. 7 | */ 8 | public class ImmutableAuthorImp implements ImmutableAuthor { 9 | 10 | private final String name; 11 | 12 | private final String surname; 13 | 14 | public ImmutableAuthorImp() { 15 | this(null, null); 16 | } 17 | 18 | public ImmutableAuthorImp(String name, String surname) { 19 | this.name = name; 20 | this.surname = surname; 21 | } 22 | 23 | @Override 24 | public ImmutableAuthor withName(String name) { 25 | return new ImmutableAuthorImp(name, this.surname); 26 | } 27 | 28 | @Override 29 | public ImmutableAuthor withSurname(String surname) { 30 | return new ImmutableAuthorImp(this.name, surname); 31 | } 32 | 33 | @Override 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | @Override 39 | public String getSurname() { 40 | return surname; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol06/ImmutableBookImp.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol06; 2 | 3 | import org.pg4200.ex06.ImmutableAuthor; 4 | import org.pg4200.ex06.ImmutableBook; 5 | 6 | import java.util.Arrays; 7 | import java.util.Collections; 8 | import java.util.List; 9 | 10 | /** 11 | * Created by arcuri82 on 02-May-18. 12 | */ 13 | public class ImmutableBookImp implements ImmutableBook { 14 | 15 | private final String title; 16 | 17 | private final int year; 18 | 19 | private final List authors; 20 | 21 | /** 22 | * Default constructor, with no input parameters. 23 | * As the fields are final, we still need to initialize them 24 | * with some values, otherwise it will not compile. 25 | */ 26 | public ImmutableBookImp() { 27 | this(null, -1, null); 28 | } 29 | 30 | public ImmutableBookImp(String title, int year, List authors) { 31 | this.title = title; 32 | this.year = year; 33 | this.authors = authors == null ? null : Collections.unmodifiableList(authors); 34 | } 35 | 36 | @Override 37 | public ImmutableBook withTitle(String title) { 38 | return new ImmutableBookImp(title, this.year, this.authors); 39 | } 40 | 41 | @Override 42 | public ImmutableBook withYear(int year) { 43 | return new ImmutableBookImp(this.title, year, this.authors); 44 | } 45 | 46 | @Override 47 | public ImmutableBook withAuthors(List authors) { 48 | return new ImmutableBookImp(this.title, this.year, authors); 49 | } 50 | 51 | @Override 52 | public ImmutableBook withAuthors(ImmutableAuthor... authors) { 53 | return withAuthors(Arrays.asList(authors)); 54 | } 55 | 56 | 57 | @Override 58 | public String getTitle() { 59 | return title; 60 | } 61 | 62 | @Override 63 | public int getYear() { 64 | return year; 65 | } 66 | 67 | @Override 68 | public List getAuthors() { 69 | return authors; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol07/AnotherStreamList.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol07; 2 | 3 | import org.pg4200.ex07.AnotherStream; 4 | import org.pg4200.les07.iterator.MyIterableLinkedList; 5 | 6 | /** 7 | * Created by arcuri82 on 04-Oct-17. 8 | */ 9 | public class AnotherStreamList extends MyIterableLinkedList { 10 | 11 | public AnotherStream stream() { 12 | return AnotherStreamSupport.createStream(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol07/ComputationExampleStream.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol07; 2 | 3 | import org.pg4200.ex06.Book; 4 | import org.pg4200.ex07.ComputationExample; 5 | 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | 9 | public class ComputationExampleStream implements ComputationExample { 10 | 11 | @Override 12 | public List compute(List books) { 13 | 14 | return books.stream() 15 | .filter(b -> b.getYear() >= 2010 && b.getYear() <= 2015) 16 | .filter(b -> b.getAuthors().size() >= 2) 17 | .flatMap(b -> b.getAuthors().stream()) 18 | .filter(a -> a.getName() != null && a.getSurname() != null) 19 | .map(a -> a.getName() + " " + a.getSurname()) 20 | .distinct() 21 | .collect(Collectors.toList()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol07/ExtendedListImpl.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol07; 2 | 3 | import org.pg4200.ex07.ExtendedList; 4 | import org.pg4200.les02.list.MyArrayList; 5 | import org.pg4200.les06.set.MySet; 6 | import org.pg4200.les06.set.MySetHashMap; 7 | 8 | import java.util.function.Consumer; 9 | import java.util.function.Function; 10 | import java.util.function.Predicate; 11 | 12 | /** 13 | * Created by arcuri82 on 07-Jun-19. 14 | */ 15 | public class ExtendedListImpl extends MyArrayList implements ExtendedList { 16 | 17 | 18 | @Override 19 | public ExtendedList filter(Predicate predicate) { 20 | 21 | ExtendedList other = new ExtendedListImpl<>(); 22 | 23 | for(int i=0; i ExtendedList map(Function mapper) { 35 | 36 | ExtendedList other = new ExtendedListImpl<>(); 37 | 38 | for(int i=0; i ExtendedList flatMap(Function> mapper) { 48 | 49 | ExtendedList other = new ExtendedListImpl<>(); 50 | 51 | for(int i=0; i list = mapper.apply(value); 54 | for(int j=0; j action) { 64 | 65 | for(int i=0; i toSet() { 73 | 74 | MySet set = new MySetHashMap<>(); 75 | 76 | for(int i=0; i extends UndirectedGraph { 11 | 12 | 13 | public List> findAllPaths(V start, V end) { 14 | 15 | if (!graph.containsKey(start) && !graph.containsKey(end)) { 16 | return Collections.emptyList(); 17 | } 18 | 19 | if (start.equals(end)) { 20 | //we do not consider cycles 21 | throw new IllegalArgumentException(); 22 | } 23 | 24 | Deque stack = new ArrayDeque<>(); 25 | 26 | List> paths = new ArrayList<>(); 27 | 28 | dfs(paths, stack, start, end); 29 | 30 | return paths; 31 | } 32 | 33 | private void dfs(List> paths, Deque stack, V current, V end) { 34 | 35 | stack.push(current); 36 | 37 | if (isPathTo(stack, end)) { 38 | List path = new ArrayList<>(stack); 39 | Collections.reverse(path); 40 | paths.add(path); 41 | return; 42 | } 43 | 44 | for (V connected : getAdjacents(current)) { 45 | if (stack.contains(connected)) { 46 | continue; 47 | } 48 | 49 | dfs(paths, stack, connected, end); 50 | //backtrack 51 | stack.pop(); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol09/PatternExamplesImp.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol09; 2 | 3 | import org.pg4200.ex09.PatternExamples; 4 | 5 | /** 6 | * Created by arcuri82 on 07-May-18. 7 | */ 8 | public class PatternExamplesImp implements PatternExamples { 9 | 10 | 11 | @Override 12 | public String dnaRegex() { 13 | return "[CGAT]+"; 14 | } 15 | 16 | @Override 17 | public String telephoneNumberRegex() { 18 | return "((\\+|00)[0-9]{2})?[0-9]{8}"; 19 | } 20 | 21 | @Override 22 | public String emailRegex() { 23 | return "[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})"; 24 | } 25 | 26 | @Override 27 | public String isItAJoke() { 28 | return "[iI][sS] +[tT][hH][iI][sS] +[aA][nN] +[oO][uU][tT] +[oO][fF] +[sS][eE][aA][sS][oO][nN] +[aA][pP][rR][iI][lL] +[fF][oO][oO][lL][sS] +[jJ][oO][kK][eE]\\?"; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol09/TextSearchKMPCached.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol09; 2 | 3 | import org.pg4200.les09.search.TextSearchKMP; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * Created by arcuri82 on 07-May-18. 10 | */ 11 | public class TextSearchKMPCached extends TextSearchKMP { 12 | 13 | private final Map cache = new HashMap<>(); 14 | 15 | public TextSearchKMPCached() { 16 | super(); 17 | } 18 | 19 | public TextSearchKMPCached(String token) { 20 | super(token); 21 | } 22 | 23 | @Override 24 | public int findFirst(String text, String token) { 25 | 26 | if(defaultTarget != null && defaultTarget.equals(token)){ 27 | return findFirst(text); 28 | } 29 | 30 | TextSearchKMP kmp = cache.get(token); 31 | 32 | if(kmp == null){ 33 | kmp = new TextSearchKMP(token); 34 | cache.put(token, kmp); 35 | } 36 | 37 | return kmp.findFirst(text); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol10/RandomForKnapsackOptimized.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol10; 2 | 3 | import org.pg4200.les10.knapsack.KnapsackProblem; 4 | 5 | import java.util.Objects; 6 | import java.util.Random; 7 | 8 | public class RandomForKnapsackOptimized { 9 | 10 | 11 | public static boolean[] solve(int maxIterations, KnapsackProblem problem){ 12 | 13 | if(maxIterations < 1){ 14 | throw new IllegalArgumentException("Invalid number of iterations"); 15 | } 16 | Objects.requireNonNull(problem); 17 | 18 | Random random = new Random(); 19 | 20 | final int n = problem.getSize(); 21 | 22 | boolean[] solution = new boolean[n]; 23 | boolean[] buffer = new boolean[n]; 24 | 25 | sample(solution, random); 26 | 27 | for(int i=1; i problem.evaluate(solution)){ 31 | boolean[] tmp = solution; 32 | solution = buffer; 33 | buffer = tmp; 34 | } 35 | } 36 | 37 | return solution; 38 | } 39 | 40 | private static void sample(boolean[] buffer, Random random){ 41 | for(int i=0; i 0; i--) 71 | { 72 | index = random.nextInt(i + 1); 73 | temp = array[index]; 74 | array[index] = array[i]; 75 | array[i] = temp; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /solutions/src/main/java/org/pg4200/sol12/GradeCompressorImp.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol12; 2 | 3 | import org.pg4200.ex12.GradeCompressor; 4 | import org.pg4200.les12.BitReader; 5 | import org.pg4200.les12.BitWriter; 6 | 7 | public class GradeCompressorImp implements GradeCompressor { 8 | 9 | @Override 10 | public byte[] compress(String idsAndGrades) { 11 | 12 | BitWriter writer = new BitWriter(); 13 | String id = ""; 14 | 15 | for(int i=0; i= '0' && c <= '9'){ 18 | id += c; 19 | } else if( c >= 'A' && c <= 'F'){ 20 | writer.write(Integer.parseInt(id), 9); 21 | writer.write(c - 'A', 3); 22 | id = ""; 23 | } 24 | } 25 | 26 | return writer.extract(); 27 | } 28 | 29 | @Override 30 | public String decompress(byte[] data) { 31 | 32 | BitReader reader = new BitReader(data); 33 | String result = ""; 34 | int entries = (data.length * 8) / 12; 35 | 36 | for(int i=0; i MyList getNewInstance(Class klass) { 13 | return new MyArrayListResizable<>(1); 14 | } 15 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol02/MyBidirectionalLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol02; 2 | 3 | import org.pg4200.les02.list.MyList; 4 | import org.pg4200.les02.list.MyListTestTemplate; 5 | 6 | 7 | /** 8 | * Created by arcuri82 on 05-Jun-19. 9 | */ 10 | class MyBidirectionalLinkedListTest extends MyListTestTemplate { 11 | 12 | @Override 13 | protected MyList getNewInstance(Class klass) { 14 | return new MyBidirectionalLinkedList<>(); 15 | } 16 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol02/MyMiddleBidirectionalLinkedListTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol02; 2 | 3 | import org.pg4200.les02.list.MyList; 4 | import org.pg4200.les02.list.MyListTestTemplate; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | class MyMiddleBidirectionalLinkedListTest extends MyListTestTemplate { 9 | 10 | @Override 11 | protected MyList getNewInstance(Class klass) { 12 | return new MyMiddleBidirectionalLinkedList<>(); 13 | } 14 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol02/MyRingArrayQueueTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol02; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.pg4200.les02.queue.MyQueue; 5 | import org.pg4200.les02.queue.MyQueueTestTemplate; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertThrows; 8 | 9 | 10 | /** 11 | * Created by arcuri82 on 16-Aug-17. 12 | */ 13 | public class MyRingArrayQueueTest extends MyQueueTestTemplate{ 14 | 15 | @Override 16 | protected MyQueue getNewInstance(Class klass) { 17 | return new MyRingArrayQueue<>(); 18 | } 19 | 20 | @Test 21 | public void testFailToPeekOnEmpty(){ 22 | 23 | assertThrows(RuntimeException.class, 24 | () -> queue.peek()); 25 | } 26 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol03/SortCheckerImpTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol03; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.pg4200.ex03.SortChecker; 5 | import org.pg4200.ex03.SortCheckerTestTemplate; 6 | 7 | import java.util.Arrays; 8 | 9 | public class SortCheckerImpTest extends SortCheckerTestTemplate { 10 | 11 | @Override 12 | protected SortChecker getNewInstance() { 13 | return new SortCheckerImp(); 14 | } 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol04/FibonacciImplMemoizedTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol04; 2 | 3 | import org.pg4200.ex04.Fibonacci; 4 | import org.pg4200.ex04.FibonacciTestTemplate; 5 | 6 | /** 7 | * Created by arcuri82 on 07-Jun-19. 8 | */ 9 | class FibonacciImplMemoizedTest extends FibonacciTestTemplate { 10 | 11 | @Override 12 | protected Fibonacci getInstance() { 13 | return new FibonacciImplMemoized(); 14 | } 15 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol04/FibonacciImplTestNot.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol04; 2 | 3 | import org.pg4200.ex04.Fibonacci; 4 | import org.pg4200.ex04.FibonacciTestTemplate; 5 | 6 | 7 | /** 8 | * Created by arcuri82 on 07-Jun-19. 9 | */ 10 | public class FibonacciImplTestNot extends FibonacciTestTemplate { 11 | 12 | @Override 13 | protected Fibonacci getInstance() { 14 | return new FibonacciImpl(); 15 | } 16 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol04/MixedSortTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol04; 2 | 3 | import org.pg4200.les03.sort.MySort; 4 | import org.pg4200.les03.sort.SortTestTemplate; 5 | 6 | /** 7 | * Created by arcuri82 on 21-Aug-17. 8 | */ 9 | public class MixedSortTest extends SortTestTemplate { 10 | 11 | @Override 12 | protected MySort getInstance() { 13 | return new MixedSort(4); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol05/BinaryTreeLeftMaxDeleteTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol05; 2 | 3 | import org.pg4200.les05.*; 4 | 5 | /** 6 | * Created by arcuri82 on 30-Apr-18. 7 | */ 8 | public class BinaryTreeLeftMaxDeleteTest extends MyMapBinarySearchTreeTest { 9 | 10 | @Override 11 | protected , V> MyMapTreeBased getTreeInstance() { 12 | return new BinaryTreeLeftMaxDelete<>(); 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol05/TernaryTreeMapTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol05; 2 | 3 | import org.junit.jupiter.api.BeforeEach; 4 | import org.junit.jupiter.api.Test; 5 | import org.pg4200.les05.MyMap; 6 | import org.pg4200.les05.MyMapTestTemplate; 7 | import org.pg4200.les05.MyMapTreeBased; 8 | 9 | import static org.junit.jupiter.api.Assertions.assertEquals; 10 | 11 | 12 | /** 13 | * Created by arcuri82 on 24-Aug-17. 14 | */ 15 | public class TernaryTreeMapTest extends MyMapTestTemplate { 16 | 17 | 18 | protected , V> MyMapTreeBased getTreeInstance() { 19 | return new TernaryTreeMap<>(); 20 | } 21 | 22 | @Override 23 | protected , V> MyMap getInstance() { 24 | return getTreeInstance(); 25 | } 26 | 27 | /* 28 | Note: this field does NOT override the one in the super class. 29 | */ 30 | private MyMapTreeBased map; 31 | 32 | 33 | /* 34 | Make sure this method does not have the same name as superclass, otherwise 35 | it will be overwritten, and all the tests in superclass will fail, as their 36 | "map" field would not be initialized 37 | */ 38 | @BeforeEach 39 | public void initMyTreeBasedMapTestTemplateTest() { 40 | map = getTreeInstance(); 41 | } 42 | 43 | 44 | @Test 45 | public void testDepthZero() { 46 | 47 | assertEquals(0, map.getMaxTreeDepth()); 48 | } 49 | 50 | @Test 51 | public void testBalanced2() { 52 | 53 | map.put(0, "a"); 54 | assertEquals(1, map.getMaxTreeDepth()); 55 | 56 | map.put(5, "b"); 57 | assertEquals(1, map.getMaxTreeDepth()); 58 | } 59 | 60 | 61 | @Test 62 | public void testWorstCaseFor3() { 63 | 64 | map.put(0, "b"); 65 | assertEquals(1, map.getMaxTreeDepth()); 66 | 67 | map.put(-5, "a"); 68 | assertEquals(2, map.getMaxTreeDepth()); 69 | 70 | map.put(-10, "c"); 71 | assertEquals(3, map.getMaxTreeDepth()); 72 | } 73 | 74 | 75 | @Test 76 | public void testBalanced8() { 77 | 78 | map.put(5, "a"); 79 | map.put(2, "a"); 80 | map.put(3, "a"); 81 | map.put(10, "a"); 82 | map.put(6, "a"); 83 | map.put(7, "a"); 84 | map.put(11, "a"); 85 | map.put(12, "a"); 86 | 87 | assertEquals(2, map.getMaxTreeDepth()); 88 | } 89 | 90 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol06/HashMapLinearProbeTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol06; 2 | 3 | import org.pg4200.les06.hash.MyHashMap; 4 | import org.pg4200.les06.hash.MyHashMapTestTemplate; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | /** 9 | * Created by arcuri82 on 02-May-18. 10 | */ 11 | public class HashMapLinearProbeTest extends MyHashMapTestTemplate { 12 | 13 | @Override 14 | protected MyHashMap getInstance() { 15 | return new HashMapLinearProbe<>(); 16 | } 17 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol06/ImmutableBookAndAuthorTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol06; 2 | 3 | import org.pg4200.ex06.ImmutableAuthor; 4 | import org.pg4200.ex06.ImmutableBook; 5 | import org.pg4200.ex06.ImmutableBookAndAuthorTestTemplate; 6 | 7 | /** 8 | * Created by arcuri82 on 02-May-18. 9 | */ 10 | public class ImmutableBookAndAuthorTest extends ImmutableBookAndAuthorTestTemplate { 11 | 12 | @Override 13 | protected ImmutableBook getNewEmptyInstanceOfBook() { 14 | return new ImmutableBookImp(); 15 | } 16 | 17 | @Override 18 | protected ImmutableAuthor getNewEmptyInstanceOfAuthor() { 19 | return new ImmutableAuthorImp(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol07/ComputationExampleStreamTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol07; 2 | 3 | import org.pg4200.ex07.ComputationExample; 4 | import org.pg4200.ex07.ComputationExampleTestTemplate; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | public class ComputationExampleStreamTest extends ComputationExampleTestTemplate { 9 | 10 | @Override 11 | protected ComputationExample getNewInstance() { 12 | return new ComputationExampleStream(); 13 | } 14 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol07/ExtendedListImplTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol07; 2 | 3 | import org.pg4200.ex07.ExtendedList; 4 | import org.pg4200.ex07.ExtendedListTestTemplate; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | /** 9 | * Created by arcuri82 on 07-Jun-19. 10 | */ 11 | public class ExtendedListImplTest extends ExtendedListTestTemplate { 12 | 13 | @Override 14 | protected ExtendedList getInstance(Class klass) { 15 | return new ExtendedListImpl<>(); 16 | } 17 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol08/AllPathsGraphTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol08; 2 | 3 | 4 | import org.junit.jupiter.api.Test; 5 | 6 | import java.util.List; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | 12 | /** 13 | * Created by arcuri82 on 03-Nov-17. 14 | */ 15 | public class AllPathsGraphTest { 16 | 17 | @Test 18 | public void test(){ 19 | 20 | AllPathsGraph graph = new AllPathsGraph<>(); 21 | graph.addEdge("0","X"); 22 | graph.addEdge("X","1"); 23 | graph.addEdge("X","Y"); 24 | graph.addEdge("1","2"); 25 | graph.addEdge("2","Y"); 26 | graph.addEdge("1","3"); 27 | graph.addEdge("3","4"); 28 | graph.addEdge("3","5"); 29 | graph.addEdge("4","5"); 30 | 31 | 32 | List> paths = graph.findAllPaths("X","5"); 33 | assertEquals(4, paths.size()); 34 | assertTrue(paths.stream().anyMatch(p -> p.size() == 4)); 35 | assertTrue(paths.stream().anyMatch(p -> p.size() == 5)); 36 | assertTrue(paths.stream().anyMatch(p -> p.size() == 6)); 37 | assertTrue(paths.stream().anyMatch(p -> p.size() == 7)); 38 | } 39 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol09/PatternExamplesImpTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol09; 2 | 3 | import org.pg4200.ex09.PatternExamples; 4 | import org.pg4200.ex09.PatternExamplesTestTemplate; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | /** 9 | * Created by arcuri82 on 07-May-18. 10 | */ 11 | public class PatternExamplesImpTest extends PatternExamplesTestTemplate { 12 | 13 | @Override 14 | protected PatternExamples getNewInstance() { 15 | return new PatternExamplesImp(); 16 | } 17 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol09/TextSearchKMPCachedTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol09; 2 | 3 | import org.pg4200.les09.search.TextSearch; 4 | import org.pg4200.les09.search.TextSearchTestTemplate; 5 | 6 | import static org.junit.jupiter.api.Assertions.*; 7 | 8 | /** 9 | * Created by arcuri82 on 07-May-18. 10 | */ 11 | public class TextSearchKMPCachedTest extends TextSearchTestTemplate { 12 | 13 | @Override 14 | protected TextSearch getNewInstance() { 15 | return new TextSearchKMPCached(); 16 | } 17 | 18 | @Override 19 | protected TextSearch getNewInstance(String token) { 20 | return new TextSearchKMPCached(token); 21 | } 22 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol10/RandomForKnapsackOptimizedTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol10; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.pg4200.les10.knapsack.KnapsackInstanceWithSolution; 5 | import org.pg4200.les10.knapsack.RandomForKnapsack; 6 | 7 | import static org.junit.jupiter.api.Assertions.assertEquals; 8 | 9 | class RandomForKnapsackOptimizedTest { 10 | 11 | private void test(int iterations, KnapsackInstanceWithSolution p, double optimum){ 12 | 13 | boolean[] res = RandomForKnapsackOptimized.solve(iterations, p.getProblem()); 14 | 15 | double fitness = p.getProblem().evaluate(res); 16 | 17 | assertEquals(optimum, fitness, 0.001); 18 | 19 | double best = p.getBestFitness(); 20 | 21 | assertEquals(best, fitness, 0.001); 22 | } 23 | 24 | /* 25 | Note: here we put high enough number of iterations (compared to the size 26 | of search space) that it is more likely to be hit on the head by a meteor 27 | while reading this text than these tests will fail. 28 | */ 29 | 30 | @Test 31 | public void testP05(){ 32 | 33 | test(1000, KnapsackInstanceWithSolution.problemP05(), 51d); 34 | } 35 | 36 | @Test 37 | public void testP15(){ 38 | 39 | test(1_000_000, KnapsackInstanceWithSolution.problemP15(), 1458d); 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol10/SteepestAscentHCforQueensTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol10; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.pg4200.les10.queens.QueensProblem; 5 | 6 | import java.util.Arrays; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | 12 | /** 13 | * Created by arcuri82 on 16-Oct-17. 14 | */ 15 | public class SteepestAscentHCforQueensTest { 16 | 17 | private void testSteepestAscent(int n){ 18 | 19 | int[] positions = SteepestAscentHCforQueens.solve(n); 20 | 21 | int fitness = QueensProblem.evaluate(positions); 22 | 23 | assertEquals(0, fitness); 24 | assertTrue(QueensProblem.isCorrect(positions)); 25 | 26 | System.out.println(Arrays.toString(positions)); 27 | } 28 | 29 | @Test 30 | public void testSteepestAscent_8x8(){ 31 | 32 | testSteepestAscent(8); 33 | } 34 | 35 | @Test 36 | public void testSteepestAscent_16x16(){ 37 | 38 | testSteepestAscent(16); 39 | } 40 | 41 | @Test 42 | public void testSteepestAscent_20x20(){ 43 | 44 | testSteepestAscent(20); 45 | } 46 | 47 | @Test 48 | public void testSteepestAscent_100x100(){ 49 | 50 | /* 51 | Even on a 100x100 board, HC is still fast 52 | */ 53 | testSteepestAscent(100); 54 | } 55 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol11/OnePlusOneEAForQueensTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol11; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.pg4200.les10.queens.QueensProblem; 5 | 6 | import java.util.Arrays; 7 | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; 9 | import static org.junit.jupiter.api.Assertions.assertTrue; 10 | 11 | 12 | /** 13 | * Created by arcuri82 on 25-Oct-17. 14 | */ 15 | public class OnePlusOneEAForQueensTest { 16 | 17 | private void testOnePlusOneEA(int n){ 18 | 19 | int[] positions = OnePlusOneEAForQueens.solve(n); 20 | 21 | int fitness = QueensProblem.evaluate(positions); 22 | 23 | assertEquals(0, fitness); 24 | assertTrue(QueensProblem.isCorrect(positions)); 25 | 26 | System.out.println(Arrays.toString(positions)); 27 | } 28 | 29 | @Test 30 | public void testOnePlusOneEA_8x8(){ 31 | 32 | testOnePlusOneEA(8); 33 | } 34 | 35 | @Test 36 | public void testOnePlusOneEA_16x16(){ 37 | 38 | testOnePlusOneEA(16); 39 | } 40 | 41 | @Test 42 | public void testOnePlusOneEA_20x20(){ 43 | 44 | testOnePlusOneEA(20); 45 | } 46 | 47 | @Test 48 | public void testOnePlusOneEA_100x100(){ 49 | 50 | testOnePlusOneEA(100); 51 | } 52 | 53 | 54 | } -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol12/GradeCompressorTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol12; 2 | 3 | import org.pg4200.ex12.GradeCompressor; 4 | import org.pg4200.ex12.GradeCompressorTestTemplate; 5 | 6 | public class GradeCompressorTest extends GradeCompressorTestTemplate { 7 | 8 | @Override 9 | protected GradeCompressor getNewInstance() { 10 | return new GradeCompressorImp(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /solutions/src/test/java/org/pg4200/sol12/HuffmanIsoTest.java: -------------------------------------------------------------------------------- 1 | package org.pg4200.sol12; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.pg4200.les12.Huffman; 5 | import org.pg4200.les12.HuffmanTest; 6 | 7 | import java.nio.charset.Charset; 8 | import java.util.Scanner; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertEquals; 11 | import static org.junit.jupiter.api.Assertions.assertTrue; 12 | 13 | 14 | /** 15 | * Created by arcuri82 on 06-Nov-17. 16 | */ 17 | public class HuffmanIsoTest { 18 | 19 | private double checkCompressAndDecompress(Huffman huffman , String text, String charset){ 20 | 21 | byte[] compressed = huffman.compress(text); 22 | 23 | String res = huffman.decompress(compressed); 24 | 25 | assertEquals(text, res); 26 | 27 | System.out.println(huffman.getStatistics(text)); 28 | 29 | int originalLength = text.getBytes(Charset.forName(charset)).length; 30 | 31 | double ratio = (double) compressed.length / (double) originalLength; 32 | 33 | System.out.println("Original size for "+charset+": " + originalLength); 34 | System.out.println("Compressed size: " + compressed.length); 35 | System.out.println("Ratio for "+charset+": " + ratio); 36 | 37 | return ratio; 38 | } 39 | 40 | 41 | @Test 42 | public void testCompareOnShortNorwegianSentence(){ 43 | 44 | String text = "Jeg ønsker å få en god karakter i denne eksamenen"; 45 | Huffman h16 = new Huffman(); 46 | Huffman hiso = new HuffmanIso(); 47 | 48 | double r16 = checkCompressAndDecompress(h16, text, "utf-8"); 49 | double riso = checkCompressAndDecompress(hiso, text, "utf-8"); 50 | 51 | assertTrue(riso < r16); 52 | assertTrue(r16 > 1); 53 | assertTrue(riso < 1); 54 | } 55 | 56 | 57 | @Test 58 | public void testCompareOnBook(){ 59 | 60 | String text = new Scanner(HuffmanTest.class.getResourceAsStream("/compression/odyssey.mb.txt"), "UTF-8").useDelimiter("\\A").next(); 61 | 62 | Huffman h16 = new Huffman(); 63 | Huffman hiso = new HuffmanIso(); 64 | 65 | double r16 = checkCompressAndDecompress(h16, text, "utf-8"); 66 | double riso = checkCompressAndDecompress(hiso, text, "utf-8"); 67 | 68 | assertTrue(riso < r16); 69 | 70 | double diff = r16 - riso; 71 | assertTrue(diff < 0.001); 72 | } 73 | } --------------------------------------------------------------------------------