├── .courseignore ├── images ├── network1.tex ├── network2.tex ├── network9.tex ├── network3.tex ├── network4.tex ├── network5.tex ├── network6.tex ├── network7.tex ├── network14.tex ├── sum_of_two_digits_logo.tex ├── opposite_values_logo.tex ├── big_o.png ├── gold_1.png ├── gold_2.png ├── gold_3.png ├── merge.png ├── pair01.png ├── big_o_1.png ├── big_o_2.png ├── greedy_1.png ├── greedy_2.png ├── greedy_3.png ├── greedy_4.png ├── greedy_5.png ├── merge_2.png ├── merge_3.png ├── merge_4.png ├── network1.png ├── network2.png ├── network3.png ├── network4.png ├── network5.png ├── network6.png ├── network7.png ├── network8.png ├── network9.png ├── pair01_2.png ├── pair01_3.png ├── pair01_4.png ├── pair01_5.png ├── subsets.png ├── big_o_dark.png ├── gold_1_dark.png ├── gold_2_dark.png ├── gold_3_dark.png ├── merge_dark.png ├── network10.png ├── network12.png ├── network13.png ├── network14.png ├── network15.png ├── network16.png ├── pair01_dark.png ├── partitions.png ├── big_o_1_dark.png ├── big_o_2_dark.png ├── calculator_1.png ├── calculator_2.png ├── calculator_3.png ├── calculator_4.png ├── derangements.png ├── greedy_1_dark.png ├── greedy_2_dark.png ├── greedy_3_dark.png ├── greedy_4_dark.png ├── greedy_5_dark.png ├── guess_number.png ├── inversions_1.png ├── inversions_2.png ├── merge_2_dark.png ├── merge_3_dark.png ├── merge_4_dark.png ├── network1_dark.png ├── network2_dark.png ├── network3_dark.png ├── network4_dark.png ├── network5_dark.png ├── network6_dark.png ├── network7_dark.png ├── network8_dark.png ├── network9_dark.png ├── pair01_2_dark.png ├── pair01_3_dark.png ├── pair01_4_dark.png ├── pair01_5_dark.png ├── palindromic_1.png ├── palindromic_2.png ├── palindromic_3.png ├── subsets_dark.png ├── subsets_logo.png ├── binary_strings_1.png ├── binary_strings_2.png ├── count_ones_logo.png ├── edit_distance_1.png ├── edit_distance_2.png ├── edit_distance_3.png ├── edit_distance_4.png ├── edit_distance_5.png ├── edit_distance_6.png ├── inversions_logo.png ├── network10_dark.png ├── network12_dark.png ├── network13_dark.png ├── network14_dark.png ├── network15_dark.png ├── network16.tex ├── network16_dark.png ├── palindromic_logo.png ├── partitions_dark.png ├── partitions_logo.png ├── big_o_1.tex ├── calculator_1_dark.png ├── calculator_2_dark.png ├── calculator_3_dark.png ├── calculator_4_dark.png ├── derangements_dark.png ├── derangements_logo.png ├── edit_distance_logo.png ├── guess_number_dark.png ├── inversions_1_dark.png ├── inversions_2_dark.png ├── median_two_lists_1.png ├── median_two_lists_2.png ├── median_two_lists_3.png ├── money_change_dp_1.png ├── money_change_dp_2.png ├── money_change_dp_3.png ├── money_change_dp_4.png ├── money_change_logo.png ├── palindromic_1_dark.png ├── palindromic_2_dark.png ├── palindromic_3_dark.png ├── range_sum_queries.png ├── subsets_logo_dark.png ├── sum_of_two_digits.png ├── binary_strings_1_dark.png ├── binary_strings_2_dark.png ├── binary_strings_logo.png ├── count_ones_logo_dark.png ├── covering_segments_1.png ├── edit_distance_1_dark.png ├── edit_distance_2_dark.png ├── edit_distance_3_dark.png ├── edit_distance_4_dark.png ├── edit_distance_5_dark.png ├── edit_distance_6_dark.png ├── inversions_logo_dark.png ├── max_pairwise_product_8.tex ├── median_two_lists_logo.png ├── money_change_dp_logo.png ├── money_change_greedy_1.png ├── money_change_greedy_2.png ├── opposite_values_logo.png ├── palindromic_logo_dark.png ├── partitions_logo_dark.png ├── big_o_2.tex ├── collecting_signatures_1.png ├── collecting_signatures_2.png ├── collecting_signatures_3.png ├── derangements_logo_dark.png ├── distinct_summands_logo.png ├── edit_distance_logo_dark.png ├── max_pairwise_product_1.png ├── max_pairwise_product_2.png ├── max_pairwise_product_3.png ├── max_pairwise_product_4.png ├── max_pairwise_product_5.png ├── max_pairwise_product_6.png ├── max_pairwise_product_7.png ├── max_pairwise_product_7.tex ├── max_pairwise_product_8.png ├── max_pairwise_product_9.png ├── median_two_lists_1_dark.png ├── median_two_lists_2_dark.png ├── median_two_lists_3_dark.png ├── money_change_dp_1_dark.png ├── money_change_dp_2_dark.png ├── money_change_dp_3_dark.png ├── money_change_dp_4_dark.png ├── money_change_logo_dark.png ├── range_sum_queries_dark.png ├── searching_sorted_data1.png ├── searching_sorted_data2.png ├── searching_sorted_data3.png ├── sum_of_two_digits_dark.png ├── sum_of_two_digits_logo.png ├── binary_strings_logo_dark.png ├── collecting_signatures_logo.png ├── count_blocks_of_ones_logo.png ├── count_ones_logo.tex ├── covering_segments_1_dark.png ├── max_pairwise_product_logo.png ├── median_two_lists_logo_dark.png ├── money_change_dp_logo_dark.png ├── money_change_greedy_1_dark.png ├── money_change_greedy_2_dark.png ├── opposite_values_logo_dark.png ├── points_and_segments_logo.png ├── unchangeable_amount_logo.png ├── collecting_signatures_1_dark.png ├── collecting_signatures_2_dark.png ├── collecting_signatures_3_dark.png ├── count_ones_with_updates_logo.png ├── distinct_summands_logo_dark.png ├── max_pairwise_product_1_dark.png ├── max_pairwise_product_2_dark.png ├── max_pairwise_product_3_dark.png ├── max_pairwise_product_4_dark.png ├── max_pairwise_product_5_dark.png ├── max_pairwise_product_6_dark.png ├── max_pairwise_product_7_dark.png ├── max_pairwise_product_8_dark.png ├── max_pairwise_product_9_dark.png ├── network13.tex ├── searching_sorted_data1_dark.png ├── searching_sorted_data2_dark.png ├── searching_sorted_data3_dark.png ├── sum_of_two_digits_logo_dark.png ├── collecting_signatures_logo_dark.png ├── count_blocks_of_ones_logo_dark.png ├── max_pairwise_product_6.tex ├── max_pairwise_product_logo_dark.png ├── points_and_segments_logo_dark.png ├── unchangeable_amount_logo_dark.png ├── count_ones_with_updates_logo_dark.png ├── sum_of_two_digits.tex ├── network15.tex ├── count_blocks_of_ones_with_updates_logo.png ├── money_change_dp_logo.tex ├── network12.tex ├── count_blocks_of_ones_with_updates_logo_dark.png ├── money_change_dp_1.tex ├── money_change_logo.tex ├── pair01_2.tex ├── count_ones_with_updates_logo.tex ├── money_change_greedy_2.tex ├── edit_distance_logo.tex ├── distinct_summands_logo.tex ├── pair01_5.tex ├── palindromic_1.tex ├── palindromic_logo.tex ├── count_blocks_of_ones_logo.tex ├── pair01_3.tex ├── pair01_4.tex ├── range_sum_queries.tex ├── calculator_1.tex ├── network10.tex ├── count_blocks_of_ones_with_updates_logo.tex ├── pair01.tex ├── searching_sorted_data1.tex ├── median_two_lists_1.tex ├── inversions_logo.tex ├── gold_1.tex ├── binary_strings_1.tex ├── binary_strings_2.tex ├── binary_strings_logo.tex ├── subsets_logo.tex ├── max_pairwise_product_logo.tex ├── collecting_signatures_logo.tex ├── max_pairwise_product_2.tex ├── partitions_logo.tex ├── edit_distance_3.tex ├── median_two_lists_logo.tex ├── greedy_5.tex ├── greedy_3.tex ├── main.tex ├── main_dark.tex ├── points_and_segments_logo.tex ├── greedy_4.tex ├── calculator_4.tex ├── greedy_1.tex ├── max_pairwise_product_1.tex ├── money_change_dp_2.tex ├── collecting_signatures_2.tex ├── money_change_dp_4.tex ├── greedy_2.tex ├── derangements_logo.tex ├── subsets.tex ├── gold_3.tex ├── profile.tex ├── searching_sorted_data2.tex ├── searching_sorted_data3.tex ├── unchangeable_amount_logo.tex ├── partitions.tex ├── derangements.tex ├── money_change_greedy_1.tex ├── max_pairwise_product_3.tex ├── max_pairwise_product_9.tex ├── calculator_2.tex ├── big_o.tex ├── inversions_1.tex ├── median_two_lists_3.tex ├── median_two_lists_2.tex ├── max_pairwise_product_4.tex ├── palindromic_2.tex ├── gold_2.tex ├── money_change_dp_3.tex ├── merge_2.tex ├── max_pairwise_product_5.tex ├── palindromic_3.tex ├── inversions_2.tex ├── cover.tex ├── collecting_signatures_1.tex ├── covering_segments_1.tex ├── edit_distance_4.tex └── edit_distance_5.tex ├── Warmup ├── lesson-remote-info.yaml ├── Welcome! │ ├── task-remote-info.yaml │ ├── src │ │ └── Main.kt │ └── task-info.yaml ├── Sum of Two Digits │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ ├── test │ │ ├── Tests.kt │ │ └── HiddenTests.kt │ ├── task-info.yaml │ ├── task_template.md │ └── solution.md ├── Maximum Pairwise Product │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ ├── task-info.yaml │ └── test │ │ └── Tests.kt ├── Estimating the Running Time │ ├── task-remote-info.yaml │ └── task-info.yaml ├── Maximum Pairwise Product — Fixing the Time Limit Issue │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ ├── task-info.yaml │ └── test │ │ └── Tests.kt ├── Maximum Pairwise Product — Fixing the Integer Overflow Issue │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ ├── task-info.yaml │ ├── task_template.md │ └── test │ │ └── Tests.kt └── lesson-info.yaml ├── Brute Force ├── lesson-remote-info.yaml ├── Introduction │ ├── task-remote-info.yaml │ ├── src │ │ └── Main.kt │ ├── task-info.yaml │ └── task_template.md ├── Generate Partitions │ ├── task-remote-info.yaml │ └── src │ │ ├── Partition.kt │ │ └── Task.kt ├── Generate Subsets │ ├── task-remote-info.yaml │ ├── task-info.yaml │ ├── test │ │ └── Tests.kt │ ├── src │ │ └── Task.kt │ ├── task_template.md │ └── solution.md ├── Generate Binary Strings │ ├── task-remote-info.yaml │ ├── test │ │ ├── Tests.kt │ │ └── HiddenTests.kt │ ├── task-info.yaml │ ├── src │ │ └── Task.kt │ └── task_template.md ├── Generate Derangements │ ├── task-remote-info.yaml │ ├── src │ │ ├── Derangement.kt │ │ └── Task.kt │ ├── solution.md │ ├── task-info.yaml │ ├── test │ │ └── Tests.kt │ └── task_template.md └── lesson-info.yaml ├── Divide and Conquer ├── lesson-remote-info.yaml ├── Count in Range │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ ├── test │ │ └── Tests.kt │ ├── task-info.yaml │ ├── solution.md │ └── task_template.md ├── Lower Bound │ ├── task-remote-info.yaml │ ├── task-info.yaml │ └── src │ │ └── Main.kt ├── Sorting Data │ ├── task-remote-info.yaml │ ├── src │ │ └── Main.kt │ └── task-info.yaml ├── Count Inversions │ ├── task-remote-info.yaml │ ├── test │ │ └── Tests.kt │ └── task-info.yaml ├── Guess a Number │ ├── task-remote-info.yaml │ ├── task-info.yaml │ └── src │ │ └── Main.kt ├── Opposite Values │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ ├── test │ │ └── Tests.kt │ ├── task-info.yaml │ └── task_template.md ├── Points and Segments │ ├── task-remote-info.yaml │ ├── task-info.yaml │ ├── solution.md │ ├── src │ │ └── Task.kt │ └── test │ │ └── Tests.kt ├── Searching Sorted Data │ ├── task-remote-info.yaml │ ├── task-info.yaml │ └── src │ │ └── Main.kt ├── Median in Two Sorted Lists │ ├── task-remote-info.yaml │ ├── test │ │ └── Tests.kt │ ├── src │ │ └── Task.kt │ └── task-info.yaml └── lesson-info.yaml ├── Dynamic Programming ├── lesson-remote-info.yaml ├── Edit Distance │ ├── task-remote-info.yaml │ ├── test │ │ └── Tests.kt │ └── task-info.yaml ├── The Main Idea │ ├── task-remote-info.yaml │ ├── src │ │ └── Main.kt │ └── task-info.yaml ├── Minimum Sum Path │ ├── task-remote-info.yaml │ ├── test │ │ └── Tests.kt │ ├── src │ │ └── Task.kt │ ├── task-info.yaml │ └── solution.md ├── Maximum Amount of Gold │ ├── task-remote-info.yaml │ ├── test │ │ └── Tests.kt │ ├── src │ │ └── Task.kt │ ├── task-info.yaml │ └── task_template.md ├── Money Change Again │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ ├── test │ │ └── Tests.kt │ ├── task_template.md │ └── task-info.yaml ├── Primitive Calculator │ ├── task-remote-info.yaml │ ├── test │ │ └── Tests.kt │ ├── task-info.yaml │ └── src │ │ └── Task.kt ├── Longest Palindromic Subsequence │ ├── task-remote-info.yaml │ ├── test │ │ └── Tests.kt │ └── task-info.yaml └── lesson-info.yaml ├── Greedy Algorithms ├── lesson-remote-info.yaml ├── Money Change │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ ├── test │ │ ├── Tests.kt │ │ └── HiddenTests.kt │ ├── task-info.yaml │ └── task_template.md ├── The Main Idea │ ├── task-remote-info.yaml │ ├── src │ │ └── Main.kt │ └── task-info.yaml ├── Distinct Summands │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ ├── task-info.yaml │ ├── task_template.md │ └── solution.md ├── Collecting Signatures │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ └── task-info.yaml ├── Minimum Unchangeable Amount │ ├── task-remote-info.yaml │ ├── src │ │ └── Task.kt │ ├── task-info.yaml │ ├── test │ │ └── Tests.kt │ └── task_template.md └── lesson-info.yaml ├── Queries and Incremental Updates ├── lesson-remote-info.yaml ├── Count Ones │ ├── task-remote-info.yaml │ ├── solution.md │ ├── src │ │ └── Task.kt │ ├── test │ │ └── Tests.kt │ ├── task-info.yaml │ └── task_template.md ├── Count Blocks of Ones │ ├── task-remote-info.yaml │ ├── solution.md │ ├── src │ │ └── Task.kt │ ├── test │ │ └── Tests.kt │ ├── task-info.yaml │ └── task_template.md ├── Range Sum Queries │ ├── task-remote-info.yaml │ ├── src │ │ └── RangeSum.kt │ ├── test │ │ └── Tests.kt │ ├── task-info.yaml │ └── solution.md ├── Count Ones with Updates │ ├── task-remote-info.yaml │ ├── solution.md │ ├── src │ │ └── CountOnesWithUpdates.kt │ ├── test │ │ └── Tests.kt │ └── task-info.yaml ├── Count Blocks of Ones with Updates │ ├── task-remote-info.yaml │ ├── solution.md │ ├── test │ │ └── Tests.kt │ └── task-info.yaml └── lesson-info.yaml ├── course-remote-info.yaml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .idea └── inspectionProfiles │ └── profiles_settings.xml ├── .gitignore ├── .github └── workflows │ ├── gradle-test.yml │ └── gradle-build.yml ├── util ├── common.css └── src │ └── TestUtil.kt └── settings.gradle.kts /.courseignore: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /images/network1.tex: -------------------------------------------------------------------------------- 1 | \network{~} -------------------------------------------------------------------------------- /images/network2.tex: -------------------------------------------------------------------------------- 1 | \network{1} -------------------------------------------------------------------------------- /images/network9.tex: -------------------------------------------------------------------------------- 1 | \spnetwork{~} -------------------------------------------------------------------------------- /images/network3.tex: -------------------------------------------------------------------------------- 1 | \network{1,1,1} -------------------------------------------------------------------------------- /images/network4.tex: -------------------------------------------------------------------------------- 1 | \network{1,1,1,2} -------------------------------------------------------------------------------- /images/network5.tex: -------------------------------------------------------------------------------- 1 | \network{1,1,1,2,3} -------------------------------------------------------------------------------- /images/network6.tex: -------------------------------------------------------------------------------- 1 | \network{1,1,1,2,3,1} -------------------------------------------------------------------------------- /images/network7.tex: -------------------------------------------------------------------------------- 1 | \network{1,1,1,2,3,1,6} -------------------------------------------------------------------------------- /Warmup/lesson-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 973085617 2 | -------------------------------------------------------------------------------- /images/network14.tex: -------------------------------------------------------------------------------- 1 | \spnetwork{0,4,5,6,8,12,12} -------------------------------------------------------------------------------- /Brute Force/lesson-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1780749552 2 | -------------------------------------------------------------------------------- /Warmup/Welcome!/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 197119725 2 | -------------------------------------------------------------------------------- /Divide and Conquer/lesson-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 552481657 2 | -------------------------------------------------------------------------------- /Dynamic Programming/lesson-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 389193117 2 | -------------------------------------------------------------------------------- /Greedy Algorithms/lesson-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 656042150 2 | -------------------------------------------------------------------------------- /Brute Force/Introduction/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 862087786 2 | -------------------------------------------------------------------------------- /Warmup/Sum of Two Digits/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1010771345 2 | -------------------------------------------------------------------------------- /Brute Force/Generate Partitions/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1970304342 2 | -------------------------------------------------------------------------------- /Brute Force/Generate Subsets/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1440838842 2 | -------------------------------------------------------------------------------- /Divide and Conquer/Count in Range/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 534251275 2 | -------------------------------------------------------------------------------- /Divide and Conquer/Lower Bound/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1427180237 2 | -------------------------------------------------------------------------------- /Divide and Conquer/Sorting Data/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 381048668 2 | -------------------------------------------------------------------------------- /Dynamic Programming/Edit Distance/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 34663278 2 | -------------------------------------------------------------------------------- /Dynamic Programming/The Main Idea/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 859662097 2 | -------------------------------------------------------------------------------- /Greedy Algorithms/Money Change/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 37914342 2 | -------------------------------------------------------------------------------- /Greedy Algorithms/The Main Idea/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 149639705 2 | -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 826232520 2 | -------------------------------------------------------------------------------- /Brute Force/Generate Binary Strings/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1835947196 2 | -------------------------------------------------------------------------------- /Brute Force/Generate Derangements/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1099617220 2 | -------------------------------------------------------------------------------- /Divide and Conquer/Count Inversions/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 336840196 2 | -------------------------------------------------------------------------------- /Divide and Conquer/Guess a Number/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 2108161667 2 | -------------------------------------------------------------------------------- /Divide and Conquer/Opposite Values/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1565106581 2 | -------------------------------------------------------------------------------- /Dynamic Programming/Minimum Sum Path/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1515002585 2 | -------------------------------------------------------------------------------- /Greedy Algorithms/Distinct Summands/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1674596384 2 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/lesson-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1832859663 2 | -------------------------------------------------------------------------------- /Warmup/Estimating the Running Time/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1895973463 2 | -------------------------------------------------------------------------------- /Warmup/Welcome!/src/Main.kt: -------------------------------------------------------------------------------- 1 | fun main() { 2 | println("Welcome!") 3 | } 4 | -------------------------------------------------------------------------------- /Divide and Conquer/Points and Segments/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1269592101 2 | -------------------------------------------------------------------------------- /Divide and Conquer/Searching Sorted Data/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 599589161 2 | -------------------------------------------------------------------------------- /Dynamic Programming/Maximum Amount of Gold/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 622579765 2 | -------------------------------------------------------------------------------- /Dynamic Programming/Money Change Again/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1376612358 2 | -------------------------------------------------------------------------------- /Dynamic Programming/Primitive Calculator/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 786831611 2 | -------------------------------------------------------------------------------- /Greedy Algorithms/Collecting Signatures/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 830057945 2 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Ones/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 931177794 2 | -------------------------------------------------------------------------------- /images/sum_of_two_digits_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | \node[hc] at (0,0) {\Huge $2+3=5$}; -------------------------------------------------------------------------------- /Divide and Conquer/Median in Two Sorted Lists/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 71731226 2 | -------------------------------------------------------------------------------- /Greedy Algorithms/Minimum Unchangeable Amount/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 846518508 2 | -------------------------------------------------------------------------------- /Dynamic Programming/Longest Palindromic Subsequence/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 992228970 2 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Blocks of Ones/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1206070302 2 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Range Sum Queries/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1335650951 2 | -------------------------------------------------------------------------------- /Brute Force/Generate Partitions/src/Partition.kt: -------------------------------------------------------------------------------- 1 | 2 | data class Partition(val terms: List) -------------------------------------------------------------------------------- /Brute Force/Introduction/src/Main.kt: -------------------------------------------------------------------------------- 1 | fun main() { 2 | // Write your solution here 3 | } 4 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Ones with Updates/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 605078065 2 | -------------------------------------------------------------------------------- /Divide and Conquer/Sorting Data/src/Main.kt: -------------------------------------------------------------------------------- 1 | fun main() { 2 | // Write your solution here 3 | } 4 | -------------------------------------------------------------------------------- /Greedy Algorithms/The Main Idea/src/Main.kt: -------------------------------------------------------------------------------- 1 | fun main() { 2 | // Write your solution here 3 | } 4 | -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product — Fixing the Time Limit Issue/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 886373105 2 | -------------------------------------------------------------------------------- /Dynamic Programming/The Main Idea/src/Main.kt: -------------------------------------------------------------------------------- 1 | fun main() { 2 | // Write your solution here 3 | } 4 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Blocks of Ones with Updates/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 2105834176 2 | -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product — Fixing the Integer Overflow Issue/task-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 1097440407 2 | -------------------------------------------------------------------------------- /images/opposite_values_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | \matrix[array] (a) {0\&0\&1\&0\&|[text=hc]|0\&1\&1\&1\\}; 3 | -------------------------------------------------------------------------------- /Warmup/Sum of Two Digits/src/Task.kt: -------------------------------------------------------------------------------- 1 | fun sumOfTwoDigits(a: Int, b: Int): Int { 2 | return a + b 3 | } 4 | -------------------------------------------------------------------------------- /images/big_o.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/big_o.png -------------------------------------------------------------------------------- /images/gold_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/gold_1.png -------------------------------------------------------------------------------- /images/gold_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/gold_2.png -------------------------------------------------------------------------------- /images/gold_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/gold_3.png -------------------------------------------------------------------------------- /images/merge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/merge.png -------------------------------------------------------------------------------- /images/pair01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/pair01.png -------------------------------------------------------------------------------- /images/big_o_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/big_o_1.png -------------------------------------------------------------------------------- /images/big_o_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/big_o_2.png -------------------------------------------------------------------------------- /images/greedy_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/greedy_1.png -------------------------------------------------------------------------------- /images/greedy_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/greedy_2.png -------------------------------------------------------------------------------- /images/greedy_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/greedy_3.png -------------------------------------------------------------------------------- /images/greedy_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/greedy_4.png -------------------------------------------------------------------------------- /images/greedy_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/greedy_5.png -------------------------------------------------------------------------------- /images/merge_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/merge_2.png -------------------------------------------------------------------------------- /images/merge_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/merge_3.png -------------------------------------------------------------------------------- /images/merge_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/merge_4.png -------------------------------------------------------------------------------- /images/network1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network1.png -------------------------------------------------------------------------------- /images/network2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network2.png -------------------------------------------------------------------------------- /images/network3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network3.png -------------------------------------------------------------------------------- /images/network4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network4.png -------------------------------------------------------------------------------- /images/network5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network5.png -------------------------------------------------------------------------------- /images/network6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network6.png -------------------------------------------------------------------------------- /images/network7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network7.png -------------------------------------------------------------------------------- /images/network8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network8.png -------------------------------------------------------------------------------- /images/network9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network9.png -------------------------------------------------------------------------------- /images/pair01_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/pair01_2.png -------------------------------------------------------------------------------- /images/pair01_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/pair01_3.png -------------------------------------------------------------------------------- /images/pair01_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/pair01_4.png -------------------------------------------------------------------------------- /images/pair01_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/pair01_5.png -------------------------------------------------------------------------------- /images/subsets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/subsets.png -------------------------------------------------------------------------------- /images/big_o_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/big_o_dark.png -------------------------------------------------------------------------------- /images/gold_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/gold_1_dark.png -------------------------------------------------------------------------------- /images/gold_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/gold_2_dark.png -------------------------------------------------------------------------------- /images/gold_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/gold_3_dark.png -------------------------------------------------------------------------------- /images/merge_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/merge_dark.png -------------------------------------------------------------------------------- /images/network10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network10.png -------------------------------------------------------------------------------- /images/network12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network12.png -------------------------------------------------------------------------------- /images/network13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network13.png -------------------------------------------------------------------------------- /images/network14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network14.png -------------------------------------------------------------------------------- /images/network15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network15.png -------------------------------------------------------------------------------- /images/network16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network16.png -------------------------------------------------------------------------------- /images/pair01_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/pair01_dark.png -------------------------------------------------------------------------------- /images/partitions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/partitions.png -------------------------------------------------------------------------------- /images/big_o_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/big_o_1_dark.png -------------------------------------------------------------------------------- /images/big_o_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/big_o_2_dark.png -------------------------------------------------------------------------------- /images/calculator_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/calculator_1.png -------------------------------------------------------------------------------- /images/calculator_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/calculator_2.png -------------------------------------------------------------------------------- /images/calculator_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/calculator_3.png -------------------------------------------------------------------------------- /images/calculator_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/calculator_4.png -------------------------------------------------------------------------------- /images/derangements.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/derangements.png -------------------------------------------------------------------------------- /images/greedy_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/greedy_1_dark.png -------------------------------------------------------------------------------- /images/greedy_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/greedy_2_dark.png -------------------------------------------------------------------------------- /images/greedy_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/greedy_3_dark.png -------------------------------------------------------------------------------- /images/greedy_4_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/greedy_4_dark.png -------------------------------------------------------------------------------- /images/greedy_5_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/greedy_5_dark.png -------------------------------------------------------------------------------- /images/guess_number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/guess_number.png -------------------------------------------------------------------------------- /images/inversions_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/inversions_1.png -------------------------------------------------------------------------------- /images/inversions_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/inversions_2.png -------------------------------------------------------------------------------- /images/merge_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/merge_2_dark.png -------------------------------------------------------------------------------- /images/merge_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/merge_3_dark.png -------------------------------------------------------------------------------- /images/merge_4_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/merge_4_dark.png -------------------------------------------------------------------------------- /images/network1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network1_dark.png -------------------------------------------------------------------------------- /images/network2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network2_dark.png -------------------------------------------------------------------------------- /images/network3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network3_dark.png -------------------------------------------------------------------------------- /images/network4_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network4_dark.png -------------------------------------------------------------------------------- /images/network5_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network5_dark.png -------------------------------------------------------------------------------- /images/network6_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network6_dark.png -------------------------------------------------------------------------------- /images/network7_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network7_dark.png -------------------------------------------------------------------------------- /images/network8_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network8_dark.png -------------------------------------------------------------------------------- /images/network9_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network9_dark.png -------------------------------------------------------------------------------- /images/pair01_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/pair01_2_dark.png -------------------------------------------------------------------------------- /images/pair01_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/pair01_3_dark.png -------------------------------------------------------------------------------- /images/pair01_4_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/pair01_4_dark.png -------------------------------------------------------------------------------- /images/pair01_5_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/pair01_5_dark.png -------------------------------------------------------------------------------- /images/palindromic_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/palindromic_1.png -------------------------------------------------------------------------------- /images/palindromic_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/palindromic_2.png -------------------------------------------------------------------------------- /images/palindromic_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/palindromic_3.png -------------------------------------------------------------------------------- /images/subsets_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/subsets_dark.png -------------------------------------------------------------------------------- /images/subsets_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/subsets_logo.png -------------------------------------------------------------------------------- /course-remote-info.yaml: -------------------------------------------------------------------------------- 1 | id: 22214 2 | course_version: 6 3 | generated_edu_id: Algorithmic Challenges in Kotlin_JetBrains_kotlin 4 | -------------------------------------------------------------------------------- /images/binary_strings_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/binary_strings_1.png -------------------------------------------------------------------------------- /images/binary_strings_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/binary_strings_2.png -------------------------------------------------------------------------------- /images/count_ones_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/count_ones_logo.png -------------------------------------------------------------------------------- /images/edit_distance_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_1.png -------------------------------------------------------------------------------- /images/edit_distance_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_2.png -------------------------------------------------------------------------------- /images/edit_distance_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_3.png -------------------------------------------------------------------------------- /images/edit_distance_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_4.png -------------------------------------------------------------------------------- /images/edit_distance_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_5.png -------------------------------------------------------------------------------- /images/edit_distance_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_6.png -------------------------------------------------------------------------------- /images/inversions_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/inversions_logo.png -------------------------------------------------------------------------------- /images/network10_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network10_dark.png -------------------------------------------------------------------------------- /images/network12_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network12_dark.png -------------------------------------------------------------------------------- /images/network13_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network13_dark.png -------------------------------------------------------------------------------- /images/network14_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network14_dark.png -------------------------------------------------------------------------------- /images/network15_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network15_dark.png -------------------------------------------------------------------------------- /images/network16.tex: -------------------------------------------------------------------------------- 1 | \node{$\myvar{length}(c)=\min \{\myvar{length}(a)+4, \myalert{\myvar{length}(b)+1}\}=\min\{8,\myalert{6}\}=6$}; -------------------------------------------------------------------------------- /images/network16_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/network16_dark.png -------------------------------------------------------------------------------- /images/palindromic_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/palindromic_logo.png -------------------------------------------------------------------------------- /images/partitions_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/partitions_dark.png -------------------------------------------------------------------------------- /images/partitions_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/partitions_logo.png -------------------------------------------------------------------------------- /images/big_o_1.tex: -------------------------------------------------------------------------------- 1 | \begin{axis}[domain=0:30, grid=major] 2 | \addplot[hc] {4 * x * log2(x)}; 3 | \addplot[one] {x^2}; 4 | \end{axis} -------------------------------------------------------------------------------- /images/calculator_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/calculator_1_dark.png -------------------------------------------------------------------------------- /images/calculator_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/calculator_2_dark.png -------------------------------------------------------------------------------- /images/calculator_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/calculator_3_dark.png -------------------------------------------------------------------------------- /images/calculator_4_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/calculator_4_dark.png -------------------------------------------------------------------------------- /images/derangements_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/derangements_dark.png -------------------------------------------------------------------------------- /images/derangements_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/derangements_logo.png -------------------------------------------------------------------------------- /images/edit_distance_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_logo.png -------------------------------------------------------------------------------- /images/guess_number_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/guess_number_dark.png -------------------------------------------------------------------------------- /images/inversions_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/inversions_1_dark.png -------------------------------------------------------------------------------- /images/inversions_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/inversions_2_dark.png -------------------------------------------------------------------------------- /images/median_two_lists_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/median_two_lists_1.png -------------------------------------------------------------------------------- /images/median_two_lists_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/median_two_lists_2.png -------------------------------------------------------------------------------- /images/median_two_lists_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/median_two_lists_3.png -------------------------------------------------------------------------------- /images/money_change_dp_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_dp_1.png -------------------------------------------------------------------------------- /images/money_change_dp_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_dp_2.png -------------------------------------------------------------------------------- /images/money_change_dp_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_dp_3.png -------------------------------------------------------------------------------- /images/money_change_dp_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_dp_4.png -------------------------------------------------------------------------------- /images/money_change_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_logo.png -------------------------------------------------------------------------------- /images/palindromic_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/palindromic_1_dark.png -------------------------------------------------------------------------------- /images/palindromic_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/palindromic_2_dark.png -------------------------------------------------------------------------------- /images/palindromic_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/palindromic_3_dark.png -------------------------------------------------------------------------------- /images/range_sum_queries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/range_sum_queries.png -------------------------------------------------------------------------------- /images/subsets_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/subsets_logo_dark.png -------------------------------------------------------------------------------- /images/sum_of_two_digits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/sum_of_two_digits.png -------------------------------------------------------------------------------- /images/binary_strings_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/binary_strings_1_dark.png -------------------------------------------------------------------------------- /images/binary_strings_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/binary_strings_2_dark.png -------------------------------------------------------------------------------- /images/binary_strings_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/binary_strings_logo.png -------------------------------------------------------------------------------- /images/count_ones_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/count_ones_logo_dark.png -------------------------------------------------------------------------------- /images/covering_segments_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/covering_segments_1.png -------------------------------------------------------------------------------- /images/edit_distance_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_1_dark.png -------------------------------------------------------------------------------- /images/edit_distance_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_2_dark.png -------------------------------------------------------------------------------- /images/edit_distance_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_3_dark.png -------------------------------------------------------------------------------- /images/edit_distance_4_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_4_dark.png -------------------------------------------------------------------------------- /images/edit_distance_5_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_5_dark.png -------------------------------------------------------------------------------- /images/edit_distance_6_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_6_dark.png -------------------------------------------------------------------------------- /images/inversions_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/inversions_logo_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_8.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | $i \neq \myvar{index}_1$ 4 | \end{pseudocode} 5 | }; -------------------------------------------------------------------------------- /images/median_two_lists_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/median_two_lists_logo.png -------------------------------------------------------------------------------- /images/money_change_dp_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_dp_logo.png -------------------------------------------------------------------------------- /images/money_change_greedy_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_greedy_1.png -------------------------------------------------------------------------------- /images/money_change_greedy_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_greedy_2.png -------------------------------------------------------------------------------- /images/opposite_values_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/opposite_values_logo.png -------------------------------------------------------------------------------- /images/palindromic_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/palindromic_logo_dark.png -------------------------------------------------------------------------------- /images/partitions_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/partitions_logo_dark.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /images/big_o_2.tex: -------------------------------------------------------------------------------- 1 | \begin{axis}[domain=0:100, grid=major] 2 | \addplot[hc] {11 * x}; 3 | \addplot[one] {11 * x ^ 2 + 5 * x + 3}; 4 | \end{axis} -------------------------------------------------------------------------------- /images/collecting_signatures_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/collecting_signatures_1.png -------------------------------------------------------------------------------- /images/collecting_signatures_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/collecting_signatures_2.png -------------------------------------------------------------------------------- /images/collecting_signatures_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/collecting_signatures_3.png -------------------------------------------------------------------------------- /images/derangements_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/derangements_logo_dark.png -------------------------------------------------------------------------------- /images/distinct_summands_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/distinct_summands_logo.png -------------------------------------------------------------------------------- /images/edit_distance_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/edit_distance_logo_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_1.png -------------------------------------------------------------------------------- /images/max_pairwise_product_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_2.png -------------------------------------------------------------------------------- /images/max_pairwise_product_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_3.png -------------------------------------------------------------------------------- /images/max_pairwise_product_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_4.png -------------------------------------------------------------------------------- /images/max_pairwise_product_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_5.png -------------------------------------------------------------------------------- /images/max_pairwise_product_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_6.png -------------------------------------------------------------------------------- /images/max_pairwise_product_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_7.png -------------------------------------------------------------------------------- /images/max_pairwise_product_7.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | $A[i] \neq A[\myvar{index}_1]$ 4 | \end{pseudocode} 5 | }; -------------------------------------------------------------------------------- /images/max_pairwise_product_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_8.png -------------------------------------------------------------------------------- /images/max_pairwise_product_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_9.png -------------------------------------------------------------------------------- /images/median_two_lists_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/median_two_lists_1_dark.png -------------------------------------------------------------------------------- /images/median_two_lists_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/median_two_lists_2_dark.png -------------------------------------------------------------------------------- /images/median_two_lists_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/median_two_lists_3_dark.png -------------------------------------------------------------------------------- /images/money_change_dp_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_dp_1_dark.png -------------------------------------------------------------------------------- /images/money_change_dp_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_dp_2_dark.png -------------------------------------------------------------------------------- /images/money_change_dp_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_dp_3_dark.png -------------------------------------------------------------------------------- /images/money_change_dp_4_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_dp_4_dark.png -------------------------------------------------------------------------------- /images/money_change_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_logo_dark.png -------------------------------------------------------------------------------- /images/range_sum_queries_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/range_sum_queries_dark.png -------------------------------------------------------------------------------- /images/searching_sorted_data1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/searching_sorted_data1.png -------------------------------------------------------------------------------- /images/searching_sorted_data2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/searching_sorted_data2.png -------------------------------------------------------------------------------- /images/searching_sorted_data3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/searching_sorted_data3.png -------------------------------------------------------------------------------- /images/sum_of_two_digits_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/sum_of_two_digits_dark.png -------------------------------------------------------------------------------- /images/sum_of_two_digits_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/sum_of_two_digits_logo.png -------------------------------------------------------------------------------- /images/binary_strings_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/binary_strings_logo_dark.png -------------------------------------------------------------------------------- /images/collecting_signatures_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/collecting_signatures_logo.png -------------------------------------------------------------------------------- /images/count_blocks_of_ones_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/count_blocks_of_ones_logo.png -------------------------------------------------------------------------------- /images/count_ones_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | \matrix[array] {1\&1\&0\&1\&1\&1\&1\&0\\}; 3 | \node at (0,-1.25) {$\texttt{countOnes()} \to \textcolor{hc}{6}$}; -------------------------------------------------------------------------------- /images/covering_segments_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/covering_segments_1_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_logo.png -------------------------------------------------------------------------------- /images/median_two_lists_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/median_two_lists_logo_dark.png -------------------------------------------------------------------------------- /images/money_change_dp_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_dp_logo_dark.png -------------------------------------------------------------------------------- /images/money_change_greedy_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_greedy_1_dark.png -------------------------------------------------------------------------------- /images/money_change_greedy_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/money_change_greedy_2_dark.png -------------------------------------------------------------------------------- /images/opposite_values_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/opposite_values_logo_dark.png -------------------------------------------------------------------------------- /images/points_and_segments_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/points_and_segments_logo.png -------------------------------------------------------------------------------- /images/unchangeable_amount_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/unchangeable_amount_logo.png -------------------------------------------------------------------------------- /images/collecting_signatures_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/collecting_signatures_1_dark.png -------------------------------------------------------------------------------- /images/collecting_signatures_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/collecting_signatures_2_dark.png -------------------------------------------------------------------------------- /images/collecting_signatures_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/collecting_signatures_3_dark.png -------------------------------------------------------------------------------- /images/count_ones_with_updates_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/count_ones_with_updates_logo.png -------------------------------------------------------------------------------- /images/distinct_summands_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/distinct_summands_logo_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_1_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_2_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_3_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_4_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_4_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_5_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_5_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_6_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_6_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_7_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_7_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_8_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_8_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_9_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_9_dark.png -------------------------------------------------------------------------------- /images/network13.tex: -------------------------------------------------------------------------------- 1 | \node { 2 | $\myvar{length}(v)= \min_{\text{each predecessor~$w$ of~$v$}} 3 | \{\myvar{length}(w) + \myvar{length}(w, v) \} \, .$ 4 | }; -------------------------------------------------------------------------------- /images/searching_sorted_data1_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/searching_sorted_data1_dark.png -------------------------------------------------------------------------------- /images/searching_sorted_data2_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/searching_sorted_data2_dark.png -------------------------------------------------------------------------------- /images/searching_sorted_data3_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/searching_sorted_data3_dark.png -------------------------------------------------------------------------------- /images/sum_of_two_digits_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/sum_of_two_digits_logo_dark.png -------------------------------------------------------------------------------- /images/collecting_signatures_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/collecting_signatures_logo_dark.png -------------------------------------------------------------------------------- /images/count_blocks_of_ones_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/count_blocks_of_ones_logo_dark.png -------------------------------------------------------------------------------- /images/max_pairwise_product_6.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | print($\myvar{index}_1$, $\myvar{index}_2$) 4 | \end{pseudocode} 5 | }; -------------------------------------------------------------------------------- /images/max_pairwise_product_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/max_pairwise_product_logo_dark.png -------------------------------------------------------------------------------- /images/points_and_segments_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/points_and_segments_logo_dark.png -------------------------------------------------------------------------------- /images/unchangeable_amount_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/unchangeable_amount_logo_dark.png -------------------------------------------------------------------------------- /Brute Force/lesson-info.yaml: -------------------------------------------------------------------------------- 1 | content: 2 | - Introduction 3 | - Generate Binary Strings 4 | - Generate Derangements 5 | - Generate Subsets 6 | - Generate Partitions 7 | -------------------------------------------------------------------------------- /images/count_ones_with_updates_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/count_ones_with_updates_logo_dark.png -------------------------------------------------------------------------------- /images/sum_of_two_digits.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | $\myproc{SumOfTwoDigits}(a, b)$:\\ 4 | return $a+b$ 5 | \end{pseudocode} 6 | }; -------------------------------------------------------------------------------- /Greedy Algorithms/lesson-info.yaml: -------------------------------------------------------------------------------- 1 | content: 2 | - The Main Idea 3 | - Money Change 4 | - Minimum Unchangeable Amount 5 | - Distinct Summands 6 | - Collecting Signatures 7 | -------------------------------------------------------------------------------- /images/network15.tex: -------------------------------------------------------------------------------- 1 | \node{ 2 | $\myvar{length}(t)=\min \{\myalert{\myvar{length}(c)+6}, \myvar{length}(d)+8, \myvar{length}(e)+4\} = \min\{\myalert{12},16,16\}=12$ 3 | }; -------------------------------------------------------------------------------- /images/count_blocks_of_ones_with_updates_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/count_blocks_of_ones_with_updates_logo.png -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Ones/solution.md: -------------------------------------------------------------------------------- 1 | 2 | ### Solution 3 | 4 | Scan the string and count the number of ones. 5 | You can also use the built-in `count` method. 6 | -------------------------------------------------------------------------------- /images/money_change_dp_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \foreach \y/\n in {1.5/1, 0/3, -1.5/4} 4 | \node[draw=mc, text=mc, circle, inner sep=0mm, minimum size=10mm] at (0, \y) {\textcent\n}; -------------------------------------------------------------------------------- /images/network12.tex: -------------------------------------------------------------------------------- 1 | \node { 2 | $ \begin{aligned} 3 | \myvar{length}(a)&=\myvar{length}(s)+4\,,\\ 4 | \myvar{length}(b)&=\myvar{length}(s)+5\,. 5 | \end{aligned}$ 6 | }; -------------------------------------------------------------------------------- /images/count_blocks_of_ones_with_updates_logo_dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jetbrains-academy/algo-challenges-in-kotlin/HEAD/images/count_blocks_of_ones_with_updates_logo_dark.png -------------------------------------------------------------------------------- /Queries and Incremental Updates/lesson-info.yaml: -------------------------------------------------------------------------------- 1 | content: 2 | - Count Ones 3 | - Count Ones with Updates 4 | - Count Blocks of Ones 5 | - Count Blocks of Ones with Updates 6 | - Range Sum Queries 7 | -------------------------------------------------------------------------------- /images/money_change_dp_1.tex: -------------------------------------------------------------------------------- 1 | \foreach \c [count=\i] in {3, 3, 4, 4, 4, 4, 4} 2 | \node[draw=mc,circle,inner sep=0mm,minimum size=8mm] at (\i * 1.5, 0) {\textcent \c}; 3 | \draw[dashed] (2.5,-0.5) rectangle (8,0.5); -------------------------------------------------------------------------------- /images/money_change_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \foreach \x/\y/\r/\n in {-1.5/0/30/1, 0/0/30/5, 1.5/0/30/10} { 4 | \node[draw=mc,fill=mcfill,circle,inner sep=0mm,minimum size={\r}] at (\x,\y) {\textcent\n};} -------------------------------------------------------------------------------- /images/pair01_2.tex: -------------------------------------------------------------------------------- 1 | \foreach \s [count=\i from 0] in {0,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,~,1} { 2 | \draw[mc] (0.5*\i,0) rectangle (0.5*\i + 0.5, 0.5); 3 | \node[draw=none, text=mc] at (0.5*\i + 0.25, 0.25) {$\s$}; 4 | } -------------------------------------------------------------------------------- /Dynamic Programming/lesson-info.yaml: -------------------------------------------------------------------------------- 1 | content: 2 | - The Main Idea 3 | - Money Change Again 4 | - Primitive Calculator 5 | - Minimum Sum Path 6 | - Edit Distance 7 | - Longest Palindromic Subsequence 8 | - Maximum Amount of Gold 9 | -------------------------------------------------------------------------------- /images/count_ones_with_updates_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | \matrix[array] {1\&1\&0\&1\&1\&1\&1\&0\\}; 3 | \node[text width=45mm, align=center] at (0,-1.25) { 4 | $\texttt{flip(4)}$\\ 5 | $\texttt{countOnes()} \to \textcolor{hc}{5}$ 6 | }; -------------------------------------------------------------------------------- /images/money_change_greedy_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | return $\lfloor \myvar{money}/10 \rfloor + \lfloor(\myvar{money} \bmod{10})/5\rfloor + 4 | (\myvar{money} \bmod{5})$ 5 | \end{pseudocode} 6 | }; -------------------------------------------------------------------------------- /images/edit_distance_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \foreach \t [count=\i] in {short, hort, port, ports} 4 | \node[rectangle, draw=none, inner sep=.5mm] (\i) at (0, 2.5-\i) {\t}; 5 | \foreach \f/\t in {1/2, 2/3, 3/4} 6 | \draw[->, hc] (\f) -- (\t); -------------------------------------------------------------------------------- /images/distinct_summands_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \foreach \x/\y/\w in {-2/.5/8, -2/-1/1, -1.5/-1/2, -.5/-1/5} { 4 | \draw (\x, \y) rectangle (\x+.5*\w, \y+.5); 5 | \node at (\x+.25*\w, \y+.25) {\w}; 6 | } 7 | 8 | \node[text=hc] at (0,-1.5) {3}; -------------------------------------------------------------------------------- /.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /images/pair01_5.tex: -------------------------------------------------------------------------------- 1 | \foreach \s [count=\i from 0] in {0,~,~,~,~,~,~,~,~,~,1,~,~,~,~,~,~,~,~,1} { 2 | \draw[mc] (0.5*\i,0) rectangle (0.5*\i + 0.5, 0.5); 3 | \node[draw=none, text=mc] at (0.5*\i + 0.25, 0.25) {$\s$}; 4 | } 5 | \draw[hc] (0,0) rectangle (5.5,0.5); -------------------------------------------------------------------------------- /images/palindromic_1.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | $\operatorname{LPS}(i,j)=\max 3 | \begin{cases} 4 | \operatorname{LPS}(i+1,j-1)+2 & \text{if } s[i]=s[j-1]\\ 5 | \operatorname{LPS}(i+1,j)\\ 6 | \operatorname{LPS}(i,j-1)\\ 7 | \end{cases}$ 8 | }; -------------------------------------------------------------------------------- /images/palindromic_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \matrix[array] (a) {A\&B\&C\&A\&B\&C\&A\&B\\}; 4 | \foreach \i in {2, 3, 4, 6, 8} 5 | \draw[hc] (a-1-\i.-90) -- ([shift={(0,-.2)}]a-1-\i.-90); 6 | \draw[hc] ([shift={(0,-.2)}]a-1-2.-90) -- ([shift={(0,-.2)}]a-1-8.-90); -------------------------------------------------------------------------------- /Warmup/lesson-info.yaml: -------------------------------------------------------------------------------- 1 | content: 2 | - Welcome! 3 | - Sum of Two Digits 4 | - Maximum Pairwise Product 5 | - Maximum Pairwise Product — Fixing the Integer Overflow Issue 6 | - Maximum Pairwise Product — Fixing the Time Limit Issue 7 | - Estimating the Running Time 8 | -------------------------------------------------------------------------------- /images/count_blocks_of_ones_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | \matrix[array] {1\&1\&1\&0\&0\&1\&0\&1\\}; 3 | \node[align=center, text width=48mm] at (0,-1.25) { 4 | $\texttt{countOnes()} \to \textcolor{hc}{5}$\\ 5 | $\texttt{countBlocksOfOnes()} \to \textcolor{hc}{3}$\\ 6 | }; -------------------------------------------------------------------------------- /Divide and Conquer/lesson-info.yaml: -------------------------------------------------------------------------------- 1 | content: 2 | - Guess a Number 3 | - Searching Sorted Data 4 | - Lower Bound 5 | - Count in Range 6 | - Opposite Values 7 | - Sorting Data 8 | - Points and Segments 9 | - Count Inversions 10 | - Median in Two Sorted Lists 11 | -------------------------------------------------------------------------------- /images/pair01_3.tex: -------------------------------------------------------------------------------- 1 | \foreach \s [count=\i from 0] in {0,~,~,~,~,~,~,~,~,~,0,~,~,~,~,~,~,~,~,1} { 2 | \draw[mc] (0.5*\i,0) rectangle (0.5*\i + 0.5, 0.5); 3 | \node[draw=none, text=mc] at (0.5*\i + 0.25, 0.25) {$\s$}; 4 | } 5 | \draw[hc] (0.5*10,0) rectangle (0.5*11,0.5); -------------------------------------------------------------------------------- /images/pair01_4.tex: -------------------------------------------------------------------------------- 1 | \foreach \s [count=\i from 0] in {0,~,~,~,~,~,~,~,~,~,0,~,~,~,~,~,~,~,~,1} { 2 | \draw[mc] (0.5*\i,0) rectangle (0.5*\i + 0.5, 0.5); 3 | \node[draw=none, text=mc] at (0.5*\i + 0.25, 0.25) {$\s$}; 4 | } 5 | \draw[hc] (0.5*10,0) rectangle (0.5*20,0.5); -------------------------------------------------------------------------------- /images/range_sum_queries.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | \matrix[array] (a) {\strut $2$ \&\strut $-1$ \&\strut $7$ \&\strut $2$ \&\strut $-3$ \&\strut $-2$ \&\strut $4$\\}; 3 | \draw[hc] ([shift={(0,-.2)}]a-1-2.-135) -- ([shift={(0,-.2)}]a-1-6.-45); 4 | \node[text=hc] at (0, -.7) {$3$}; -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Ones/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | fun countOnes(seq: CharSequence): Int { 3 | var count = 0 4 | for (digit in seq) { 5 | if (digit == '1') { 6 | count += 1 7 | } 8 | } 9 | return count 10 | } 11 | -------------------------------------------------------------------------------- /images/calculator_1.tex: -------------------------------------------------------------------------------- 1 | \node{ 2 | $\myvar{calculator}(n)=1+\min 3 | \begin{cases} 4 | \myvar{calculator}(n-1), &\\ 5 | \myvar{calculator}(n/2), & \text{if $n$ is divisible by~$2$,}\\ 6 | \myvar{calculator}(n/3), & \text{if $n$ is divisible by~$3$.}\\ 7 | \end{cases}$ 8 | }; -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /images/network10.tex: -------------------------------------------------------------------------------- 1 | \node { 2 | $ \begin{aligned} 3 | \myvar{length}(c)&=\min \{\myvar{length}(a)+4, \myvar{length}(b)+1\}\,, \\ 4 | \myvar{length}(d)&=\min \{\myvar{length}(a)+7, \myvar{length}(c)+2\}\,, \\ 5 | \myvar{length}(e)&=\myvar{length}(b)+7\,. 6 | \end{aligned}$ 7 | }; -------------------------------------------------------------------------------- /images/count_blocks_of_ones_with_updates_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | \matrix[array] {1\&1\&1\&0\&0\&1\&0\&1\\}; 3 | \node[align=center, text width=48mm] at (0,-1.25) { 4 | $\texttt{flip(0)}$\\ 5 | $\texttt{countOnes()} \to \textcolor{hc}{4}$\\ 6 | $\texttt{countBlocksOfOnes()} \to \textcolor{hc}{3}$\\ 7 | }; -------------------------------------------------------------------------------- /Warmup/Welcome!/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: theory 2 | files: 3 | - name: src/Main.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Warmup+/+Welcome! -------------------------------------------------------------------------------- /images/pair01.tex: -------------------------------------------------------------------------------- 1 | \foreach \s [count=\i from 0] in {0,0,0,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1} { 2 | \draw[mc] (0.5*\i,0) rectangle (0.5*\i + 0.5, 0.5); 3 | \node[draw=none, text=mc] at (0.5*\i + 0.25, 0.25) {$\s$}; 4 | } 5 | \foreach \x in {3, 5, 9, 13, 15, 19} 6 | \draw[hc,->] (0.5*\x,-0.4) -- (0.5*\x,-0.1); -------------------------------------------------------------------------------- /images/searching_sorted_data1.tex: -------------------------------------------------------------------------------- 1 | \begin{scope}[scale=.4] 2 | \foreach \h [count=\n] in {1, 2, 4, 5, 7, 9, 12, 13, 16, 18, 19, 20, 21} 3 | \draw[mc, fill=mcfill] (\n, 0) rectangle (\n + .8, \h / 5); 4 | \foreach \x/\t in {0/0, 1/1, 2/2, 12/{n-1}} 5 | \node[below] at (\x + 1.4, 0) {$a_{\t}$}; 6 | \end{scope} -------------------------------------------------------------------------------- /images/median_two_lists_1.tex: -------------------------------------------------------------------------------- 1 | \foreach \i in {0,...,6} { 2 | \node at (\i, 0.5) {$a_{\i}$}; 3 | \node at (\i, -0.5) {$b_{\i}$}; 4 | } 5 | 6 | \foreach \i in {0,...,5} { 7 | \node at (\i+0.5, 0.5) {$\le$}; 8 | \node at (\i+0.5, -0.5) {$\le$}; 9 | } 10 | 11 | \node[rotate=-90] at (3, 0) {$\ge$}; 12 | -------------------------------------------------------------------------------- /images/inversions_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \matrix (A) [array, row 2/.style={nodes={text=hc, draw=none}}] { 4 | 4\&3\&2\&4\&5\&4\&7\&3\\ 5 | 0\&1\&2\&0\&0\&1\&0\&5\\ 6 | }; 7 | 8 | \foreach \i/\j in {1/2, 1/3, 2/3, 5/6, 5/8, 7/8, 6/8, 4/8, 1/8} 9 | \path (A-1-\i) edge[draw,out=90,in=90,hc] (A-1-\j); 10 | -------------------------------------------------------------------------------- /Greedy Algorithms/Minimum Unchangeable Amount/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | 3 | fun findMinimumChange(v: IntArray): Long { 4 | v.sort() 5 | var answer = 1L 6 | for (value in v) { 7 | if (value > answer) { 8 | break 9 | } 10 | answer += value 11 | } 12 | return answer 13 | } -------------------------------------------------------------------------------- /Brute Force/Introduction/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: theory 2 | files: 3 | - name: src/Main.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Brute+Force+/+Introduction -------------------------------------------------------------------------------- /Divide and Conquer/Lower Bound/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: theory 2 | files: 3 | - name: src/Main.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Divide+and+Conquer+/+Lower+Bound -------------------------------------------------------------------------------- /Divide and Conquer/Guess a Number/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: theory 2 | files: 3 | - name: src/Main.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Divide+and+Conquer+/+Guess+a+Number -------------------------------------------------------------------------------- /Divide and Conquer/Sorting Data/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: theory 2 | files: 3 | - name: src/Main.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Divide+and+Conquer+/+Sorting+Data -------------------------------------------------------------------------------- /Dynamic Programming/The Main Idea/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: theory 2 | files: 3 | - name: src/Main.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Dynamic+Programming+/+The+main+idea -------------------------------------------------------------------------------- /Greedy Algorithms/The Main Idea/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: theory 2 | files: 3 | - name: src/Main.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Greedy+Algorithms+/+The+main+idea -------------------------------------------------------------------------------- /Warmup/Estimating the Running Time/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: theory 2 | files: 3 | - name: src/Main.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Warmup+/+Estimating+the+running+time -------------------------------------------------------------------------------- /Divide and Conquer/Searching Sorted Data/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: theory 2 | files: 3 | - name: src/Main.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Divide+and+Conquer+/+Searching+Sorted+Data -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Blocks of Ones/solution.md: -------------------------------------------------------------------------------- 1 | 2 | ### Solution 3 | 4 | An index $0 \le i < n$ 5 | is a starting index of a block of ones 6 | of a binary string $s[0\dotsc n)$ if and only if 7 | $$s[i]=1 \text{ and } (i=0 \text{ or } s[i-1]=0).$$ 8 | Thus, it suffices to count the number of $0 \le i < n$ 9 | satisfying the condition above. -------------------------------------------------------------------------------- /images/gold_1.tex: -------------------------------------------------------------------------------- 1 | \node { 2 | $ 3 | \myvar{pack}(w,i)= 4 | \begin{cases} 5 | {\tt true} &\text{if $i=0$ and $w=0$}\\ 6 | {\tt false} &\text{if $i=0$ and $w>0$}\\ 7 | \myvar{pack}(w,i-1) &\text{if $i>0$ and $w_{i-1} > w$}\\ 8 | \myvar{pack}(w,i-1) \text{ or } \myvar{pack}(w-w_{i-1},i-1) &\text{otherwise} 9 | \end{cases} 10 | $ 11 | }; 12 | -------------------------------------------------------------------------------- /Greedy Algorithms/Money Change/src/Task.kt: -------------------------------------------------------------------------------- 1 | fun change(money: Int): Int { 2 | var current = money 3 | var coins = 0 4 | while (current >= 10) { 5 | current -= 10 6 | coins++ 7 | } 8 | while (current >= 5) { 9 | current -= 5 10 | coins++ 11 | } 12 | coins += current 13 | return coins 14 | } 15 | -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product/src/Task.kt: -------------------------------------------------------------------------------- 1 | import kotlin.math.max 2 | 3 | fun maximumPairwiseProduct(a: IntArray): Int { 4 | val len = a.size 5 | var res = Int.MIN_VALUE 6 | for (i in 0 until len) { 7 | for (j in i + 1 until len) { 8 | res = max(res, a[i] * a[j]) 9 | } 10 | } 11 | return res 12 | } 13 | 14 | -------------------------------------------------------------------------------- /images/binary_strings_1.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | $\myproc{GenerateBinaryStrings}(s, n)$:\\ 4 | if $\operatorname{length}(s)=n$:\\ 5 | \quad add $s$ to the list\\ 6 | else:\\ 7 | \quad $\myproc{GenerateBinaryStrings}(s + {\tt 0}, n)$\\ 8 | \quad $\myproc{GenerateBinaryStrings}(s + {\tt 1}, n)$\\ 9 | \end{pseudocode} 10 | }; -------------------------------------------------------------------------------- /images/binary_strings_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | $\myproc{GenerateBinaryStrings}(n)$:\\ 4 | if $n=0$:\\ 5 | \quad return empty list\\ 6 | $\myvar{list} \gets \myproc{GenerateBinaryStrings}(n-1)$\\ 7 | return $[{\tt 0} + s \text{ for $s$ in \myvar{list}}] + [{\tt 1} + s \text{ for $s$ in \myvar{list}}]$ 8 | \end{pseudocode} 9 | }; -------------------------------------------------------------------------------- /images/binary_strings_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \begin{scope}[every tree node/.style={draw, rectangle, inner sep=1mm, minimum size=4mm}, mc, scale=.7, yshift=15mm] 4 | \Tree [.~ 5 | [.0 [.00 \node[hc]{000}; \node[hc]{001}; ] [.01 \node[hc]{010}; \node[hc]{011}; ] ] 6 | [.1 [.10 \node[hc]{100}; \node[hc]{101}; ] [.11 \node[hc]{110}; \node[hc]{111}; ] ] 7 | ] 8 | \end{scope} -------------------------------------------------------------------------------- /Dynamic Programming/Maximum Amount of Gold/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample1() { 7 | val expected = 9 8 | val found = findMaximumAmountOfGold(10, intArrayOf(1, 4, 8)) 9 | assertEquals(expected, found) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /images/subsets_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | \node[text width=45mm] { 3 | \centerline{$n=4, k=2$} 4 | \begin{align} 5 | &\{0, 1\}\tag{\textcolor{hc}{1}}\\ 6 | &\{0, 2\}\tag{\textcolor{hc}{2}}\\ 7 | &\{0, 3\}\tag{\textcolor{hc}{3}}\\ 8 | &\{1, 2\}\tag{\textcolor{hc}{4}}\\ 9 | &\{1, 3\}\tag{\textcolor{hc}{5}}\\ 10 | &\{2, 3\}\tag{\textcolor{hc}{6}} 11 | \end{align} 12 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | /.idea 3 | /gradle 4 | /gradlew 5 | /gradlew.bat 6 | /**/build 7 | /.coursecreator 8 | *.DS_Store 9 | images/tmp.tex 10 | images/main_dark.pdf 11 | /**/task.md 12 | images/cover.synctex.gz 13 | images/cover.pdf 14 | images/sandbox.aux 15 | images/sandbox.log 16 | images/sandbox.pdf 17 | images/sandbox.synctex.gz 18 | images/main.aux 19 | images/main.log 20 | -------------------------------------------------------------------------------- /Greedy Algorithms/Distinct Summands/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | fun distinctSummands(n: Long): List { 3 | val answer = mutableListOf() 4 | var left = n 5 | for (x in 1..n) { 6 | if (left - x <= x) { 7 | answer.add(left) 8 | break 9 | } 10 | left -= x 11 | answer.add(x) 12 | } 13 | return answer 14 | } 15 | -------------------------------------------------------------------------------- /images/max_pairwise_product_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \matrix[array, 4 | row 1/.style={nodes={arraynodes,draw=none}}, 5 | column 1/.style={nodes={arraynodes,draw=none}} 6 | ] at (0,0) 7 | {~\&5\&6\&2\&7\&4\\ 8 | 5\&~\&30\&10\&35\&20\\ 9 | 6\&30\&~\&12\&\textcolor{hc}{42}\&24\\ 10 | 2\&10\&12\&~\&14\&8\\ 11 | 7\&35\&\textcolor{hc}{42}\&14\&~\&28\\ 12 | 4\&20\&24\&8\&28\&~\\}; -------------------------------------------------------------------------------- /Divide and Conquer/Count Inversions/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertArrayEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample1() { 7 | val list = listOf(3, 1, 3, 4, 2) 8 | val actual = findInversions(list) 9 | assertArrayEquals(intArrayOf(0, 1, 0, 0, 3), actual) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Ones with Updates/solution.md: -------------------------------------------------------------------------------- 1 | 2 | ### Solution 3 | 4 | Given a string, count the number of ones in it and store it 5 | in a variable, say, `counter`. Then, each time `flip` is called, 6 | adjust `counter` accordingly. In turn, when `countOnes` is called, 7 | instead of counting the number of ones from scratch, just return the 8 | value of `counter`. 9 | -------------------------------------------------------------------------------- /images/collecting_signatures_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \foreach \a/\b/\y in {0.5/1.5/0, 1/4/-.25, 2.5/4.5/-0.5, 2/3.5/-0.75} 4 | \draw[mc] (\a-2.5,\y+0.5) -- (\b-2.5,\y+0.5); 5 | \draw[mc,->] (-2.2,-1+0.5) -- (2.2,-1+0.5); 6 | \foreach \x in {1.25, 3} { 7 | \draw[hc,dashed] (\x-2.5,-1) -- (\x-2.5,1); 8 | \node[draw=hc, fill=hc, circle,minimum size=1mm,inner sep=0mm] at (\x-2.5,-0.5) {}; 9 | } -------------------------------------------------------------------------------- /images/max_pairwise_product_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | \myproc{MaxPairwiseProductNaive}($A[1\dotsc n]$):\\ 4 | $\myvar{product} \gets 0$\\ 5 | for $i$ from $1$ to~$n$:\\ 6 | \quad for $j$ from $i+1$ to~$n$:\\ 7 | \quad\quad $\myvar{product} \gets \max(\myvar{product}, A[i] \cdot A[j])$\\ 8 | return \myvar{product} 9 | \end{pseudocode} 10 | }; -------------------------------------------------------------------------------- /Greedy Algorithms/Collecting Signatures/src/Task.kt: -------------------------------------------------------------------------------- 1 | data class Segment(val l: Int, val r: Int) 2 | 3 | fun segmentsCover(segments: List): List { 4 | val res = ArrayList() 5 | for (segment in segments.sortedBy { it.r }) { 6 | if (res.isEmpty() || res.last() < segment.l) { 7 | res.add(segment.r) 8 | } 9 | } 10 | return res 11 | } 12 | -------------------------------------------------------------------------------- /images/partitions_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | \node[text width=45mm] { 3 | \begin{align} 4 | 5&=\notag\\ 5 | &=1+1+1+1+1\tag{\textcolor{hc}{1}}\\ 6 | &=1+1+1+2\tag{\textcolor{hc}{2}}\\ 7 | &=1+1+3\tag{\textcolor{hc}{3}}\\ 8 | &=1+2+2\tag{\textcolor{hc}{4}}\\ 9 | &=1+4\tag{\textcolor{hc}{5}}\\ 10 | &=2+3\tag{\textcolor{hc}{6}}\\ 11 | &=5\tag{\textcolor{hc}{7}} 12 | \end{align} 13 | }; -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product — Fixing the Integer Overflow Issue/src/Task.kt: -------------------------------------------------------------------------------- 1 | import kotlin.math.max 2 | 3 | fun maximumPairwiseProduct(a: IntArray): Long { 4 | val len = a.size 5 | var res = Long.MIN_VALUE 6 | for (i in 0 until len) { 7 | for (j in i + 1 until len) { 8 | res = max(res, a[i].toLong() * a[j]) 9 | } 10 | } 11 | return res 12 | } 13 | -------------------------------------------------------------------------------- /Warmup/Sum of Two Digits/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample1() { 7 | val a = 9 8 | val b = 7 9 | val correct = 16 10 | val result = sumOfTwoDigits(a, b) 11 | assertEquals(result, correct, "countOnes($a, $b)") 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /Divide and Conquer/Opposite Values/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | fun findAnyOccurrenceOf01(str: CharSequence): Int { 3 | var left = 0 4 | var right = str.length - 1 5 | while (left + 1 < right) { 6 | val mid = (left + right) ushr 1 7 | if (str[mid] == '1') { 8 | right = mid 9 | } else { 10 | left = mid 11 | } 12 | } 13 | return left 14 | } 15 | -------------------------------------------------------------------------------- /images/edit_distance_3.tex: -------------------------------------------------------------------------------- 1 | \node { 2 | $\operatorname{EditDistance}(i,j)=\min 3 | \begin{cases} 4 | \textcolor{two}{\operatorname{EditDistance}(i,j-1)+1}\\ 5 | \textcolor{one}{\operatorname{EditDistance}(i-1,j)+1}\\ 6 | \textcolor{four}{\operatorname{EditDistance}(i-1,j-1)+1} &\text{if }A[i]\neq B[j]\\ 7 | \textcolor{three}{\operatorname{EditDistance}(i-1,j-1)} &\text{if }A[i]=B[j]\\ 8 | \end{cases}$ 9 | }; -------------------------------------------------------------------------------- /Dynamic Programming/Money Change Again/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | fun changeMoney(money: Int): Int { 3 | val table = IntArray(money + 1) { Int.MAX_VALUE } 4 | table[0] = 0 5 | for (m in 1..money) { 6 | for (c in sequenceOf(1, 3, 4)) { 7 | if (c <= m) { 8 | table[m] = minOf(table[m], 1 + table[m - c]) 9 | } 10 | } 11 | } 12 | return table[money] 13 | } 14 | -------------------------------------------------------------------------------- /images/median_two_lists_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \tikzstyle{a}=[draw=mc] 4 | \tikzstyle{b}=[draw=hc] 5 | \begin{scope}[xshift=4, yshift=3] 6 | \foreach \h/\s [count=\i from 0] in {1/a, 2/b, 4/b, 5/b, 7/a, 8/b, 9/b, 11/b, 12/a, 13/a, 14/a, 15/b, 15.5/a, 16/a} 7 | \draw[\s] (-2+\i*0.25,-2) rectangle (-1.75+\i*0.25-.04,-2+\h*0.25); 8 | \draw[hc, ->] (-1.875+6*0.25, -2.4) -- (-1.875+6*0.25, -2.1); 9 | \end{scope} 10 | -------------------------------------------------------------------------------- /images/greedy_5.tex: -------------------------------------------------------------------------------- 1 | \node[text width=110mm] { 2 | \begin{pseudocode} 3 | \myproc{Change}(\myvar{money}, \myvar{Denominations}):\\ 4 | if $\myvar{money}=0$:\\ 5 | \quad return~$0$\\ 6 | $\myvar{maxCoin} \gets \text{largest}$ among 7 | \myvar{Denominations} that does not 8 | exceed \myvar{money}\\ 9 | return $1+\myproc{Change}(\myvar{money}-\myvar{maxCoin}, \myvar{Denominations})$ 10 | \end{pseudocode} 11 | }; -------------------------------------------------------------------------------- /Dynamic Programming/Money Change Again/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample1() { 7 | val actual = changeMoney(15) 8 | assertEquals(4, actual) 9 | } 10 | 11 | @Test 12 | fun sample2() { 13 | val actual = changeMoney(26) 14 | assertEquals(7, actual) 15 | } 16 | } -------------------------------------------------------------------------------- /images/greedy_3.tex: -------------------------------------------------------------------------------- 1 | \begin{scope}[scale=.75] 2 | \foreach \y in {0, 1, 2, 3} 3 | \draw (0,\y) -- (11,\y); 4 | \foreach \x in {0, 1, 4, 5, 11} { 5 | \draw (\x,0) -- (\x,1); 6 | \draw (\x,2) -- (\x,3); 7 | } 8 | 9 | \node[rotate=-90] at (5.5,1.5) {$>$}; 10 | 11 | \foreach \x/\y/\n in {0/2/d_m, 0/0/d_i, 2/0/\alpha, 2/2/\alpha, 4/0/d_m, 4/2/d_i, 7.5/0/\beta, 7.5/2/\beta} 12 | \node at (\x+0.5,\y+0.5) {$\n$}; 13 | \end{scope} -------------------------------------------------------------------------------- /images/main.tex: -------------------------------------------------------------------------------- 1 | \documentclass{standalone} 2 | \usepackage[dvipsnames]{xcolor} 3 | 4 | \colorlet{mc}{black} % main color 5 | \colorlet{hc}{red!90!black} % highlight color 6 | 7 | \colorlet{one}{green!40} 8 | \colorlet{two}{blue!30} 9 | \colorlet{three}{red!30} 10 | \colorlet{four}{yellow} 11 | 12 | \input{header} 13 | 14 | \begin{document} 15 | \begin{tikzpicture} 16 | \input tmp 17 | \end{tikzpicture} 18 | \end{document} 19 | -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | - name: test/Tests.kt 6 | visible: true 7 | - name: task_template.md 8 | visible: false 9 | - name: test/HiddenTests.kt 10 | visible: false 11 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Warmup+/+Maximum+pairwise+product -------------------------------------------------------------------------------- /images/main_dark.tex: -------------------------------------------------------------------------------- 1 | \documentclass{standalone} 2 | \usepackage[dvipsnames]{xcolor} 3 | 4 | \colorlet{mc}{white!85!black} % main color 5 | \colorlet{hc}{yellow} % highlight color 6 | 7 | \colorlet{one}{green!40} 8 | \colorlet{two}{blue!30} 9 | \colorlet{three}{red!30} 10 | \colorlet{four}{yellow} 11 | 12 | \input{header} 13 | 14 | \begin{document} 15 | \begin{tikzpicture} 16 | \input tmp 17 | \end{tikzpicture} 18 | \end{document} 19 | -------------------------------------------------------------------------------- /images/points_and_segments_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | 3 | \begin{scope}[xshift=-25mm,yshift=-25mm] 4 | \foreach \a/\b/\y in {0.5/1.5/2.75, 2.5/4.5/2.5, 2/3.5/2.25} 5 | \draw[mc] (\a,\y) -- (\b,\y); 6 | 7 | \draw[->] (0.5,2) -- (4.5,2); 8 | \foreach \x/\n in {1/1, 1.75/0, 3/2, 4/1} { 9 | \draw[dashed,hc] (\x,1.75) -- (\x,3.5); 10 | \node[below] at (\x,1.75) {\n}; 11 | \draw[draw=hc, fill=hc] (\x,2) circle (.5mm); 12 | } 13 | \end{scope} -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Blocks of Ones/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | fun countBlocksOfOnes(seq: CharSequence): Int { 3 | var oneRecently = false 4 | var blocksCount = 0 5 | for (c in seq) { 6 | val isOne = c == '1' 7 | if (isOne) { 8 | if (!oneRecently) { 9 | blocksCount += 1 10 | } 11 | } 12 | oneRecently = isOne 13 | } 14 | return blocksCount 15 | } 16 | -------------------------------------------------------------------------------- /images/greedy_4.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | \myproc{LargestConcatenate}(\myvar{Numbers}):\\ 4 | if $\myvar{Numbers}$ is empty:\\ 5 | \quad return empty string\\ 6 | $\myvar{maxNumber} \gets \text{largest among \myvar{Numbers}}$\\ 7 | remove \myvar{maxNumber} from \myvar{Numbers}\\ 8 | return concatenate of \myvar{maxNumber} 9 | and \myproc{LargestConcatenate}(\myvar{Numbers}) 10 | \end{pseudocode} 11 | }; -------------------------------------------------------------------------------- /Brute Force/Generate Binary Strings/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertTrue 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample() { 7 | val actual = generateBinaryStrings(2) 8 | val expected = listOf("00", "01", "10", "11") 9 | assertTrue(actual == expected) { 10 | "[length = 4] Expected $expected, found $actual" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Divide and Conquer/Opposite Values/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertTrue 2 | import org.junit.jupiter.api.Assertions.assertEquals 3 | import org.junit.jupiter.api.Test 4 | 5 | class Tests { 6 | @Test 7 | fun sampleTests() { 8 | val result = findAnyOccurrenceOf01("000101") 9 | assertTrue(result == 2 || result == 4) 10 | 11 | assertEquals(findAnyOccurrenceOf01("000111"), 2) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /images/calculator_4.tex: -------------------------------------------------------------------------------- 1 | \foreach \n in {1,...,12} 2 | \node[circle, draw, inner sep=0mm, minimum size=5mm] (\n) at (\n,0) {$\n$}; 3 | \foreach \n in {1,...,12} { 4 | \pgfmathtruncatemacro{\a}{\n+1} 5 | \ifnumless{\a}{13}{\draw[->] (\n) -- (\a);}{} 6 | \pgfmathtruncatemacro{\a}{2*\n} 7 | \ifnumless{\a}{13}{\path (\n) edge[->,bend right] (\a);}{} 8 | \pgfmathtruncatemacro{\a}{3*\n} 9 | \ifnumless{\a}{13}{\path (\n) edge[->,bend left] (\a);}{} 10 | } -------------------------------------------------------------------------------- /Divide and Conquer/Searching Sorted Data/src/Main.kt: -------------------------------------------------------------------------------- 1 | fun find(a: IntArray, x: Int): Int { 2 | var lower = 0 3 | var upper = a.size - 1 4 | while (upper >= lower) { 5 | val middle = (lower + upper) / 2 6 | if (a[middle] == x) { 7 | return middle 8 | } else if (a[middle] > x) { 9 | upper = middle - 1 10 | } else { 11 | lower = middle + 1 12 | } 13 | } 14 | return -1 15 | } 16 | -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product — Fixing the Time Limit Issue/src/Task.kt: -------------------------------------------------------------------------------- 1 | fun maximumPairwiseProduct(a: IntArray): Long { 2 | var firstMax = Int.MIN_VALUE 3 | var secondMax = Int.MIN_VALUE 4 | for (x in a) { 5 | if (x > firstMax) { 6 | secondMax = firstMax 7 | firstMax = x 8 | } else if (x > secondMax) { 9 | secondMax = x 10 | } 11 | } 12 | return firstMax.toLong() * secondMax 13 | } 14 | -------------------------------------------------------------------------------- /images/greedy_1.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | \myproc{LargestConcatenate}(\myvar{Numbers}):\\ 4 | $\myvar{result} \gets \text{empty string}$\\ 5 | while \myvar{Numbers} is not empty:\\ 6 | \quad $\myvar{maxNumber} \gets \text{largest among \myvar{Numbers}}$\\ 7 | \quad append \myvar{maxNumber} to \myvar{result}\\ 8 | \quad remove \myvar{maxNumber} from \myvar{Numbers}\\ 9 | return \myvar{result} 10 | \end{pseudocode} 11 | }; -------------------------------------------------------------------------------- /images/max_pairwise_product_1.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | \myproc{MaxPairwiseProductNaive}($A[1\dotsc n]$):\\ 4 | $\myvar{product} \gets 0$\\ 5 | for $i$ from $1$ to~$n$:\\ 6 | \quad for $j$ from $1$ to~$n$:\\ 7 | \quad\quad if $i \neq j$:\\ 8 | \quad\quad\quad if $\myvar{product} < A[i] \cdot A[j]$:\\ 9 | \quad\quad\quad\quad $\myvar{product} \gets A[i] \cdot A[j]$\\ 10 | return \myvar{product} 11 | \end{pseudocode} 12 | }; -------------------------------------------------------------------------------- /images/money_change_dp_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | \myproc{Change}(\myvar{money}):\\ 4 | if $\myvar{money}=0$:\\ 5 | \quad return~$0$\\ 6 | else:\\ 7 | \quad$\myvar{result} \gets +\infty$\\ 8 | \quad for $c=1,3,4$:\\ 9 | \quad\quad if $c \le \myvar{money}$:\\ 10 | \quad\quad\quad $\myvar{result} \gets \min(\myvar{result}, 1+\myproc{Change}(\myvar{money}-c))$\\ 11 | \quad return \myvar{result} 12 | \end{pseudocode} 13 | }; -------------------------------------------------------------------------------- /Dynamic Programming/Minimum Sum Path/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample1() { 7 | val input = intArrayOf(3, 1, 3, 4, 2) 8 | assertEquals(9, minimumSumPath(input)) 9 | } 10 | 11 | 12 | @Test 13 | fun sample2() { 14 | val input = intArrayOf(1, 2, 3, -2, -2, 5); 15 | assertEquals(4, minimumSumPath(input)) 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /images/collecting_signatures_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | $\myproc{SegmentsCover}(\myvar{segments})$:\\ 4 | $\myvar{points} \gets \text{empty set}$\\ 5 | while \myvar{segments} is not empty:\\ 6 | \quad $r_m \gets \text{minimum right endpoint of a~segment from \myvar{segments}}$\\ 7 | \quad add $r_m$ to \myvar{points}\\ 8 | \quad remove segments covered by~$r_m$ from the set \myvar{segments}\\ 9 | return \myvar{points} 10 | \end{pseudocode} 11 | }; -------------------------------------------------------------------------------- /images/money_change_dp_4.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | \myproc{Change}(\myvar{money}):\\ 4 | $\myvar{table}[0..\myvar{money}] \gets [+\infty, \dotsc, +\infty]$\\ 5 | $\myvar{table}[0] \gets 0$\\ 6 | 7 | for $m$~from~$1$ to~$\myvar{money}$:\\ 8 | \quad for $c=1,3,4$:\\ 9 | \quad\quad if $c \le \myvar{money}$:\\ 10 | \quad\quad\quad $\myvar{table}[m] \gets \min(\myvar{table}[m], 1+\myvar{table}[m-c])$\\ 11 | return $\myvar{table}[\myvar{money}]$ 12 | \end{pseudocode} 13 | }; -------------------------------------------------------------------------------- /Dynamic Programming/Minimum Sum Path/src/Task.kt: -------------------------------------------------------------------------------- 1 | import kotlin.math.min 2 | 3 | fun minimumSumPath(a: IntArray): Long { 4 | val n = a.size 5 | val minPath = Array(n) { LongArray(2) { Long.MAX_VALUE } } 6 | minPath[0][0] = a[0].toLong() 7 | minPath[1][0] = a[0].toLong() + a[1].toLong() 8 | for (i in 2 until n) { 9 | minPath[i][0] = min(minPath[i - 1][0], minPath[i - 1][1]) + a[i] 10 | minPath[i][1] = minPath[i - 2][0] + a[i] 11 | } 12 | return minPath[n - 1].min() 13 | } 14 | -------------------------------------------------------------------------------- /images/greedy_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=115mm] { 2 | \begin{pseudocode} 3 | \myproc{Change}(\myvar{money}, \myvar{Denominations}):\\ 4 | $\myvar{numCoins} \gets 0$\\ 5 | while $\myvar{money} > 0$:\\ 6 | \quad $\myvar{maxCoin} \gets \text{largest}$ among 7 | \myvar{Denominations} that does not 8 | exceed \myvar{money}\\ 9 | \quad $\myvar{money} \gets \myvar{money} - \myvar{maxCoin}$\\ 10 | \quad $\myvar{numCoins} \gets \myvar{numCoins} + 1$\\ 11 | return \myvar{numCoins} 12 | \end{pseudocode} 13 | }; -------------------------------------------------------------------------------- /Divide and Conquer/Count in Range/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | fun countInRange(a: IntArray, l: Int, r: Int): Int { 3 | return lowerBound(a, r + 1) - lowerBound(a, l) 4 | } 5 | 6 | fun lowerBound(a: IntArray, x: Int): Int { 7 | var lower = -1 8 | var upper = a.size 9 | while (upper > lower + 1) { 10 | val middle = (lower + upper) / 2 11 | if (a[middle] < x) { 12 | lower = middle 13 | } else { 14 | upper = middle 15 | } 16 | } 17 | return upper 18 | } 19 | -------------------------------------------------------------------------------- /images/derangements_logo.tex: -------------------------------------------------------------------------------- 1 | \logo{} 2 | \node[text width=45mm] { 3 | \vspace{1mm} 4 | \begin{align} 5 | &(1, 0, 3, 2)\tag{\textcolor{hc}{1}}\\ 6 | &(1, 2, 3, 0)\tag{\textcolor{hc}{2}}\\ 7 | &(1, 3, 0, 2)\tag{\textcolor{hc}{3}}\\ 8 | &(2, 0, 3, 1)\tag{\textcolor{hc}{4}}\\ 9 | &(2, 3, 0, 1)\tag{\textcolor{hc}{5}}\\ 10 | &(2, 3, 1, 0)\tag{\textcolor{hc}{6}}\\ 11 | &(3, 0, 1, 2)\tag{\textcolor{hc}{7}}\\ 12 | &(3, 2, 0, 1)\tag{\textcolor{hc}{8}}\\ 13 | &(3, 2, 1, 0)\tag{\textcolor{hc}{9}} 14 | \end{align} 15 | }; -------------------------------------------------------------------------------- /images/subsets.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | $\myproc{GenerateSubsets}(n, k, m)$\\ 4 | if $n-mn$:\\ 6 | \quad return empty list\\ 7 | if $s=n$:\\ 8 | \quad return a list containing a single element $L$\\ 9 | $m \gets \text{largest element of~$L$ (or $1$ if $L$ is empty)}$\\ 10 | $\myvar{result} \gets \text{empty list}$\\ 11 | for $k$ from $m$ to $n-s$:\\ 12 | \quad add to $\myvar{result}$ all lists from $\myproc{Generate}(n, L+[k])$\\ 13 | return \myvar{result} 14 | \end{pseudocode} 15 | }; -------------------------------------------------------------------------------- /Warmup/Sum of Two Digits/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 46 7 | length: 12 8 | placeholder_text: // Write your code here 9 | - name: test/Tests.kt 10 | visible: true 11 | - name: task_template.md 12 | visible: false 13 | - name: solution.md 14 | visible: false 15 | - name: test/HiddenTests.kt 16 | visible: false 17 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Warmup+/+Sum+of+two+digits -------------------------------------------------------------------------------- /Divide and Conquer/Lower Bound/src/Main.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * Finds minimum `i` such that `a[i] >= x`, 3 | * returns `a.size` if all `a[i] < x` 4 | */ 5 | fun lowerBound(a: IntArray, x: Int): Int { 6 | var lower = -1 7 | var upper = a.size 8 | while (upper > lower + 1) { 9 | val middle = (lower + upper) / 2 10 | if (a[middle] < x) { 11 | lower = middle 12 | } else { 13 | upper = middle 14 | } 15 | } 16 | return upper 17 | } 18 | 19 | fun main() { 20 | println(lowerBound(intArrayOf(2, 4, 7, 11, 12), 9)) 21 | } 22 | -------------------------------------------------------------------------------- /images/derangements.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | $\myproc{GenerateDerangements}(\myvar{prefix}, n)$\\ 4 | if $\operatorname{length}(\myvar{prefix}) = n$:\\ 5 | \quad return a~list consisting of $\myvar{prefix}$ only\\ 6 | $\myvar{result} \gets \text{empty list}$\\ 7 | for $k$ from $0$ to~$n-1$:\\ 8 | \quad if $k \not \in \myvar{prefix}$ and $k \neq \operatorname{length}(\myvar{prefix})$:\\ 9 | \quad\quad add $\myproc{GenerateDerangements}(\myvar{prefix} + [k], n)$ to $\myvar{result}$\\ 10 | return $\myvar{result}$ 11 | \end{pseudocode} 12 | }; -------------------------------------------------------------------------------- /images/money_change_greedy_1.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | \myproc{Change}(\myvar{money}):\\ 4 | $\myvar{numCoins} \gets 0$\\ 5 | while $\myvar{money} > 0$:\\ 6 | \quad if $\myvar{money} \ge 10$:\\ 7 | \quad\quad $\myvar{money} \gets \myvar{money}-10$\\ 8 | \quad else if $\myvar{money} \ge 5$:\\ 9 | \quad\quad $\myvar{money} \gets \myvar{money}-5$\\ 10 | \quad else:\\ 11 | \quad\quad $\myvar{money} \gets \myvar{money}-1$\\ 12 | \quad $\myvar{numCoins} \gets \myvar{numCoins} + 1$\\ 13 | return \myvar{numCoins} 14 | \end{pseudocode} 15 | }; -------------------------------------------------------------------------------- /.github/workflows/gradle-test.yml: -------------------------------------------------------------------------------- 1 | name: Gradle Test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-20.04 8 | 9 | steps: 10 | - uses: actions/checkout@v3.0.0 11 | - name: Set up JDK 11 12 | uses: actions/setup-java@v3.0.0 13 | with: 14 | java-version: 11 15 | distribution: liberica 16 | - name: Gradle Wrapper Validation 17 | uses: gradle/wrapper-validation-action@v1.0.4 18 | - uses: gradle/gradle-build-action@v2.1.5 19 | with: 20 | arguments: test 21 | -------------------------------------------------------------------------------- /images/max_pairwise_product_3.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | \myproc{MaxPairwiseProductFast}($A[1 \dotsc n]$):\\ 4 | $\myvar{index}_1 \gets 1$\\ 5 | for $i$ from $2$ to $n$:\\ 6 | \quad if $A[i] > A[\myvar{index}_1]$:\\ 7 | \quad\quad $\myvar{index}_1 \gets i$\\[1mm] 8 | $\myvar{index}_2 \gets 1$\\ 9 | for $i$ from $2$ to $n$:\\ 10 | \quad if $A[i] \neq A[\myvar{index}_1]$ and $A[i] > A[\myvar{index}_2]$:\\ 11 | \quad\quad $\myvar{index}_2 \gets i$\\[1mm] 12 | return $A[\myvar{index}_1] \cdot A[\myvar{index}_2]$ 13 | \end{pseudocode} 14 | }; -------------------------------------------------------------------------------- /images/max_pairwise_product_9.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | \myproc{MaxPairwiseProductFast}($A[1 \dotsc n]$):\\ 4 | $\myvar{index} \gets 1$\\ 5 | for $i$ from $2$ to $n$:\\ 6 | \quad if $A[i] > A[\myvar{index}]$:\\ 7 | \quad\quad $\myvar{index} \gets i$\\ 8 | swap $A[\myvar{index}]$ and $A[n]$\\[1mm] 9 | $\myvar{index} \gets 1$\\ 10 | for $i$ from $2$ to $n-1$:\\ 11 | \quad if $A[i] > A[\myvar{index}]$:\\ 12 | \quad\quad $\myvar{index} \gets i$\\ 13 | swap $A[\myvar{index}]$ and $A[n-1]$\\ 14 | return $A[n-1] \cdot A[n]$ 15 | \end{pseudocode} 16 | }; -------------------------------------------------------------------------------- /Queries and Incremental Updates/Range Sum Queries/src/RangeSum.kt: -------------------------------------------------------------------------------- 1 | class RangeSum(a: IntArray) { 2 | private val prefix = LongArray(a.size) { a[it].toLong() } 3 | 4 | init { 5 | for (i in prefix.indices.drop(1)) { 6 | prefix[i] += prefix[i - 1] 7 | } 8 | } 9 | 10 | private fun get(index: Int): Long { 11 | return when (index) { 12 | -1 -> 0 13 | else -> prefix[index] 14 | } 15 | } 16 | 17 | fun getSum(left: Int, right: Int): Long { 18 | return get(right - 1) - get(left - 1) 19 | } 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /.github/workflows/gradle-build.yml: -------------------------------------------------------------------------------- 1 | name: Gradle Build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-20.04 8 | 9 | steps: 10 | - uses: actions/checkout@v3.0.0 11 | - name: Set up JDK 11 12 | uses: actions/setup-java@v3.0.0 13 | with: 14 | java-version: 11 15 | distribution: liberica 16 | - name: Gradle Wrapper Validation 17 | uses: gradle/wrapper-validation-action@v1.0.4 18 | - uses: gradle/gradle-build-action@v2.1.5 19 | with: 20 | arguments: build --stacktrace -x test 21 | -------------------------------------------------------------------------------- /Greedy Algorithms/Collecting Signatures/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 100 7 | length: 197 8 | placeholder_text: // Write your code here 9 | - name: test/Tests.kt 10 | visible: true 11 | - name: task_template.md 12 | visible: false 13 | - name: solution.md 14 | visible: false 15 | - name: test/HiddenTests.kt 16 | visible: false 17 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Greedy+Algorithms+/+Collecting+Signatures -------------------------------------------------------------------------------- /Greedy Algorithms/Distinct Summands/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 45 7 | length: 227 8 | placeholder_text: ' TODO("not implemented")' 9 | - name: test/Tests.kt 10 | visible: true 11 | - name: task_template.md 12 | visible: false 13 | - name: solution.md 14 | visible: false 15 | - name: test/HiddenTests.kt 16 | visible: false 17 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Greedy+Algorithms+/+Distinct+Summands -------------------------------------------------------------------------------- /Greedy Algorithms/Money Change/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 30 7 | length: 221 8 | placeholder_text: ' TODO("implement your solution here")' 9 | - name: test/Tests.kt 10 | visible: true 11 | - name: task_template.md 12 | visible: false 13 | - name: solution.md 14 | visible: false 15 | - name: test/HiddenTests.kt 16 | visible: false 17 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Greedy+Algorithms+/+Money+Change -------------------------------------------------------------------------------- /images/calculator_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | \myproc{Calculator}($n$):\\ 4 | $\myvar{table}[1..n] \gets [+\infty, \dotsc, +\infty]$\\ 5 | $\myvar{table}[1] \gets 0$\\ 6 | 7 | for $k$~from~$2$ to~$n$:\\ 8 | \quad $\myvar{table}[k]=1+\myvar{table}[k-1]$\\ 9 | \quad if $k$ is divisible by~$2$:\\ 10 | \quad\quad $\myvar{table}[k]=\min(\myvar{table}[k], 1+\myvar{table}[k/2]$)\\ 11 | \quad if $k$ is divisible by~$3$:\\ 12 | \quad\quad $\myvar{table}[k]=\min(\myvar{table}[k], 1+\myvar{table}[k/3]$)\\ 13 | return $\myvar{table}[n]$ 14 | \end{pseudocode} 15 | }; -------------------------------------------------------------------------------- /Dynamic Programming/Minimum Sum Path/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 64 7 | length: 352 8 | placeholder_text: ' TODO("not implemented yet")' 9 | - name: test/Tests.kt 10 | visible: true 11 | - name: task_template.md 12 | visible: false 13 | - name: solution.md 14 | visible: false 15 | - name: test/HiddenTests.kt 16 | visible: false 17 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Dynamic+Programming+/+Minimum+Sum+Path -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Blocks of Ones/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun testSample1() { 7 | val sequence = "001001" 8 | val blocks = countBlocksOfOnes(sequence) 9 | assertEquals(2, blocks, "countBlocksOfOnes($sequence)") 10 | } 11 | 12 | @Test 13 | fun testSample2() { 14 | val sequence = "11100101" 15 | val blocks = countBlocksOfOnes(sequence) 16 | assertEquals(3, blocks, "countBlocksOfOnes($sequence)") 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Ones/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 41 7 | length: 126 8 | placeholder_text: ' TODO("not implemented")' 9 | - name: test/Tests.kt 10 | visible: true 11 | - name: task_template.md 12 | visible: false 13 | - name: test/HiddenTests.kt 14 | visible: false 15 | - name: solution.md 16 | visible: false 17 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Queries+and+incremental+updates+/+Count+Ones -------------------------------------------------------------------------------- /Brute Force/Generate Derangements/src/Derangement.kt: -------------------------------------------------------------------------------- 1 | 2 | data class Derangement(private val permutation: IntArray) { 3 | override fun toString(): String { 4 | return permutation.contentToString() 5 | } 6 | 7 | override fun equals(other: Any?): Boolean { 8 | if (this === other) return true 9 | if (javaClass != other?.javaClass) return false 10 | other as Derangement 11 | if (!permutation.contentEquals(other.permutation)) return false 12 | return true 13 | } 14 | 15 | override fun hashCode(): Int { 16 | return permutation.contentHashCode() 17 | } 18 | } -------------------------------------------------------------------------------- /Divide and Conquer/Opposite Values/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 57 7 | length: 241 8 | placeholder_text: return str.indexOf("01") 9 | - name: test/HiddenTests.kt 10 | visible: false 11 | - name: test/Tests.kt 12 | visible: true 13 | - name: solution.md 14 | visible: false 15 | - name: task_template.md 16 | visible: false 17 | solution_hidden: false 18 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Divide+and+Conquer+/+Opposite+Values -------------------------------------------------------------------------------- /Divide and Conquer/Median in Two Sorted Lists/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Test { 5 | @Test 6 | fun sample1() { 7 | val first = listOf(1, 2, 5) 8 | val second = listOf(3, 4, 6) 9 | val actual = getMedian(first, second) 10 | assertEquals(3, actual) 11 | } 12 | 13 | @Test 14 | fun sample2() { 15 | val first = listOf("a", "z", "zz") 16 | val second = listOf("a", "a", "zz") 17 | val actual = getMedian(first, second) 18 | assertEquals("a", actual) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Greedy Algorithms/Minimum Unchangeable Amount/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 45 7 | length: 161 8 | placeholder_text: " return v.sumOf { it.toLong() } + 1" 9 | - name: test/Tests.kt 10 | visible: true 11 | - name: test/HiddenTests.kt 12 | visible: false 13 | - name: solution.md 14 | visible: false 15 | - name: task_template.md 16 | visible: false 17 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Greedy+Algorithms+/+Minimum+Unchangeable+Amount -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Ones with Updates/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun testSample() { 7 | val sequence = "001001" 8 | val blocks = CountOnesWithUpdates(sequence) 9 | assertEquals(2, blocks.countOnes(), "countOnes($sequence)") 10 | blocks.flip(0); 11 | assertEquals(3, blocks.countOnes()) 12 | blocks.flip(1); 13 | assertEquals(4, blocks.countOnes()) 14 | blocks.flip(2); 15 | assertEquals(3, blocks.countOnes()) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /images/big_o.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{center} 3 | \begin{tabular}{rcccc} 4 | \toprule 5 | & $n$ & $n \log n$ & $n^2$ & $2^n$\\ 6 | \midrule 7 | $n=20$ & $<1$ sec & $<1$ sec & $<1$ sec & $<1$ sec\\ 8 | $n=50$ & $<1$ sec & $<1$ sec & $<1$ sec & 13 days\\ 9 | $n=10^2$ & $<1$ sec & $<1$ sec & $<1$ sec & $4\cdot 10^{13}$ year\\ 10 | $n=10^6$ & $<1$ sec & $<1$ sec & 17 min & \\ 11 | $n=10^9$ & 1 sec & 30 sec & $30$ years & \\ 12 | \midrule 13 | max $n$ & $10^9$ & $10^{7.5}$ & $10^{4.5}$ & 30 \\ 14 | \bottomrule 15 | \end{tabular} 16 | \end{center} 17 | }; -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Blocks of Ones/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 49 7 | length: 268 8 | placeholder_text: ' TODO("not implemented")' 9 | - name: test/Tests.kt 10 | visible: true 11 | - name: task_template.md 12 | visible: false 13 | - name: test/HiddenTests.kt 14 | visible: false 15 | - name: solution.md 16 | visible: false 17 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Queries+and+incremental+updates+/+Count+Blocks+of+Ones -------------------------------------------------------------------------------- /images/inversions_1.tex: -------------------------------------------------------------------------------- 1 | \node[text width=120mm] { 2 | \begin{pseudocode} 3 | \myproc{CountInversions}(\myvar{List}):\\ 4 | if $|\myvar{List}| = 1$:\\ 5 | \quad return [0]\\ 6 | $\myvar{LeftHalf} \gets \text{left half of~\myvar{List}}$\\ 7 | $\myvar{RightHalf} \gets \text{right half of~\myvar{List}}$\\ 8 | $\myvar{inversions} \gets \myproc{CountInversions}(\myvar{LeftHalf})+\myproc{CountInversions}(\myvar{RightHalf})$\\ 9 | sort \myvar{LeftHalf}\\ 10 | for $x$ in $\myvar{LeftHalf}$:\\ 11 | \quad increase inversions of~$x$ by~$\myproc{CountLarger}(\myvar{LeftHalf}, x)$\\ 12 | return \myvar{inversions} 13 | \end{pseudocode} 14 | }; -------------------------------------------------------------------------------- /Divide and Conquer/Count in Range/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun example1() { 7 | val result = countInRange(intArrayOf(2, 3, 5, 8, 10), 3, 9) 8 | assertEquals(result, 3) 9 | } 10 | 11 | @Test 12 | fun example2() { 13 | val result = countInRange(intArrayOf(2, 3, 5, 8, 10), 1, 20) 14 | assertEquals(result, 5) 15 | } 16 | 17 | @Test 18 | fun example3() { 19 | val result = countInRange(intArrayOf(2, 3, 5, 8, 10), 6, 7) 20 | assertEquals(result, 0) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /images/median_two_lists_3.tex: -------------------------------------------------------------------------------- 1 | \foreach \i in {0,...,2} { 2 | \node at (\i, 0.5) {$a_{\i}$}; 3 | \node at (\i, -0.5) {$b_{\i}$}; 4 | } 5 | 6 | \foreach \i in {3,...,6} { 7 | \node[text=hc] at (\i, 0.5) {$a_{\i}$}; 8 | \node[text=hc] at (\i, -0.5) {$b_{\i}$}; 9 | } 10 | 11 | \foreach \i in {0,1} { 12 | \node at (\i+0.5, 0.5) {$\le$}; 13 | \node at (\i+0.5, -0.5) {$\le$}; 14 | } 15 | 16 | \node at (2.5, 0.5) {$\le$}; 17 | \node[text=hc] at (2.5, -0.5) {$\le$}; 18 | 19 | \foreach \i in {3, ..., 5} { 20 | \node[text=hc] at (\i+0.5, 0.5) {$\le$}; 21 | \node[text=hc] at (\i+0.5, -0.5) {$\le$}; 22 | } 23 | 24 | \node[rotate=-90, text=hc] at (3, 0) {$\ge$}; 25 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Blocks of Ones with Updates/solution.md: -------------------------------------------------------------------------------- 1 | 2 | ### Solution 3 | 4 | Recall that an index $0 \le i < n$ 5 | is a starting index of a block of ones 6 | of a binary string $s[0\dotsc n)$ if and only if 7 | $$s[i]=1 \text{ and } (i=0 \text{ or } s[i-1]=0).$$ 8 | This expression reveals that this "status" of the $i$-th index 9 | depends on $s[i-1]$ 10 | and $s[i]$ only. 11 | When the $i$-th bit is flipped, it affects the status 12 | of the indices $i$ and $i+1$. Thus, to update the number of blocks of 13 | ones after the flip of the $i$-th bit, it suffices to compute the status 14 | of the indices $i$ and $i+1$ before and after the flip. -------------------------------------------------------------------------------- /Queries and Incremental Updates/Range Sum Queries/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample() { 7 | val rsq = RangeSum(intArrayOf(1, 3, -2, 4, 2)) 8 | assertEquals(1L, rsq.getSum(0, 1)) 9 | assertEquals(8L, rsq.getSum(0, 5)) 10 | assertEquals(0L, rsq.getSum(2, 2)) 11 | assertEquals(-2L, rsq.getSum(2, 3)) 12 | assertEquals(4L, rsq.getSum(2, 5)) 13 | assertEquals(5, rsq.getSum(1, 4)) 14 | assertEquals(0, rsq.getSum(0, 0)) 15 | assertEquals(2, rsq.getSum(4, 5)) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Warmup/Sum of Two Digits/test/HiddenTests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | import kotlin.time.Duration.Companion.seconds 4 | 5 | class HiddenTests { 6 | @Test 7 | fun testAllPairs() = runTimeout(2.seconds, "All tests") { 8 | for (a in 0 until 10) { 9 | for (b in 0 until 10) { 10 | testSingle(a, b) 11 | } 12 | } 13 | } 14 | 15 | private fun testSingle(a: Int, b: Int) { 16 | val correct = a + b 17 | val result = sumOfTwoDigits(a, b) 18 | assertEquals(result, correct, "countOnes($a, $b)") 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /images/median_two_lists_2.tex: -------------------------------------------------------------------------------- 1 | \foreach \i in {4,...,6} { 2 | \node at (\i, 0.5) {$a_{\i}$}; 3 | \node at (\i, -0.5) {$b_{\i}$}; 4 | } 5 | 6 | \foreach \i in {0,...,2} { 7 | \node[text=hc] at (\i, 0.5) {$a_{\i}$}; 8 | \node[text=hc] at (\i, -0.5) {$b_{\i}$}; 9 | } 10 | 11 | \node at (3, 0.5) {$a_3$}; 12 | \node[text=hc] at (3, -0.5) {$b_3$}; 13 | 14 | 15 | \foreach \i in {3,...,5} { 16 | \node at (\i+0.5, 0.5) {$\le$}; 17 | \node at (\i+0.5, -0.5) {$\le$}; 18 | } 19 | 20 | \foreach \i in {0,...,2} { 21 | \node[text=hc] at (\i+0.5, 0.5) {$\le$}; 22 | \node[text=hc] at (\i+0.5, -0.5) {$\le$}; 23 | } 24 | 25 | \node[rotate=-90, text=hc] at (3, 0) {$\ge$}; 26 | -------------------------------------------------------------------------------- /images/max_pairwise_product_4.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | \myproc{MaxPairwiseProductFast}($A[1 \dotsc n]$):\\ 4 | $\myvar{index}_1 \gets 1$\\ 5 | for $i$ from $2$ to $n$:\\ 6 | \quad if $A[i] > A[\myvar{index}_1]$:\\ 7 | \quad\quad $\myvar{index}_1 \gets i$\\[1mm] 8 | if $\myvar{index}_1=1$:\\ 9 | \quad $\myvar{index}_2 \gets 2$\\ 10 | else:\\ 11 | \quad $\myvar{index}_2 \gets 1$\\ 12 | for $i$ from 1 to $n$:\\ 13 | \quad if $A[i] \neq A[\myvar{index}_1]$ and $A[i] > A[\myvar{index}_2]$:\\ 14 | \quad\quad $\myvar{index}_2 \gets i$\\[1mm] 15 | return $A[\myvar{index}_1] \cdot A[\myvar{index}_2]$ 16 | \end{pseudocode} 17 | }; -------------------------------------------------------------------------------- /Dynamic Programming/Edit Distance/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | 6 | @Test 7 | fun sample1() { 8 | check(3, "short", "ports") 9 | } 10 | 11 | @Test 12 | fun sample2() { 13 | check(5, "editing", "distance") 14 | } 15 | 16 | @Test 17 | fun sample3() { 18 | check(0, "ab", "ab") 19 | } 20 | 21 | private fun check(expected: Int, first: String, second: String) { 22 | assertEquals(expected, findEditDistance(first, second)) { 23 | "editDistance($first, $second) wrong" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /images/palindromic_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | $\myvar{table} \gets \text{associative array}$\\[1mm] 4 | 5 | $\myproc{LPS}(i, j)$:\\ 6 | if $(i,j)$ is not in $\myvar{table}$:\\ 7 | \quad if $i=j$:\\ 8 | \quad\quad $\myvar{table}[i,j] \gets 0$\\ 9 | \quad else if $i=j-1$:\\ 10 | \quad\quad $\myvar{table}[i,j] \gets 1$\\ 11 | \quad else:\\ 12 | \quad\quad if $s[i]=s[j-1]$:\\ 13 | \quad\quad\quad $\myvar{table}[i,j] \gets \myproc{LPS}(i+1, j-1)+2$\\ 14 | \quad\quad else:\\ 15 | \quad\quad\quad $\myvar{table}[i,j] \gets \max(\myproc{LPS}(i+1, j), \myproc{LPS}(i, j-1))$\\ 16 | return $\myvar{table}[i,j]$ 17 | \end{pseudocode} 18 | }; -------------------------------------------------------------------------------- /images/gold_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | $\myproc{Knapsack}([w_0, \dotsc, w_{n-1}], W)$:\\ 4 | $\myvar{pack} \gets \text{two-dimensional array of size $(W+1) \times (n+1)$}$\\ 5 | initialize all elements of \myvar{pack} to {\tt false}\\ 6 | $\myvar{pack}[0][0] \gets {\tt true}$\\ 7 | for~$i$ from~$1$ to~$n$:\\ 8 | \quad for $w$ from $0$ to $W$:\\ 9 | \quad\quad if $w_{i-1} > w$:\\ 10 | \quad\quad\quad $\myvar{pack}[w][i] \gets \myvar{pack}[w][i-1]$\\ 11 | \quad\quad else:\\ 12 | \quad\quad\quad $\myvar{pack}[w][i] \gets \myvar{pack}[w][i-1]\text{ OR } \myvar{pack}[w-w_{i-1}][i-1]$\\ 13 | return $\myvar{pack}[W][n]$ 14 | \end{pseudocode} 15 | }; 16 | -------------------------------------------------------------------------------- /Brute Force/Generate Subsets/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 25 7 | length: 760 8 | placeholder_text: // Implement additional functions and classes here 9 | - offset: 839 10 | length: 43 11 | placeholder_text: TODO("not implemented") 12 | - name: test/Tests.kt 13 | visible: true 14 | - name: solution.md 15 | visible: false 16 | - name: task_template.md 17 | visible: false 18 | - name: test/HiddenTests.kt 19 | visible: false 20 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Brute+Force+/+Generate+Subsets -------------------------------------------------------------------------------- /Divide and Conquer/Count Inversions/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 1031 7 | length: 35 8 | placeholder_text: TODO("not implemented") 9 | - offset: 0 10 | length: 963 11 | placeholder_text: // Implement additional functions and classes here 12 | - name: test/Tests.kt 13 | visible: true 14 | - name: task_template.md 15 | visible: false 16 | - name: solution.md 17 | visible: false 18 | - name: test/HiddenTests.kt 19 | visible: false 20 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Divide+and+Conquer+/+Count+Inversions -------------------------------------------------------------------------------- /Greedy Algorithms/Distinct Summands/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Distinct Summands 4 | 5 | 8 | 9 | Represent a positive integer as the sum of the 10 | maximum number of pairwise distinct positive integers. 11 | 12 |
13 | 14 | | Input | Return value | 15 | |-------|--------------| 16 | | 8 | 1 2 5 | 17 | | 6 | 1 2 3 | 18 | | 2 | 2 | 19 | 20 |
21 | 22 |
23 | Can one represent $8$ as the sum of four positive distinct integers? 24 |
25 | 26 |
27 | <%include "solution.md" %> 28 |
-------------------------------------------------------------------------------- /Brute Force/Generate Derangements/solution.md: -------------------------------------------------------------------------------- 1 | 2 | ### Solution 3 | 4 | Let $n=5$. What could be the next element in a derangement starting 5 | with $4, 0$? It should be one of the remaining three elements: $1$, 6 | $2$, or $3$. At the same time, $2$ cannot follow $4, 0$ as this 7 | would create a fixed point. 8 | 9 | This suggests the following recursive algorithm. Given a prefix of 10 | a derangement, extend it by one element and proceed recursively. 11 | This one element should not appear in the prefix and should not 12 | form a fixed point. In order to generate all derangements in the 13 | lexicographical order, we enumerate the elements in the increasing 14 | order. 15 | 16 | -------------------------------------------------------------------------------- /Divide and Conquer/Count in Range/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 54 7 | length: 50 8 | placeholder_text: "return a.count{it in l..r}" 9 | - offset: 108 10 | length: 293 11 | placeholder_text: // Write your functions here 12 | - name: test/HiddenTests.kt 13 | visible: false 14 | - name: test/Tests.kt 15 | visible: true 16 | - name: solution.md 17 | visible: false 18 | - name: task_template.md 19 | visible: false 20 | solution_hidden: false 21 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Divide+and+Conquer+/+Count+in+Range -------------------------------------------------------------------------------- /Dynamic Programming/Edit Distance/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 0 7 | length: 1136 8 | placeholder_text: ' 9 | 10 | // write additional code here 11 | 12 | ' 13 | - offset: 1208 14 | length: 56 15 | placeholder_text: ' TODO("not implemented")' 16 | - name: test/Tests.kt 17 | visible: true 18 | - name: task_template.md 19 | visible: false 20 | - name: test/HiddenTests.kt 21 | visible: false 22 | - name: solution.md 23 | visible: false 24 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Dynamic+Programming+/+Edit+Distance -------------------------------------------------------------------------------- /Brute Force/Generate Binary Strings/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 657 7 | length: 47 8 | placeholder_text: TODO("not implemented") 9 | - offset: 1 10 | length: 596 11 | placeholder_text: // Implement additional functions and classes here if required 12 | - name: test/Tests.kt 13 | visible: true 14 | - name: task_template.md 15 | visible: false 16 | - name: solution.md 17 | visible: false 18 | - name: test/HiddenTests.kt 19 | visible: false 20 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Brute+Force+/+Generate+Binary+Strings -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Ones/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Count Ones 4 | 7 | 8 | Implement a function that allows one to get the number of 9 | 1's in a given binary string. 10 | 11 | ```Kotlin 12 | fun countOnes(seq: CharSequence): Int 13 | ``` 14 | 15 | 16 | ### Examples 17 | 18 |
19 | 20 | | Input | Returns | 21 | |--------------|---------| 22 | | `"001001"` | 2 | 23 | | `"11100101"` | 5 | 24 | 25 |
26 | 27 |
28 | A linear scan of the string is sufficient. 29 |
30 | 31 |
32 | <%include "solution.md" %> 33 |
-------------------------------------------------------------------------------- /Dynamic Programming/Longest Palindromic Subsequence/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Assertions.assertTrue 3 | import org.junit.jupiter.api.Test 4 | 5 | class Tests { 6 | @Test 7 | fun sample1() { 8 | assertEquals("madam", findLongestPalindromicSubsequence("bmczhadaem").toString()) 9 | } 10 | 11 | @Test 12 | fun sample2() { 13 | assertEquals("abacaba", findLongestPalindromicSubsequence("abacaba").toString()) 14 | } 15 | 16 | @Test 17 | fun sample3() { 18 | val res = findLongestPalindromicSubsequence("kotlin") 19 | assertEquals(1, res.length) 20 | assertTrue("kotlin".contains(res)) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /images/money_change_dp_3.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | $\myvar{table} \gets \text{associative array}$\\ 4 | 5 | \myproc{Change}(\myvar{money}):\\ 6 | if $\myvar{table}[\myvar{money}]$ is not yet computed:\\ 7 | \quad if $\myvar{money}=0$:\\ 8 | \quad\quad $\myvar{table}[\myvar{money}] \gets 0$\\ 9 | \quad else:\\ 10 | \quad\quad$\myvar{result} \gets +\infty$\\ 11 | \quad\quad for $c=1,3,4$:\\ 12 | \quad\quad\quad if $c \le \myvar{money}$:\\ 13 | \quad\quad\quad\quad $\myvar{result} \gets \min(\myvar{result}, 1+\myproc{Change}(\myvar{money}-c))$\\ 14 | \quad\quad $\myvar{table}[\myvar{money}] \gets \myvar{result}$\\ 15 | return $\myvar{table}[\myvar{money}]$ 16 | \end{pseudocode} 17 | }; -------------------------------------------------------------------------------- /Divide and Conquer/Guess a Number/src/Main.kt: -------------------------------------------------------------------------------- 1 | fun main() { 2 | val lower = 1 3 | val upper = 10 4 | guess(lower, upper) 5 | } 6 | 7 | fun guess(lower: Int, upper: Int) { 8 | val middle = (lower + upper) / 2 9 | val result = query(middle) 10 | if (result == '=') { 11 | return 12 | } else if (result == '<') { 13 | guess(lower, middle - 1) 14 | } else { 15 | guess(middle + 1, upper) 16 | } 17 | } 18 | 19 | val x = 4 // Change this value for testing 20 | fun query(y: Int): Char { 21 | val res = if (x == y) { 22 | '=' 23 | } else if (x < y) { 24 | '<' 25 | } else { 26 | '>' 27 | } 28 | println("Query: X = $y?, response: X $res $y") 29 | return res 30 | } 31 | -------------------------------------------------------------------------------- /Divide and Conquer/Points and Segments/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 90 7 | length: 855 8 | placeholder_text: |2 9 | return IntArray(points.size) { index -> 10 | val x = points[index] 11 | segments.count { x in it.first..it.second } 12 | } 13 | - name: test/Tests.kt 14 | visible: true 15 | - name: test/HiddenTests.kt 16 | visible: false 17 | - name: task_template.md 18 | visible: false 19 | - name: solution.md 20 | visible: false 21 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Divide+and+Conquer+/+Points+and+Segments -------------------------------------------------------------------------------- /Brute Force/Generate Derangements/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 903 7 | length: 42 8 | placeholder_text: TODO("not implemented yet") 9 | - offset: 1 10 | length: 842 11 | placeholder_text: // Write additional classes and functions here 12 | - name: test/Tests.kt 13 | visible: true 14 | - name: test/HiddenTests.kt 15 | visible: false 16 | - name: task_template.md 17 | visible: false 18 | - name: solution.md 19 | visible: false 20 | - name: src/Derangement.kt 21 | visible: true 22 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Brute+Force+/+Generate+Derangements -------------------------------------------------------------------------------- /Brute Force/Generate Derangements/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertTrue 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample1() { 7 | val actual = generateDerangements(2) 8 | val expected = listOf(intArrayOf(1, 0)).map { Derangement(it) } 9 | assertTrue(actual == expected) { 10 | "Expected $expected, found $actual" 11 | } 12 | } 13 | 14 | @Test 15 | fun sample2() { 16 | val actual = generateDerangements(3) 17 | val expected = listOf(intArrayOf(1, 2, 0), intArrayOf(2, 0, 1)).map { Derangement(it) } 18 | assertTrue(actual == expected) { 19 | "Expected $expected, found $actual" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Blocks of Ones with Updates/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample() { 7 | val sequence = "001001" 8 | val blocks = CountBlocksOfOnesWithUpdates(sequence) 9 | assertEquals(2, blocks.countOnes(), "countOnes($sequence)") 10 | assertEquals(2, blocks.countBlocksOfOnes(), "countBlocksOfOnes($sequence)") 11 | blocks.flip(3) 12 | assertEquals(3, blocks.countOnes()) 13 | assertEquals(2, blocks.countBlocksOfOnes()) 14 | blocks.flip(4) 15 | assertEquals(4, blocks.countOnes()) 16 | assertEquals(1, blocks.countBlocksOfOnes()) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Range Sum Queries/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/RangeSum.kt 4 | visible: true 5 | placeholders: 6 | - offset: 30 7 | length: 314 8 | placeholder_text: '// Implement additional fields and method here 9 | 10 | ' 11 | - offset: 391 12 | length: 45 13 | placeholder_text: ' TODO("not implemented")' 14 | - name: test/Tests.kt 15 | visible: true 16 | - name: task_template.md 17 | visible: false 18 | - name: solution.md 19 | visible: false 20 | - name: test/HiddenTests.kt 21 | visible: false 22 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Queries+and+incremental+updates+/+Range+Sum+Queries -------------------------------------------------------------------------------- /Warmup/Sum of Two Digits/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Sum of Two Digits 4 | 7 | 8 | Given two digits $0 \le a \le 9$ and $0 \le b \le 9$, 9 | compute their sum. 10 | 11 | ### Example 12 | 13 |
14 | 15 | | Input | Returns | 16 | |---------------|---------| 17 | | `9, 7` | `16` | 18 | 19 |
20 | 21 | We start from this ridiculously simple problem to show you the 22 | pipeline of reading the problem statement, designing an algorithm, 23 | implementing it, testing and debugging your program, and submitting 24 | it to the grading system. 25 | 26 |
27 | <%include "solution.md" %> 28 |
-------------------------------------------------------------------------------- /images/merge_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=125mm] { 2 | \begin{pseudocode} 3 | $\myproc{Merge}(\myvar{List}_1, \myvar{List}_2)$:\\ 4 | $\myvar{SortedList} \gets \text{empty list}$\\ 5 | while both $\myvar{List}_1$ and $\myvar{List}_2$ are non-empty:\\ 6 | \quad if the smallest element in $\myvar{List}_1$ is smaller than 7 | the smallest element in $\myvar{List}_2$:\\ 8 | \quad\quad move the smallest element from $\myvar{List}_1$ 9 | to the end of \myvar{SortedList}\\ 10 | \quad else:\\ 11 | \quad\quad move the smallest element from $\myvar{List}_2$ 12 | to the end of \myvar{SortedList}\\ 13 | move any remaining elements from either 14 | $\myvar{List}_1$ or $\myvar{List}_2$ to the end of \myvar{SortedList}\\ 15 | return \myvar{SortedList} 16 | \end{pseudocode} 17 | }; -------------------------------------------------------------------------------- /Dynamic Programming/Longest Palindromic Subsequence/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 0 7 | length: 1709 8 | placeholder_text: ' 9 | 10 | // Use additional functions and classes if required 11 | 12 | ' 13 | - offset: 1783 14 | length: 51 15 | placeholder_text: ' TODO("write your solution here")' 16 | - name: test/Tests.kt 17 | visible: true 18 | - name: task_template.md 19 | visible: false 20 | - name: solution.md 21 | visible: false 22 | - name: test/HiddenTests.kt 23 | visible: false 24 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Dynamic+Programming+/+Longest+Palindromic+Subsequence -------------------------------------------------------------------------------- /Dynamic Programming/Money Change Again/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Money Change Again 4 | 5 | 8 | 9 | Compute the minimum number of coins needed to change 10 | the given value into coins with denominations 1, 3, and 4. 11 | 12 | ### Input 13 | 14 | An `Int` ${money}$ — the value to change ($0 \le {money} \le 10^6$). 15 | 16 | ### Output 17 | 18 | Return an `Int` representing the minimum number of coins. 19 | 20 |
21 | 22 | | Input | Return value | 23 | |-------|--------------| 24 | | `15` | `4` | 25 | | `26` | `7` | 26 | 27 |
28 | 29 |
30 | <%include "solution.md" %> 31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | import kotlin.math.max 4 | import kotlin.random.Random 5 | 6 | class Tests { 7 | 8 | @Test 9 | fun sample1() { 10 | val a = intArrayOf(1, 2, 3) 11 | val correct = 6 12 | val result = maximumPairwiseProduct(a) 13 | assertEquals(correct, result, "maximumPairwiseProduct(${a.contentToString()})") 14 | } 15 | 16 | @Test 17 | fun sample2() { 18 | val a = intArrayOf(7, 5, 14, 2, 8, 8, 10, 1, 2, 3) 19 | val correct = 140 20 | val result = maximumPairwiseProduct(a) 21 | assertEquals(correct, result, "maximumPairwiseProduct(${a.contentToString()})") 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /Divide and Conquer/Median in Two Sorted Lists/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | fun > getMedian(first: List, second: List): T { 3 | assert(first.size == second.size) 4 | var left = -1 5 | var right = first.size 6 | val k = first.size 7 | while (left < right - 1) { 8 | val mid = (left + right) shr 1 9 | if (first[mid] < second[k - mid - 1]) { 10 | left = mid 11 | } else { 12 | right = mid 13 | } 14 | } 15 | return if (left == -1) { // first[0] > second[k - 1] => all second < first 16 | second[k - 1] 17 | } else if (right == first.size) { // first[k - 1] < second[0] => all second > first 18 | first[k - 1] 19 | } else { 20 | maxOf(first[left], second[k - right - 1]) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Greedy Algorithms/Minimum Unchangeable Amount/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | 6 | @Test 7 | fun testSample1() { 8 | checkSample(16, intArrayOf(1, 2, 3, 4, 5), "First sample") 9 | } 10 | 11 | @Test 12 | fun testSample2() { 13 | checkSample(3, intArrayOf(1, 1), "Second sample") 14 | } 15 | 16 | @Test 17 | fun testSample3() { 18 | checkSample(4, intArrayOf(100, 1, 2), "Third sample") 19 | } 20 | 21 | private fun checkSample(expected: Long, v: IntArray, message: String) { 22 | assertEquals( 23 | expected, 24 | findMinimumChange(v), 25 | "$message ${v.contentToString()}", 26 | ) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Divide and Conquer/Median in Two Sorted Lists/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 73 7 | length: 582 8 | placeholder_text: |2 9 | assert(first.size == second.size) 10 | return (first.asSequence() + second.asSequence()) 11 | .sorted() 12 | .drop(first.size - 1) 13 | .first() 14 | - name: test/Tests.kt 15 | visible: true 16 | - name: task_template.md 17 | visible: false 18 | - name: solution.md 19 | visible: false 20 | - name: test/HiddenTests.kt 21 | visible: false 22 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Divide+and+Conquer+/+Median+in+two+sorted+lists -------------------------------------------------------------------------------- /images/max_pairwise_product_5.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | \begin{pseudocode} 3 | $\myproc{StressTest}(N, M)$:\\ 4 | while true:\\ 5 | \quad $n \gets \text{random integer between 2 and $N$}$\\ 6 | %\null\quad print($n$)\\ 7 | \quad allocate array $A[1 \dotsc n]$\\ 8 | \quad for $i$ from $1$ to~$n$:\\ 9 | \quad\quad $A[i] \gets \text{random integer between 0 and $M$}$\\ 10 | \quad print($A[1 \dotsc n]$)\\ 11 | \quad $\myvar{result}_1 \gets \myproc{MaxPairwiseProductNaive}(A)$\\ 12 | \quad $\myvar{result}_2 \gets \myproc{MaxPairwiseProductFast}(A)$\\ 13 | \quad if $\myvar{result}_1 = \myvar{result}_2$:\\ 14 | \quad\quad print(``OK'')\\ 15 | \quad else:\\ 16 | \quad\quad print(``Wrong answer:'', \myvar{result}$_1$, \myvar{result}$_2$)\\ 17 | \quad\quad return 18 | \end{pseudocode} 19 | }; -------------------------------------------------------------------------------- /images/palindromic_3.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm] { 2 | \begin{pseudocode} 3 | $\myproc{LPS}(s)$:\\ 4 | $n \gets \text{length of $s$}$\\ 5 | $\myvar{table} \gets \text{$(n+1) \times (n+1)$ array}$ 6 | 7 | for $i$ from $0$ to $n-1$:\\ 8 | \quad $\myvar{table}[i,i] \gets 0$\\ 9 | \quad if $i < n-1$:\\ 10 | \quad\quad $\myvar{table}[i,i+1] \gets 1$\\ 11 | 12 | for $\myvar{size}$ from $2$ to $n$:\\ 13 | \quad for $i$ from $0$ to $n-\myvar{size}$:\\ 14 | \quad\quad $j \gets i + \myvar{size}$\\ 15 | \quad\quad if $s[i]=s[j-1]$:\\ 16 | \quad\quad\quad $\myvar{table}[i,j] \gets \myvar{table}[i+1, j-1]+2$\\ 17 | \quad\quad else:\\ 18 | \quad\quad\quad $\myvar{table}[i,j] \gets \max(\myvar{table}[i+1, j], \myvar{table}[i, j-1])$\\ 19 | 20 | return $\myvar{table}[0,n]$ 21 | \end{pseudocode} 22 | }; -------------------------------------------------------------------------------- /Brute Force/Generate Binary Strings/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | private class BinaryStringGenerator(private val length: Int) { 3 | private val currentString = CharArray(length) 4 | private val allStrings = mutableListOf() 5 | 6 | private fun doGenerate(index: Int) { 7 | if (index == length) { 8 | allStrings.add(String(currentString)) 9 | return 10 | } 11 | currentString[index] = '0' 12 | doGenerate(index + 1) 13 | currentString[index] = '1' 14 | doGenerate(index + 1) 15 | } 16 | 17 | fun generate(): List { 18 | if (allStrings.isEmpty()) { 19 | doGenerate(0) 20 | } 21 | return allStrings 22 | } 23 | } 24 | 25 | fun generateBinaryStrings(length: Int): List { 26 | return BinaryStringGenerator(length).generate() 27 | } 28 | -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product — Fixing the Time Limit Issue/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 48 7 | length: 290 8 | placeholder_text: |2 9 | val len = a.size 10 | var res = Long.MIN_VALUE 11 | for (i in 0 until len) { 12 | for (j in i + 1 until len) { 13 | res = kotlin.math.max(res, a[i].toLong() * a[j]) 14 | } 15 | } 16 | return res 17 | - name: test/Tests.kt 18 | visible: true 19 | - name: task_template.md 20 | visible: false 21 | - name: test/HiddenTests.kt 22 | visible: false 23 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Warmup+/+Maximum+pairwise+product+fixing+time+limit+issue -------------------------------------------------------------------------------- /util/common.css: -------------------------------------------------------------------------------- 1 | .samples th, .samples td { 2 | border: 1px solid black; 3 | border-collapse: collapse; 4 | padding: 15px; 5 | width: 300px; 6 | /*max-width: 100%;*/ 7 | /*text-align: center;*/ 8 | /*alignment: center;*/ 9 | } 10 | 11 | .sample th, .sample td { 12 | border: 1px solid black; 13 | padding: 15px; 14 | width: 300px; 15 | /*max-width: 100%;*/ 16 | /*text-align: center;*/ 17 | /*alignment: center;*/ 18 | } 19 | 20 | .sample td { 21 | border-top: none; 22 | border-bottom: none; 23 | } 24 | 25 | .sample table { 26 | border-collapse: collapse; 27 | border: 1px solid black; 28 | } 29 | 30 | .logo { 31 | display: flex; 32 | justify-content: center; 33 | } 34 | 35 | .logo img { 36 | width: 200px; 37 | align: center; 38 | } 39 | 40 | .code span { 41 | line-height: 22px; 42 | } -------------------------------------------------------------------------------- /images/inversions_2.tex: -------------------------------------------------------------------------------- 1 | \node[text width=110mm] { 2 | \begin{pseudocode} 3 | $\myproc{Merge}(\myvar{LeftHalf}, \myvar{RightHalf})$:\\ 4 | $\myvar{SortedList} \gets \text{empty list}$\\ 5 | $\myvar{inversions} \gets 0$\\ 6 | while both $\myvar{LeftHalf}$ and $\myvar{RightHalf}$ are non-empty:\\ 7 | \quad $l \gets \text{the first element of \myvar{LeftHalf}}$\\ 8 | \quad $r \gets \text{the first element of \myvar{RightHalf}}$\\ 9 | \quad if $l \le r$:\\ 10 | \quad\quad move~$l$ from $\myvar{LeftHalf}$ to \myvar{SortedList}\\ 11 | \quad else:\\ 12 | \quad\quad move~$r$ from $\myvar{RightHalf}$ to \myvar{SortedList}\\ 13 | \quad\quad $\myvar{inversions} \gets \myvar{inversions} + |\myvar{LeftHalf}|$\\ 14 | append \myvar{LeftHalf} and \myvar{RightHalf} to \myvar{SortedList}\\ 15 | return \myvar{SortedList}, \myvar{inversions} 16 | \end{pseudocode} 17 | }; -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Ones with Updates/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: test/Tests.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | - name: src/CountOnesWithUpdates.kt 8 | visible: true 9 | placeholders: 10 | - offset: 50 11 | length: 102 12 | placeholder_text: '// create required fields and methods here 13 | 14 | ' 15 | - offset: 181 16 | length: 19 17 | placeholder_text: ' TODO("not implemented")' 18 | - offset: 235 19 | length: 155 20 | placeholder_text: ' TODO("not implemented")' 21 | - name: test/HiddenTests.kt 22 | visible: false 23 | - name: solution.md 24 | visible: false 25 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Queries+and+incremental+updates+/+Count+Ones+with+Updates -------------------------------------------------------------------------------- /images/cover.tex: -------------------------------------------------------------------------------- 1 | \documentclass{standalone} 2 | \input{header} 3 | 4 | \colorlet{mc}{white!70!black} % main color 5 | \colorlet{hc}{yellow} % highlight color 6 | %\colorlet{mc}{black} % main color 7 | %\colorlet{hc}{red!90!black} % highlight color 8 | 9 | \begin{document} 10 | \begin{tikzpicture} 11 | \filldraw[fill=black] (0, 0) rectangle (2048/20, 1152/20); 12 | \node[inner sep=0mm, text width=2600, draw=red, align=center] at (2048/40, 1152/40) { 13 | \tikz{\input{count_ones_logo}}% 14 | \tikz{\input{count_ones_with_updates_logo}}% 15 | \tikz{\input{count_blocks_of_ones_logo}}% 16 | \tikz{\input{count_blocks_of_ones_with_updates_logo}}% 17 | \tikz{\input{opposite_values_logo}}% 18 | \tikz{\input{unchangeable_amount_logo}}% 19 | \tikz{\input{distinct_summands_logo}}% 20 | \tikz{\input{binary_strings_logo}}% 21 | }; 22 | \end{tikzpicture} 23 | \end{document} -------------------------------------------------------------------------------- /Dynamic Programming/Maximum Amount of Gold/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 78 7 | length: 356 8 | placeholder_text: |2 9 | weights.sortDescending() 10 | var capacityLeft = backpackCapacity 11 | for (w in weights) { 12 | if (capacityLeft >= w) { 13 | capacityLeft -= w 14 | } 15 | } 16 | return backpackCapacity - capacityLeft 17 | - name: test/Tests.kt 18 | visible: true 19 | - name: test/HiddenTests.kt 20 | visible: false 21 | - name: solution.md 22 | visible: false 23 | - name: task_template.md 24 | visible: false 25 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Dynamic+Programming+/+Maximum+Amount+of+Gold -------------------------------------------------------------------------------- /util/src/TestUtil.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.assertTimeoutPreemptively 2 | import kotlin.time.Duration 3 | import kotlin.time.toJavaDuration 4 | 5 | fun runTimeout(limit: Duration, body: () -> R) = runTimeout(limit, { "" }, body) 6 | 7 | fun runTimeout(limit: Duration, message: String, body: () -> R) = runTimeout(limit, { message }, body) 8 | 9 | fun runTimeout(limit: Duration, message: () -> String, body: () -> R) = 10 | assertTimeoutPreemptively(limit.toJavaDuration(), message, body) 11 | 12 | fun runIfTimeout(withTimeout: Boolean, limit: Duration, message: String, body: () -> R) = when (withTimeout) { 13 | true -> runTimeout(limit, message, body) 14 | else -> body() 15 | } 16 | 17 | fun runIfTimeout(withTimeout: Boolean, limit: Duration, body: () -> R) = when (withTimeout) { 18 | true -> runTimeout(limit, body) 19 | else -> body() 20 | } 21 | -------------------------------------------------------------------------------- /Brute Force/Generate Binary Strings/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Generate Binary Strings 4 | 5 | 8 | 9 | Given an integer $n$, generate all binary (consisting of `'0'` and `'1'`) 10 | strings of length $n$. 11 | The strings should be lexicographically ordered. 12 | 13 | ### Input 14 | 15 | Given an `Int` $n$ — the length of strings ($0 \le n \le 20$). 16 | 17 | ### Output 18 | 19 | Return a `List` that contains the required binary strings. 20 | The list should be lexicographically ordered. 21 | 22 | ### Example 23 | 24 | 25 |
26 | 27 | | Input | Returns | 28 | |-------|----------------------------| 29 | | `2` | `["00", "01", "10", "11"]` | 30 | 31 |
32 | 33 |
34 | <%include "solution.md" %> 35 |
36 | -------------------------------------------------------------------------------- /Dynamic Programming/Minimum Sum Path/solution.md: -------------------------------------------------------------------------------- 1 | 2 | # Solution 3 | 4 | The character can reach point $i$ either from point $i-1$ or 5 | from point $i-2$ (if he reached it from point $i-3$). This 6 | motivates introducing the following functions. For $0 \le i R$. We can use the same function `lowerBound` to find it 15 | in $O(\log n)$ time. The easiest way is to see that since the element are integers, 16 | $a[r] > R$ is the same as $a[r] \ge R+1$, so we can make `r = lowerBound(a, R + 1)`. 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Greedy Algorithms/Minimum Unchangeable Amount/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Minimum Unchangeable Amount 4 | 7 | 8 | Given $n$ coins of denominations $c_1 \le c_2 \le \dotsb \le c_n$, 9 | find the minimum amount that cannot be changed using these coins. 10 | 11 |
12 | 13 | | Input | Return value | 14 | |-----------------|--------------| 15 | | `[1, 2, 4, 10]` | 8 | 16 | | `[1, 1]` | 3 | 17 | | `[1, 2, 10]` | 4 | 18 | 19 |
20 | 21 |
22 | What can you say about $c_1$ if the smallest unchangeable amount is $1$? 23 |
24 | 25 |
26 | What can you say about $c_1, c_2$ if the smallest unchangeable amount is $2$? 27 |
28 | 29 |
30 | <%include "solution.md" %> 31 |
-------------------------------------------------------------------------------- /Divide and Conquer/Opposite Values/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Find two adjacent elements with opposite values 4 | 5 | 8 | 9 | Given a binary sequence that starts with zero and ends with one, 10 | find any occurrence of zero that is followed by one. 11 | 12 | In [Task.kt](course://Divide and Conquer/Opposite Values/src/Task.kt), you already have a slow solution implemented using a standard library function. 13 | Make it work faster to pass the tests. 14 | 15 |
16 | 17 | | Input | Return value | 18 | |----------|--------------| 19 | | `000101` | 2 | 20 | | `000101` | 4 | 21 | | `000111` | 2 | 22 | 23 |
24 | 25 | 26 |
27 | Use binary search. 28 |
29 | 30 | 31 |
32 | <%include "solution.md" %> 33 |
34 | -------------------------------------------------------------------------------- /Brute Force/Generate Subsets/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | import java.util.BitSet 4 | 5 | class Tests { 6 | 7 | companion object { 8 | private fun createBitSet(vararg args: Int): BitSet { 9 | val result = BitSet() 10 | args.forEach { result.set(it) } 11 | return result 12 | } 13 | } 14 | 15 | @Test 16 | fun sample1() { 17 | val actual = generateSubsets(2, 1) 18 | val expected = listOf(createBitSet(0), createBitSet(1)) 19 | assertEquals(actual, expected) 20 | } 21 | 22 | @Test 23 | fun sample2() { 24 | val actual = generateSubsets(3, 2) 25 | val expected = listOf( 26 | createBitSet(0, 1), 27 | createBitSet(0, 2), 28 | createBitSet(1, 2) 29 | ) 30 | assertEquals(actual, expected) 31 | } 32 | } -------------------------------------------------------------------------------- /Dynamic Programming/Maximum Amount of Gold/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Maximum Amount of Gold 4 | 5 | Given a set of gold bars of various weights and a backpack that can hold at most $\mathit{capacity}$ pounds, place 6 | as much gold as possible into the backpack. 7 | 8 | ```Kotlin 9 | fun findMaximumAmountOfGold(capacity: Int, w: IntArray): Int 10 | ``` 11 | 12 | ### Input 13 | 14 | An `Int` $\mathit{capacity}$ — the backpack capacity, 15 | and an `IntArray` $w$ — a set of $n$ gold bars of integer weights $w_1, \ldots, w_n$. 16 | 17 | ### Output 18 | 19 | An `Int` — the maximum total weight of gold bars that fit into a backpack of capacity $W$. 20 | 21 | 22 |
23 | 24 | | Input | Return value | 25 | |-------------------|--------------| 26 | | `10` `[1, 4, 8]` | `9` | 27 | 28 |
29 | 30 |
31 | <%include "solution.md" %> 32 |
33 | -------------------------------------------------------------------------------- /Brute Force/Generate Binary Strings/test/HiddenTests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions 2 | import org.junit.jupiter.api.Test 3 | import kotlin.time.Duration.Companion.seconds 4 | 5 | class HiddenTests { 6 | @Test 7 | fun testAllUpTo20() { 8 | for (n in 0..20) { 9 | testSingle(n) 10 | } 11 | } 12 | 13 | private fun testSingle(n: Int) { 14 | val actual = runTimeout(1.seconds, "n = $n") { 15 | generateBinaryStrings(n) 16 | } 17 | val expected = (0 until (1 shl n)).map { 18 | convertToBinary(n, it) 19 | } 20 | Assertions.assertTrue(actual == expected) { 21 | "Wrong answer for n = $n" 22 | } 23 | } 24 | 25 | private fun convertToBinary(n: Int, x: Int): String { 26 | return when (n) { 27 | 0 -> "" 28 | else -> x.toString(2).padStart(n, '0') 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Dynamic Programming/Primitive Calculator/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Assertions.assertTrue 3 | import org.junit.jupiter.api.Test 4 | 5 | class Tests { 6 | @Test 7 | fun sample1() { 8 | val expectedLength = 1 9 | val found = findMinimumOperations(1) 10 | assertEquals(expectedLength, found.size) 11 | assertEquals(1, found[0]) 12 | } 13 | 14 | @Test 15 | fun sample2() { 16 | val expectedLength = 15 17 | val n = 96234 18 | val found = findMinimumOperations(n) 19 | assertEquals(expectedLength, found.size) 20 | assertTrue(found.first() == 1) 21 | assertTrue(found.last() == n) 22 | for (i in 1 until found.size) { 23 | val a = found[i - 1] 24 | val b = found[i] 25 | assertTrue(a + 1 == b || a * 2 == b || a * 3 == b) 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Divide and Conquer/Count in Range/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Count number of elements in given range 4 | 5 | Given a *sorted* array $a$, and numbers $L$ and $R$, 6 | count number of elements that satisfy $L \le a_i \le R$. 7 | 8 | In [Task.kt](course://Divide and Conquer/Count in Range/src/Task.kt), 9 | you already have a slow solution. 10 | Make it work faster to pass the tests. 11 | 12 |
13 | 14 | | Input | Return value | 15 | |---------------------------|--------------| 16 | | $(2, 3, 5, 8, 10)$, 3, 9 | 3 | 17 | | $(2, 3, 5, 8, 10)$, 1, 20 | 5 | 18 | | $(2, 3, 5, 8, 10)$, 6, 7 | 0 | 19 | 20 |
21 | 22 |
23 | The elements we are looking for form a segment. If we find the 24 | borders of this segment using binary search, we can find its length. 25 |
26 | 27 |
28 | <%include "solution.md" %> 29 |
30 | -------------------------------------------------------------------------------- /Greedy Algorithms/Money Change/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Money Change 4 | 5 | In this problem, you will implement a simple greedy algorithm used by 6 | cashiers all over the world. We assume that the cashier has an unlimited 7 | number of coins of each denomination. 8 | 9 | 12 | 13 | Compute the minimum number of coins needed to change 14 | the given value into coins with denominations 1, 5, and 10. 15 | 16 | ### Input 17 | 18 | An `Int` ${money}$ — the value to change ($0 \le {money} \le 10^3$). 19 | 20 | ### Output 21 | 22 | Return an `Int` representing the minimum number of coins. 23 | 24 |
25 | 26 | | Input | Return value | 27 | |-------|--------------| 28 | | `2` | `2` | 29 | | `28` | `6` | 30 | 31 |
32 | 33 |
34 | <%include "solution.md" %> 35 |
36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /images/collecting_signatures_1.tex: -------------------------------------------------------------------------------- 1 | \begin{scope}[scale=0.2] 2 | 3 | \draw[->] (0,0) -- (26,0); 4 | \draw[->] (0,-20) -- (26,-20); 5 | 6 | \foreach \f/\t/\h in {2/18/13, 5/10/12, 2/7/11, 21/23/10, 5/8/9, 13/15/8, 9/13/7, 9/21/6, 4/10/5, 8/11/4, 17/20/3, 8/17/2} { 7 | \draw[mc] (\f,\h) -- (\t,\h); 8 | \draw[mc] (\f,\h-20) -- (\t,\h-20); 9 | } 10 | 11 | \foreach \x/\n in {11/2, 14/3, 18/4, 22/5} { 12 | \draw[dashed] (\x,0) -- (\x,15); 13 | \node[draw=mc, fill=mc, circle, minimum size=1mm, inner sep=0mm] at (\x,0) {}; 14 | \draw[dashed] (\x,0-20) -- (\x,15-20); 15 | \node[draw=mc, fill=mc, circle, minimum size=1mm, inner sep=0mm] at (\x,-20) {}; 16 | } 17 | 18 | \draw[dashed] (6,0) -- (6,15); 19 | 20 | \node[draw=mc, fill=mc, circle, minimum size=1mm, inner sep=0mm,label=below:$x$] at (6,0) {}; 21 | \draw[dashed, hc] (7,0-20) -- (7,15-20); 22 | \node[draw=hc, fill=hc, circle, minimum size=1mm, inner sep=0mm,label=below:\textcolor{hc}{$r_m$}] at (7,-20) {}; 23 | \end{scope} -------------------------------------------------------------------------------- /images/covering_segments_1.tex: -------------------------------------------------------------------------------- 1 | \begin{scope}[scale=0.2] 2 | 3 | \draw[->] (0,0) -- (26,0); 4 | \draw[->] (0,-20) -- (26,-20); 5 | 6 | \foreach \f/\t/\h in {2/18/13, 5/10/12, 2/7/11, 21/23/10, 5/8/9, 13/15/8, 9/13/7, 9/21/6, 4/10/5, 8/11/4, 17/20/3, 8/17/2} { 7 | \draw[mc] (\f,\h) -- (\t,\h); 8 | \draw[mc] (\f,\h-20) -- (\t,\h-20); 9 | } 10 | 11 | \foreach \x/\n in {11/2, 14/3, 18/4, 22/5} { 12 | \draw[dashed] (\x,0) -- (\x,15); 13 | \node[draw=mc, fill=mc, circle, minimum size=1mm, inner sep=0mm] at (\x,0) {}; 14 | \draw[dashed] (\x,0-20) -- (\x,15-20); 15 | \node[draw=mc, fill=mc, circle, minimum size=1mm, inner sep=0mm] at (\x,-20) {}; 16 | } 17 | 18 | \draw[dashed] (6,0) -- (6,15); 19 | 20 | \node[draw=mc, fill=mc, circle, minimum size=1mm, inner sep=0mm,label=below:$x$] at (6,0) {}; 21 | \draw[dashed, hc] (7,0-20) -- (7,15-20); 22 | \node[draw=hc, fill=hc, circle, minimum size=1mm, inner sep=0mm,label=below:\textcolor{hc}{$r_m$}] at (7,-20) {}; 23 | \end{scope} -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product — Fixing the Integer Overflow Issue/task_template.md: -------------------------------------------------------------------------------- 1 | Now, assume that in the Maximum Pairwise Product problem, 2 | the integers $a_i$'s can be as large as $10^6$. 3 | In such a case, perhaps surprisingly, our previous 4 | solution does not work. You may want to check that 5 | by pressing the "Check" button. 6 | 7 | **Stop and think.** Do you see why the solution fails? 8 | 9 | The reason is that the `Int` type in Kotlin 10 | occupies 4 bytes and ranges from $2^{-31}$ to $2^{31}-1$, 11 | where 12 | $$2^{31}=2147483648 .$$ 13 | Thus, even though $a_i$'s fit into the `Int` type in this problem, 14 | the product of two $a_i$'s can be too large: say, if $a_1=a_2=10^6$, 15 | then 16 | $$a_1 \cdot a_2 = 10^{12}=1000000000000>2147483648.$$ 17 | 18 | To fix the solution, when computing the product of $a_i$ and 19 | $a_j$, store the result in the `Long` type: `a[i].toLong() * a[j]`. 20 | 21 | An important takeaway: make sure to always test your code for 22 | various boundary conditions. 23 | -------------------------------------------------------------------------------- /Dynamic Programming/Money Change Again/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: task_template.md 4 | visible: false 5 | - name: solution.md 6 | visible: false 7 | - name: src/Task.kt 8 | visible: true 9 | placeholders: 10 | - offset: 36 11 | length: 278 12 | placeholder_text: |2 13 | return when (money) { 14 | 0 -> 0 15 | 1 -> 1 16 | 2 -> 2 17 | 3 -> 1 18 | 4 -> 1 19 | else -> { 20 | minOf( 21 | changeMoney(money - 1), 22 | changeMoney(money - 3), 23 | changeMoney(money - 4) 24 | ) + 1 25 | } 26 | } 27 | - name: test/Tests.kt 28 | visible: true 29 | - name: test/HiddenTests.kt 30 | visible: false 31 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Dynamic+Programming+/+Money+Change+Again -------------------------------------------------------------------------------- /Queries and Incremental Updates/Range Sum Queries/solution.md: -------------------------------------------------------------------------------- 1 | 2 | ### Solution 3 | 4 | Start by computing all prefix sums, i.e., 5 | compute $\operatorname{range}(0,k)=a_0+\dotsb+a_{k-1}$ for all $0 \le k \le n$. 6 | This can be done in linear time (more precisely, in $n$ 7 | arithmetic operations), since the value of 8 | $\operatorname{range}(0,k+1)$ 9 | can be easily found from $\operatorname{range}(0,k)$: 10 | $$\operatorname{range}(0,k+1)=\operatorname{range}(0,k)+a_k.$$ 11 | 12 | Using these values, one can compute the value of 13 | $\operatorname{range}(l,r)$ in constant time, for any $0 \le l \le r \le n$. 14 | Indeed, combining the prefix range $(0,l)$ with the range $(l,r)$ 15 | gives the prefix range $(0,r)$. Thus, 16 | $$\operatorname{range}(l,r)=\operatorname{range}(0,r)-\operatorname{range}(0,l).$$ 17 | 18 | Overall, the resulting algorithm 19 | makes $n+q$ arithmetic operations: 20 | compute (and store) all prefix sum queries, 21 | then answer each of $q$ range sum queries with a single arithmetic 22 | operation. 23 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | import java.io.File 2 | 3 | rootProject.name = "algo-challenges-in-kotlin" 4 | 5 | 6 | pluginManagement { 7 | repositories { 8 | gradlePluginPortal() 9 | google() 10 | mavenCentral() 11 | } 12 | } 13 | 14 | fun sanitizeName(name: String): String { 15 | return name 16 | .replace("[ /\\\\:<>\"?*|()]".toRegex(), "_") 17 | .replace("(^[.]+)|([.]+\$)".toRegex(), "") 18 | } 19 | 20 | rootProject.projectDir.walkTopDown() 21 | .filter { isTaskDir(it) && !it.path.contains(".idea") } 22 | .forEach { dir -> 23 | val taskRelativePath = rootDir.toPath().relativize(dir.toPath()) 24 | val parts = taskRelativePath.map { sanitizeName(it.toString()) } 25 | val moduleName = parts.joinToString("-") 26 | include(moduleName) 27 | project(":$moduleName").projectDir = dir 28 | } 29 | 30 | fun isTaskDir(dir: File): Boolean { 31 | return !dir.absolutePath.contains("buildSrc") && File(dir, "src").exists() 32 | } 33 | 34 | include("util") 35 | -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product — Fixing the Time Limit Issue/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample1() { 7 | val a = intArrayOf(1, 2, 3) 8 | val correct = 6L 9 | val result = maximumPairwiseProduct(a) 10 | assertEquals(result, correct, "maximumPairwiseProduct(${a.contentToString()})") 11 | } 12 | 13 | @Test 14 | fun sample2() { 15 | val a = intArrayOf(7, 5, 14, 2, 8, 8, 10, 1, 2, 3) 16 | val correct = 140L 17 | val result = maximumPairwiseProduct(a) 18 | assertEquals(result, correct, "maximumPairwiseProduct(${a.contentToString()})") 19 | } 20 | 21 | @Test 22 | fun sample3() { 23 | val a = intArrayOf(1_000_000, 1_000_000) 24 | val correct = 1_000_000_000_000L 25 | val result = maximumPairwiseProduct(a) 26 | assertEquals(correct, result, "maximumPairwiseProduct(${a.contentToString()}") 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Brute Force/Generate Subsets/src/Task.kt: -------------------------------------------------------------------------------- 1 | import java.util.BitSet 2 | 3 | private class SubsetGenerator(private val size: Int, private val subSize: Int) { 4 | private val currentSubset = BitSet(size) 5 | private val allSubsets = mutableListOf() 6 | 7 | private fun doGenerate(index: Int, used: Int) { 8 | if (index == size) { 9 | allSubsets.add(currentSubset.clone() as BitSet) 10 | return 11 | } 12 | if (used < subSize) { 13 | currentSubset.set(index) 14 | doGenerate(index + 1, used + 1) 15 | currentSubset.set(index, false) 16 | } 17 | if (size - index > subSize - used) { 18 | doGenerate(index + 1, used) 19 | } 20 | } 21 | 22 | fun generate(): List { 23 | if (allSubsets.isEmpty()) { 24 | doGenerate(0, 0) 25 | } 26 | return allSubsets 27 | } 28 | } 29 | 30 | fun generateSubsets(n: Int, k: Int): List { 31 | return SubsetGenerator(n, k).generate() 32 | } 33 | -------------------------------------------------------------------------------- /Brute Force/Generate Subsets/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Generate Subsets 4 | 5 | 8 | 9 | Given integers $n$ and $k$, generate all subsets of 10 | the set $\lbrace 0, 1, 2, \dotsc, n - 1 \rbrace$ 11 | of size $k$. 12 | 13 | ### Input 14 | 15 | Given `Int`'s $n$ and $k$ — the sizes of the set and 16 | the subsets, respectively ($0 \le k \le n \le 200$). 17 | 18 | It is guaranteed that the size of the output (the number 19 | of subsets) 20 | does not exceed $10^6$. 21 | 22 | ### Output 23 | 24 | Return a `List` that contains the required subsets. 25 | The list should be lexicographically ordered. 26 | 27 | ### Example 28 | 29 |
30 | 31 | | Input | Returns | 32 | |-----------|----------------------------| 33 | | `2`, `1` | `[[0], [1]]` | 34 | | `3`, `2` | `[[0, 1], [0, 2], [1, 2]]` | 35 | 36 |
37 | 38 |
39 | <%include "solution.md" %> 40 |
41 | -------------------------------------------------------------------------------- /Brute Force/Generate Partitions/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | 3 | private class PartitionGenerator(private val n: Int) { 4 | private val currentPartition = mutableListOf() 5 | private val generated = mutableListOf() 6 | 7 | private fun recursiveGenerate(lastTerm: Int, sumLeft: Int) { 8 | if (sumLeft == 0) { 9 | generated.add(Partition(currentPartition.toList())) 10 | return 11 | } 12 | if (lastTerm > sumLeft) { 13 | return; 14 | } 15 | for (currentTerm in lastTerm..sumLeft) { 16 | currentPartition.add(currentTerm) 17 | recursiveGenerate(currentTerm, sumLeft - currentTerm) 18 | currentPartition.removeLast() 19 | } 20 | } 21 | 22 | fun generate(): List { 23 | if (generated.isEmpty()) { 24 | recursiveGenerate(1, n) 25 | } 26 | return generated 27 | } 28 | } 29 | 30 | fun generatePartitions(n: Int): List { 31 | return PartitionGenerator(n).generate() 32 | } 33 | -------------------------------------------------------------------------------- /Dynamic Programming/Primitive Calculator/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: src/Task.kt 4 | visible: true 5 | placeholders: 6 | - offset: 0 7 | length: 861 8 | placeholder_text: | 9 | fun findMinimumOperations(n: Int): List { 10 | var i = n 11 | val answer = mutableListOf() 12 | while (i > 1) { 13 | answer.add(i) 14 | i = when { 15 | i % 3 == 0 -> i / 3 16 | i % 2 == 0 -> i / 2 17 | else -> i - 1 18 | } 19 | } 20 | answer.add(1) 21 | answer.reverse() 22 | return answer 23 | } 24 | - name: test/Tests.kt 25 | visible: true 26 | - name: test/HiddenTests.kt 27 | visible: false 28 | - name: solution.md 29 | visible: false 30 | - name: task_template.md 31 | visible: false 32 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Dynamic+Programming+/+Primitive+Calculator -------------------------------------------------------------------------------- /Dynamic Programming/Primitive Calculator/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | private fun calculateDP(n: Int): IntArray { 3 | val minOp = IntArray(n + 1) 4 | minOp[0] = 0 5 | for (i in 1..n) { 6 | var current = minOp[i - 1] + 1 7 | for (div in 2..3) { 8 | if (i % div == 0) { 9 | current = minOf(current, minOp[i / div] + 1) 10 | } 11 | } 12 | minOp[i] = current 13 | } 14 | return minOp 15 | } 16 | 17 | private fun restoreAnswer(n: Int, minOp: IntArray): List { 18 | val answer = mutableListOf() 19 | var i = n 20 | while (i > 1) { 21 | answer.add(i) 22 | i = when { 23 | minOp[i] == minOp[i - 1] + 1 -> i - 1 24 | i % 2 == 0 && minOp[i] == minOp[i / 2] + 1 -> i / 2 25 | else -> i / 3 26 | } 27 | } 28 | answer.add(1) 29 | answer.reverse() 30 | return answer 31 | } 32 | 33 | fun findMinimumOperations(n: Int): List { 34 | val minOp = calculateDP(n) 35 | return restoreAnswer(n, minOp) 36 | } 37 | -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Blocks of Ones with Updates/task-info.yaml: -------------------------------------------------------------------------------- 1 | type: edu 2 | files: 3 | - name: test/Tests.kt 4 | visible: true 5 | - name: task_template.md 6 | visible: false 7 | - name: src/CountBlocksOfOnesWithUpdates.kt 8 | visible: true 9 | placeholders: 10 | - offset: 57 11 | length: 391 12 | placeholder_text: '// write required fields and methods here 13 | 14 | ' 15 | - offset: 476 16 | length: 19 17 | placeholder_text: ' TODO("not implemented")' 18 | - offset: 538 19 | length: 21 20 | placeholder_text: ' TODO("not implemented")' 21 | - offset: 594 22 | length: 590 23 | placeholder_text: ' TODO("not implemented")' 24 | - name: test/HiddenTests.kt 25 | visible: false 26 | - name: solution.md 27 | visible: false 28 | feedback_link: https://docs.google.com/forms/d/e/1FAIpQLSfxqHNk7ZtD9Br3NqgSlkdbaN6HuDWjJXvP3vFSIyFROZ6nYg/viewform?usp=pp_url&entry.2103429047=Queries+and+incremental+updates+/+Count+Blocks+of+Ones+with+updates -------------------------------------------------------------------------------- /Warmup/Maximum Pairwise Product — Fixing the Integer Overflow Issue/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | @Test 6 | fun sample1() { 7 | val a = intArrayOf(1, 2, 3) 8 | val correct = 6L 9 | val result = maximumPairwiseProduct(a).toLong() 10 | assertEquals(result, correct, "maximumPairwiseProduct(${a.contentToString()})") 11 | } 12 | 13 | @Test 14 | fun sample2() { 15 | val a = intArrayOf(7, 5, 14, 2, 8, 8, 10, 1, 2, 3) 16 | val correct = 140L 17 | val result = maximumPairwiseProduct(a).toLong() 18 | assertEquals(result, correct, "maximumPairwiseProduct(${a.contentToString()})") 19 | } 20 | 21 | @Test 22 | fun sample3() { 23 | val a = intArrayOf(1_000_000, 1_000_000) 24 | val correct = 1_000_000_000_000L 25 | val result = maximumPairwiseProduct(a).toLong() 26 | assertEquals(correct, result, "maximumPairwiseProduct(${a.contentToString()}") 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Divide and Conquer/Points and Segments/solution.md: -------------------------------------------------------------------------------- 1 | 2 | # Solution 3 | 4 | Let $\operatorname{before}(p)$ be the number of segments that end 5 | before a point $p$, $\operatorname{after}(p)$ be the number of 6 | segments that start after $p$, and $\operatorname{cover}(p)$ be 7 | the number of segments covering $p$. 8 | 9 | **Exercise break.** Prove that for each point $p$, 10 | $$\operatorname{before}(p)+\operatorname{after}(p)+\operatorname{cover}(p)$$ 11 | is equal to the total number of segments. 12 | 13 | Hence, to count the number of segments that do not cover the 14 | given point $p$, it is sufficient to count the number of right-ends of 15 | segments that are smaller than $p$ and the number of left-ends of 16 | segments that are greater than $p$. If all left-ends and right-ends 17 | are sorted, one can use the binary search algorithm to perform such a 18 | check in $O(\log m)$ time. The corresponding solution has running 19 | time $O(m\log m + n\log m)$. 20 | 21 | Source: 22 | [Ace Your Next Coding Interview by Learning Algorithms](https://bit.ly/acecogniterra) 23 | -------------------------------------------------------------------------------- /Divide and Conquer/Points and Segments/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | 3 | fun countSegmentsForEach(points: IntArray, segments: Array>): IntArray { 4 | val segmentsCnt = segments.size 5 | val start = segments.map { it.first }.sorted() 6 | val end = segments.map { it.second }.sorted() 7 | val pointsCnt = points.size 8 | val pointIndices = points.indices.sortedBy { points[it] } 9 | val answer = IntArray(pointsCnt) 10 | var endsBefore = 0 11 | var startsAfter = 0 12 | for (index in pointIndices) { 13 | val x = points[index] 14 | while (endsBefore < segmentsCnt && end[endsBefore] < x) { 15 | ++endsBefore 16 | } // end[endsBefore] >= x && end[endsBefore - 1] < x 17 | while (startsAfter < segmentsCnt && start[startsAfter] <= x) { 18 | ++startsAfter 19 | } // start[startsAfter] > x && start[startsAfter - 1] <= x 20 | val outside = endsBefore + (segmentsCnt - startsAfter) 21 | val inside = segmentsCnt - outside 22 | answer[index] = inside 23 | } 24 | return answer 25 | } 26 | -------------------------------------------------------------------------------- /Divide and Conquer/Points and Segments/test/Tests.kt: -------------------------------------------------------------------------------- 1 | import org.junit.jupiter.api.Assertions.assertArrayEquals 2 | import org.junit.jupiter.api.Test 3 | 4 | class Tests { 5 | 6 | @Test 7 | fun sample1() { 8 | val points = intArrayOf(1, 6, 11) 9 | val segments = arrayOf(0 to 5, 7 to 10) 10 | val expected = intArrayOf(1, 0, 0) 11 | val found = countSegmentsForEach(points, segments) 12 | assertArrayEquals(expected, found) 13 | } 14 | 15 | @Test 16 | fun sample2() { 17 | val points = intArrayOf(-100, 100, 0) 18 | val segments = arrayOf(-10 to 10) 19 | val expected = intArrayOf(0, 0, 1) 20 | val found = countSegmentsForEach(points, segments) 21 | assertArrayEquals(expected, found) 22 | } 23 | 24 | @Test 25 | fun sample3() { 26 | val points = intArrayOf(1, 6) 27 | val segments = arrayOf(0 to 5, -3 to 2, 7 to 10) 28 | val expected = intArrayOf(2, 0) 29 | val found = countSegmentsForEach(points, segments) 30 | assertArrayEquals(expected, found) 31 | } 32 | } -------------------------------------------------------------------------------- /Queries and Incremental Updates/Count Blocks of Ones/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Count Blocks of Ones 4 | 5 | 8 | 9 | Implement a function that computes the number of blocks of 1's in the binary string. 10 | 11 | ```Kotlin 12 | fun countBlocksOfOnes(s: CharSequence): Int 13 | ``` 14 | 15 | ### Input 16 | 17 | Given a `CharSequence` $s$ — the binary string consisting of `0`s and `1`s. The length doesn't exceed $10^6$. 18 | 19 | ### Output 20 | 21 | Return an `Int` representing the number of blocks in the binary string. 22 | 23 | ### Examples 24 | 25 |
26 | 27 | | Input | Returns | 28 | |---------------|---------| 29 | | `"001001"` | 2 | 30 | | `"11100101"` | 3 | 31 | 32 |
33 | 34 |
35 | Given an index $0 \le i < n$, how would you check whether it is a starting 36 | index of a block of ones in a binary string $s[0\dotsc n)$? 37 |
38 | 39 |
40 | <%include "solution.md" %> 41 |
42 | -------------------------------------------------------------------------------- /Brute Force/Generate Derangements/src/Task.kt: -------------------------------------------------------------------------------- 1 | 2 | private class DerangementsGenerator(private val length: Int) { 3 | private val currentDerangement = IntArray(length) 4 | private val allDerangements = mutableListOf() 5 | private val used = BooleanArray(length) 6 | 7 | private fun doGenerate(index: Int) { 8 | if (index == length) { 9 | allDerangements.add(Derangement(currentDerangement.clone())) 10 | return 11 | } 12 | for (value in 0 until length) { 13 | if (value == index || used[value]) { 14 | continue 15 | } 16 | used[value] = true 17 | currentDerangement[index] = value 18 | doGenerate(index + 1) 19 | used[value] = false 20 | } 21 | } 22 | 23 | fun generate(): List { 24 | if (allDerangements.isEmpty()) { 25 | doGenerate(0) 26 | } 27 | return allDerangements 28 | } 29 | } 30 | 31 | fun generateDerangements(n: Int): List { 32 | return DerangementsGenerator(n).generate() 33 | } -------------------------------------------------------------------------------- /Brute Force/Generate Subsets/solution.md: -------------------------------------------------------------------------------- 1 | 2 | ### Solution 3 | 4 | Recall that the resulting list needs to be sorted. This suggests 5 | the following idea. First, generate all subsets of size $k$ 6 | containing 0. To do 7 | this, generate recursively all subsets of size $k-1$ of the set 8 | $\lbrace 1, \dotsc, n-1 \rbrace$ and add $0$ to each of them. 9 | Then, generate all subsets of size $k$ that do not contain $0$. 10 | To do this, generate recursively all subsets of size $k-1$ 11 | of the set $\lbrace 1, \dotsc, n-1 \rbrace$. 12 | To implement this recursive procedure, we pass to each recursive call 13 | not only the parameters $n$ (the size of the universe set) 14 | and $k$ (the size of subsets), but also an additional parameter $m$, 15 | the minimum value of subsets to be generated. Thus, given $n$, $k$, 16 | and $m$, the procedure generates all subsets of size $k$ 17 | of the set $\lbrace m, m+1, \dotsc, n-1\rbrace$. If the number of 18 | elements in this set, $n-m$, is smaller than $k$ (the base case of 19 | recursion), the resulting list is empty. 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /images/edit_distance_4.tex: -------------------------------------------------------------------------------- 1 | \node[text width=100mm]{ 2 | $\myvar{table} \gets \text{associative array}$\\[2mm] 3 | $\myproc{EditDistance}(A, B, i, j)$:\\ 4 | if $\operatorname{table}[i, j]$ is not yet computed:\\ 5 | \quad if $i=0$ or $j=0$:\\ 6 | \quad\quad $\myvar{table}[i, j] \gets \max(i, j)$\\ 7 | \quad else:\\ 8 | \quad\quad \textcolor{two}{$\myvar{insertion} \gets \myproc{EditDistance}(A, B, i, j-1)+1$}\\ 9 | \quad\quad \textcolor{one}{$\myvar{deletion} \gets \myproc{EditDistance}(A, B, i-1, j)+1$}\\ 10 | \quad\quad \textcolor{three}{$\myvar{match} \gets \myproc{EditDistance}(A, B, i-1, j-1)$}\\ 11 | \quad\quad \textcolor{four}{$\myvar{mismatch} \gets \myproc{EditDistance}(A, B, i-1, j-1)+1$}\\ 12 | \quad\quad if $A[i]=B[j]$:\\ 13 | \quad\quad\quad $\myvar{table}(i,j) \gets \min(\textcolor{two}{\myvar{insertion}}, \textcolor{one}{\myvar{deletion}}, \textcolor{three}{\myvar{match}})$\\ 14 | \quad\quad else:\\ 15 | \quad\quad\quad $\myvar{table}(i,j) \gets \min(\textcolor{two}{\myvar{insertion}}, \textcolor{one}{\myvar{deletion}}, \textcolor{four}{\myvar{mismatch}})$\\ 16 | return $\myvar{table}(i,j)$ 17 | }; -------------------------------------------------------------------------------- /Brute Force/Generate Derangements/task_template.md: -------------------------------------------------------------------------------- 1 | <%css "/util/common.css" %> 2 | 3 | # Generate Derangements 4 | 5 | 8 | 9 | Given an integer $n$, generate all permutations 10 | (of the set $\lbrace 0, 1, \dotsc, n-1\rbrace$) 11 | without fixed points, that is, all permutations 12 | $(p_0, \dotsc, p_{n-1})$ such that $p_i \neq i$ 13 | for all $0 \le i < n$. 14 | 15 | ### Input 16 | 17 | Given an `Int` $n$ — the length of a permutation ($0 \le n \le 10$). 18 | 19 | ### Output 20 | 21 | Return a `List` that contains the required permutations. 22 | The list should be lexicographically ordered. 23 | 24 | ### Example 25 | 26 | 27 |
28 | 29 | | Input | Returns | 30 | |-------|--------------------------| 31 | | `2` | `[[1, 0]]` | 32 | | `3` | `[[1, 2, 0], [2, 0, 1]]` | 33 | 34 |
35 | 36 |
37 | Let $n=5$. How would you generate all derangements that start with 38 | $4, 0$? 39 |
40 | 41 |
42 | <%include "solution.md" %> 43 |
44 | -------------------------------------------------------------------------------- /Brute Force/Introduction/task_template.md: -------------------------------------------------------------------------------- 1 | In this module, we'll practice implementing brute-force solutions. To find an object satisfying a particular property, a brute-force algorithm simply enumerates all possible objects. In many cases, such an algorithm is too slow. Still, there are situations when a brute-force solution is needed. 2 | 3 | * Say, you need to find a permutation of five objects with some property. Since the input size in this case is small, it is perfectly fine to enumerate all permutations. 4 | 5 | * When implementing an efficient algorithm, it is desirable to have a baseline algorithm that is correct even if slow. Such an algorithm can be used to test your efficient solution: to do that, you generate tests of small size and compare the results of two solutions. A brute-force algorithm is a perfect candidate for such a baseline solution. 6 | 7 | * There are computational problems for which a brute-force algorithm is the best solution we have. 8 | 9 | * Finally, dynamic programming, an extremely popular algorithmic technique, which we will cover later in this course, can be viewed as an optimized brute-force method. 10 | 11 | -------------------------------------------------------------------------------- /Greedy Algorithms/Distinct Summands/solution.md: -------------------------------------------------------------------------------- 1 | 2 | ### Solution 3 | 4 | It is not difficult to see that one cannot represent 8 as the sum of four 5 | positive distinct integers. 6 | Indeed, assume that $8=a_1+a_2+a_3+a_4$ and $a_1