├── .DS_Store ├── 02.Notes ├── .DS_Store ├── 01.From Problem Description to Python Program Example │ ├── From Problem Description to Python Program Example.pdf │ ├── example.py │ ├── example2.py │ └── example3.py ├── 02.Turing machines │ ├── Turing machines.ipynb │ ├── Turing machines.pdf │ ├── addition.txt │ ├── division_by_2.txt │ ├── multiplication.txt │ ├── parity.txt │ ├── readme.md │ ├── successor.txt │ └── turing_machine_simulator.py ├── 03.The Monty Hall problem │ ├── The Monty Hall problem.ipynb │ ├── The Monty Hall problem.pdf │ ├── monty_hall.py │ └── readme.md ├── 04.From decimal expansions to reduced fractions │ ├── From decimal expansions to reduced fractions.ipynb │ ├── From decimal expansions to reduced fractions.pdf │ ├── rational_number.py │ └── readme.md ├── 05.Eratosthenes sieve │ ├── Eratosthenes_sieve.ipynb │ ├── Eratosthenes_sieve.pdf │ ├── readme.md │ ├── v1 │ │ ├── eratosthenes_sieve_v1.py │ │ └── input_output.py │ └── v2 │ │ ├── eratosthenes_sieve_v2.py │ │ └── input_output.py ├── 06.Euler sieve │ ├── Euler_sieve.ipynb │ ├── Euler_sieve.pdf │ ├── readme.md │ ├── v1 │ │ ├── euler_sieve_v1.py │ │ └── input_output.py │ └── v2 │ │ ├── euler_sieve_v2.py │ │ └── input_output.py ├── 07.Card shuffling │ ├── Card shuffling.pdf │ ├── Card_shuffling.ipynb │ ├── Cards │ │ ├── 1.gif │ │ ├── 10.gif │ │ ├── 11.gif │ │ ├── 12.gif │ │ ├── 13.gif │ │ ├── 14.gif │ │ ├── 15.gif │ │ ├── 16.gif │ │ ├── 17.gif │ │ ├── 18.gif │ │ ├── 19.gif │ │ ├── 2.gif │ │ ├── 20.gif │ │ ├── 21.gif │ │ ├── 22.gif │ │ ├── 23.gif │ │ ├── 24.gif │ │ ├── 25.gif │ │ ├── 26.gif │ │ ├── 27.gif │ │ ├── 28.gif │ │ ├── 29.gif │ │ ├── 3.gif │ │ ├── 30.gif │ │ ├── 31.gif │ │ ├── 32.gif │ │ ├── 33.gif │ │ ├── 34.gif │ │ ├── 35.gif │ │ ├── 36.gif │ │ ├── 37.gif │ │ ├── 38.gif │ │ ├── 39.gif │ │ ├── 4.gif │ │ ├── 40.gif │ │ ├── 41.gif │ │ ├── 42.gif │ │ ├── 43.gif │ │ ├── 44.gif │ │ ├── 45.gif │ │ ├── 46.gif │ │ ├── 47.gif │ │ ├── 48.gif │ │ ├── 49.gif │ │ ├── 5.gif │ │ ├── 50.gif │ │ ├── 51.gif │ │ ├── 52.gif │ │ ├── 6.gif │ │ ├── 7.gif │ │ ├── 8.gif │ │ └── 9.gif │ ├── card_shuffling.py │ └── readme.md ├── 08.US Social Security data on given names │ ├── US Social Security data on given names.pdf │ ├── names.zip │ ├── names_per_gender.py │ ├── names_revivals.py │ └── readme.md ├── 09.The tower and marbles puzzle │ ├── The tower and marbles puzzle.pdf │ ├── The_tower_and_marbles_puzzle.ipynb │ ├── readme.md │ ├── tower_and_2_marbles.py │ └── tower_and_m_marbles.py ├── 10.K-means clustering │ ├── k-means clustering.pdf │ ├── k-means_clustering.ipynb │ ├── k_means_clustering.py │ └── readme.md ├── 11.The game of life │ ├── The game of life.pdf │ ├── The_game_of_life.ipynb │ ├── b3_s23_movie.py │ ├── game_of_life.py │ ├── gosperglidergun.mp4 │ ├── gosperglidergun.rle │ └── readme.md ├── 12.The Fibonacci sequence │ ├── The Fibonacci sequence.ipynb │ ├── The Fibonacci sequence.pdf │ ├── add2numbers.py │ ├── factorial.py │ ├── fib_vs_fibi_runit.py │ ├── fibm_vs_fibi_runit.py │ ├── fibonacci.py │ ├── mult4rec.py │ └── readme.md ├── 13.The towers of Hanoi │ ├── The towers of Hanoi.pdf │ ├── The_towers_of_Hanoi.ipynb │ ├── iterative_hanoi.py │ ├── readme.md │ └── recursive_hanoi.py ├── 14.Quadratic equations │ ├── Quadratic equations.pdf │ ├── Quadratic_equations.ipynb │ ├── quadratic_equation_v1.py │ ├── quadratic_equation_v2.py │ ├── quadratic_equation_v3.py │ ├── quadratic_equation_v4.py │ └── quadratic_equation_v5.py ├── 15.Levenshtein distance │ ├── Levenshtein distance.ipynb │ ├── Levenshtein distance.pdf │ ├── levenshtein_distance.py │ └── readme.md ├── 16.Context free grammars │ ├── Context free grammars.ipynb │ ├── Context free grammars.pdf │ ├── context_free_grammar.py │ └── readme.md ├── 17.Loans and savings │ ├── Loans and savings.ipynb │ ├── Loans and savings.pdf │ ├── loans_and_savings.py │ └── readme.md ├── 18.Three special perfect squares │ ├── Three special perfect squares.ipynb │ ├── Three special perfect squares.pdf │ ├── readme.md │ ├── three_special_perfect_squares_v1.py │ ├── three_special_perfect_squares_v2.py │ └── three_special_perfect_squares_v3.py ├── 19.Searching and Sorting │ ├── batcher_sort.py │ ├── binary_search.py │ ├── binary_search_recursive.py │ ├── bubble_sort.py │ ├── heap_sort.py │ ├── insertion_sort.py │ ├── linear_search.py │ ├── merge_sort.py │ ├── quick_sort.py │ ├── readme.md │ ├── selection_sort.py │ ├── shell_sort.py │ └── sorting.py ├── 20.Elementary cellular automata │ ├── Elementary cellular automata.ipynb │ ├── Elementary cellular automata.pdf │ ├── elementary_cellular_automata.py │ └── readme.md ├── 21.The Babylonian method for computing square roots │ ├── The Babylonian method for computing square roots.ipynb │ ├── The Babylonian method for computing square roots.pdf │ ├── readme.md │ └── sqrt_approximation.py ├── 22.ASCII art │ ├── ASCII art.ipynb │ ├── ASCII art.pdf │ ├── Illustrations.zip │ ├── Illustrations │ │ ├── 10_as_block_size_35_32_as_character_ramp.pdf │ │ └── 3_as_block_size_64_37_35_42_43_61_45_58_46_32_as_character_ramp.pdf │ ├── ascii_art.py │ ├── mona_lisa.jpeg │ ├── mona_lisa_10_as_block_size_35_32_as_character_ramp.pdf │ ├── mona_lisa_10_as_block_size_35_32_as_character_ramp.tex │ ├── mona_lisa_3_as_block_size_64_37_35_42_43_61_45_58_46_32_as_character_ramp.pdf │ └── mona_lisa_3_as_block_size_64_37_35_42_43_61_45_58_46_32_as_character_ramp.tex ├── 23.The Vigenere cipher │ ├── The Vigenere cipher.ipynb │ ├── The Vigenere cipher.pdf │ ├── carroll.txt │ ├── dictionary.txt │ ├── encrypted_carroll.txt │ └── vigenere_cipher.py ├── 24.Nash equilibrium │ ├── Illustrations.zip │ ├── Illustrations │ │ ├── charlie_graph.pdf │ │ ├── chicken.pdf │ │ ├── ruth_graph.pdf │ │ ├── table_1.pdf │ │ ├── table_2.pdf │ │ └── table_3.pdf │ ├── Nash equilibrium.ipynb │ ├── Nash equilibrium.pdf │ └── nash_equilibrium_calculator.py ├── 25.Permutations, Heaps algorithm and cryptarithms │ ├── Illustrations.zip │ ├── Illustrations │ │ ├── cycle.pdf │ │ ├── iterative_example.pdf │ │ ├── principle.pdf │ │ └── recursive_example.pdf │ ├── Permutations, Heap's algorithm and cryptarithms.pdf │ ├── Permutations, Heap_s algorithm and cryptarithms.ipynb │ ├── cryptarithm.py │ ├── iterative_heap_permute.py │ ├── naive_recursive_permute.py │ └── recursive_heap_permute.py ├── 26.Cryptography │ ├── Cryptography.ipynb │ ├── Cryptography.pdf │ └── RSA.py ├── 27.Discrete probability distributions │ ├── Discrete probability distributions.ipynb │ ├── Discrete probability distributions.pdf │ └── discrete_probability_distribution.py ├── 28.Continued fractions │ ├── Continued fractions.ipynb │ ├── Continued fractions.pdf │ ├── Illustrations.zip │ ├── Illustrations │ │ ├── equations_1.pdf │ │ ├── equations_2.pdf │ │ ├── fraction.pdf │ │ ├── squares_1.pdf │ │ └── squares_2.pdf │ └── continued_fraction.py ├── 29.Fractals │ ├── Fractals.ipynb │ ├── Fractals.pdf │ ├── Illustrations.zip │ ├── Illustrations │ │ ├── colored_barnsley_fern.pdf │ │ ├── sierpinsky_1.pdf │ │ └── sierpinsky_2.pdf │ └── barnsley_fern.py ├── 30.Pure Prolog │ ├── Illustrations.zip │ ├── Illustrations │ │ ├── tree_1.pdf │ │ ├── tree_2.pdf │ │ ├── tree_3.pdf │ │ ├── tree_4.pdf │ │ └── tree_5.pdf │ ├── Pure Prolog.ipynb │ ├── Pure Prolog.pdf │ ├── logic.py │ ├── prolog_ex_1.pl │ ├── prolog_ex_2.pl │ ├── prolog_ex_3.pl │ ├── prolog_ex_4.pl │ └── prolog_interpreter.py └── 31.Sorting │ ├── Illustrations.zip │ ├── Sorting.html │ ├── Sorting.ipynb │ ├── batcher_sort.py │ ├── bubble_sort.py │ ├── heap_sort.py │ ├── insertion_sort.py │ ├── merge_sort.py │ ├── quick_sort.py │ ├── selection_sort.py │ ├── shell_sort.py │ └── sorting.py ├── 03.exercies ├── .DS_Store ├── 01.Temperature conversions │ ├── celsius_to_fahrenheit.py │ ├── commands_and_expected_outputs.txt │ ├── fahrenheit_to_celsius.py │ └── readme.md ├── 02.Max element and span in a list │ ├── commands_and_expected_outputs.txt │ ├── max_in_list.py │ ├── readme.md │ └── span.py ├── 03.Classifying elements in a list │ ├── commands_and_expected_outputs.txt │ ├── intervals.py │ ├── modulo_4.py │ └── readme.md ├── 04.Mean median standard deviation │ ├── commands_and_expected_outputs.txt │ ├── mean_median_standard_deviation.py │ └── readme.md ├── 05.Drawing polygons with Turtle │ ├── Illustrations.zip │ ├── Illustrations │ │ ├── dodecagon.mov │ │ ├── dodecagrams.mov │ │ ├── hexagram.mov │ │ └── octagram.mov │ ├── dodecagon.py │ ├── dodecagrams.py │ └── drawing_polygons_with_turtle.ipynb ├── 06.Characters triangle │ ├── characters_triangle.ipynb │ ├── characters_triangle.py │ └── run_and_test.py ├── 06.Decoding a multiplication │ ├── commands_and_expected_outputs.txt │ ├── decoded_multiplication.py │ ├── decoded_multiplication_scaffold.py │ └── readme.md ├── 07.Diophantine equations │ ├── .DS_Store │ ├── diophantine_equations.ipynb │ ├── diophantine_equations.py │ └── run_and_test.py ├── 08.Mediants │ ├── .DS_Store │ ├── mediants.ipynb │ ├── mediants.py │ ├── run_and_test.py │ └── stern_brocot_tree.pdf ├── 09.Trailing zeroes in factorial │ ├── .DS_Store │ ├── run_and_test.py │ ├── trailing_0s_in_factorial.ipynb │ └── trailing_0s_in_factorial.py ├── 10.Cycloidal curves │ ├── .DS_Store │ ├── Illustrations.zip │ ├── cycloidal_curves.ipynb │ └── cycloidal_curves.py ├── 11.Mysterious multiplication │ ├── .DS_Store │ ├── mysterious_multiplication.ipynb │ ├── mysterious_multiplication.py │ └── run_and_test.py ├── 12.Pascal triangle │ ├── pascal1.png │ ├── pascal2.png │ ├── pascal3.png │ ├── pascal_triangle.py │ ├── pascal_triangle_scaffold_1.py │ └── readme.md ├── 12.Special triples │ ├── run_and_test.py │ ├── special_triples.ipynb │ └── special_triples.py ├── 13.Taxicab numbers │ ├── Taxicab numbers.ipynb │ ├── run_and_test.py │ └── taxicab.py ├── 14.Balanced single type brackets │ ├── balanced_single_type_brackets.ipynb │ ├── balanced_single_type_brackets.py │ └── run_and_test.py ├── 14.Encoding pairs of integers as natural numbers │ ├── plane_encoding.py │ └── readme.md ├── 15.Roman numerals │ ├── readme.md │ └── roman_numerals.py ├── 15.Unix calendar │ ├── run_and_test.py │ ├── unix_calendar.ipynb │ └── unix_calendar.py ├── 16.Canonical coin systems │ ├── canonical_coin_systems.ipynb │ ├── canonical_coin_systems.py │ ├── readme.md │ └── run_and_test.py ├── 16.Longest sequence of consecutive letters │ ├── longest_sequence.ipynb │ ├── longest_sequence.py │ ├── longest_sequence_scaffold_1.py │ ├── readme.md │ └── run_and_test.py ├── 17.Special products │ ├── run_and_test.py │ ├── special_products.ipynb │ └── special_products.py ├── 18.Closed paths │ ├── Closed paths.ipynb │ ├── closed_paths.py │ └── run_and_test.py ├── 18.Mediants │ ├── mediant.py │ ├── mediants.ipynb │ └── run_and_test.py ├── 19.Bayes rule │ ├── bayes_rule.ipynb │ ├── bayes_rule.py │ └── run_and_test.py ├── 19.Obtaining a sum from a subsequence of digits │ ├── readme.md │ ├── sum_of_digits.py │ └── sum_of_digits_scaffold_1.py ├── 20.Merging two strings into a third one │ ├── merging_strings.py │ ├── merging_strings_scaffold.py │ └── readme.md ├── 20.Powers in range │ ├── powers_in_range.ipynb │ ├── powers_in_range.py │ └── run_and_test.py ├── 21.Fibonacci codes │ ├── fibonacci_codes.ipynb │ ├── fibonacci_codes.py │ ├── readme.md │ └── run_and_test.py ├── 21.The 8 puzzle │ ├── 9_puzzle_1.png │ ├── 9_puzzle_2.png │ ├── eight_puzzle.ipynb │ ├── eight_puzzle.py │ └── readme.md ├── 22.Dice rolls │ ├── Illustrations.zip │ ├── dice_rolls.ipynb │ ├── dice_rolls.py │ └── run_and_test.py ├── 22.Magic squares │ ├── magic_squares.ipynb │ ├── magic_squares.py │ └── readme.md ├── 23.Colombo sequence │ ├── Colombo sequence.ipynb │ ├── colombo.py │ └── run_and_test.py ├── 23.Unit fractions │ ├── readme.md │ └── unit_fractions.py ├── 24.Diophantine equations │ ├── diophantine_equation.py │ ├── diophantine_equations.ipynb │ └── readme.md ├── 24.Look-and-say sequences │ ├── Look-and-say sequences.ipynb │ ├── look_and_say.py │ └── run_and_test.py ├── 25.Decomposition in prime factors │ ├── prime_factors.ipynb │ ├── prime_factors.py │ └── run_and_test.py ├── 26.Change making │ ├── change_making.py │ └── readme.md ├── 26.Sydney temperatures │ ├── IDCJCM0037_066062.csv │ ├── sydney_temperatures.ipynb │ ├── sydney_temperatures.pdf │ └── sydney_temperatures.py ├── 27.Balanced multiple type brackets │ ├── balanced_multiple_type_brackets.ipynb │ ├── balanced_multiple_type_brackets.py │ └── run_and_test.py ├── 28.Minimal word extensions │ ├── Minimal word extensions.ipynb │ ├── dictionary.txt │ ├── minimal_word_extensions.py │ └── run_and_test.py ├── 28.Practice Exercises │ ├── Practice Exercises_Week10.pdf │ ├── Week 10 - Practice Exercises Solutions.zip │ ├── Week 10 - Practice Exercises.zip │ ├── dictionary.txt │ ├── election_1.xlsx │ ├── election_2.xlsx │ ├── election_3.xlsx │ ├── election_4.xlsx │ ├── election_5.xlsx │ ├── election_6.xlsx │ ├── word_search_1.txt │ └── word_search_2.txt ├── 29.Hasse diagrams │ ├── hasse_diagram.png │ ├── hasse_diagram.py │ ├── hasse_diagrams.ipynb │ ├── hasse_diagrams.pdf │ ├── hasse_diagrams.py │ ├── readme.md │ └── run_and_test.py ├── 30.Sierpinski triangle │ ├── Illustrations.zip │ ├── sierpinski_triangle.ipynb │ ├── sierpinski_triangle.py │ ├── sierpinski_triangle_solution.pdf │ └── sierpinski_triangle_solution.tex ├── 31.Random walk │ ├── random_walk.ipynb │ ├── random_walk.pdf │ └── random_walk.py ├── 32.Markov chains │ ├── dictionary.txt │ ├── markov_chains.ipynb │ ├── markov_chains.py │ └── run_and_test.py ├── 33.Multibases │ ├── multibases.ipynb │ ├── multibases.py │ └── run_and_test.py ├── 34.Longest sequence of consecutive letters │ ├── longest_sequence.ipynb │ ├── longest_sequence.py │ └── run_and_test.py ├── 35.Special sequences of prime numbers │ ├── consecutive_primes.ipynb │ ├── consecutive_primes.py │ └── run_and_test.py ├── 36.Miller Rabin primality test │ ├── miller_rabin_primality_test.ipynb │ ├── miller_rabin_primality_test.py │ └── run_and_test.py ├── 37.Game of nim │ ├── game_of_nim.ipynb │ ├── game_of_nim.py │ ├── readme.md │ └── run_and_test.py ├── 38.Predictive parser │ ├── predictive_parser.ipynb │ ├── predictive_parser.py │ └── run_and_test.py ├── 39.Postfix expressions │ ├── postfix_expression.ipynb │ ├── postfix_expression.py │ └── run_and_test.py ├── 40.Shortest distance in grid │ ├── run_and_test.py │ ├── shortest_distance.py │ └── shortest_distance_in_grid.ipynb ├── 41.Pascal triangle │ ├── pascal_triangle.ipynb │ └── run_and_test.py ├── 42.Eight puzzle │ ├── eight_puzzle.ipynb │ └── run_and_test.py ├── 43.Magic squares │ ├── Illustrations.zip │ ├── magic_squares.ipynb │ └── run_and_test.py ├── 44.Unit fractions │ ├── run_and_test.py │ └── unit_fractions.ipynb ├── 45.Kaprekar's constant │ ├── 6174.pdf │ ├── Kaprekar's constant.ipynb │ └── run_and_test.py ├── 46.Ulam spiral │ ├── Ulam spiral.ipynb │ └── run_and_test.py ├── 47.Sum of digits │ ├── run_and_test.py │ └── sum_of_digits.ipynb ├── 48.Maximal strictly increasing sequences │ ├── maximal_strictly_increasing_sequences.ipynb │ └── run_and_test.py ├── 49.Merge strings │ ├── merge_strings.ipynb │ └── run_and_test.py ├── 50.Catalan numbers │ ├── Illustrations.zip │ ├── catalan_numbers.ipynb │ └── run_and_test.py ├── 51.Target puzzle │ ├── dictionary.txt │ ├── run_and_test.py │ └── target_puzzle.ipynb ├── 52.Stable matching │ ├── run_and_test.py │ └── stable_matching.ipynb ├── 53.CO2 emissions │ ├── API_EN.gz │ ├── CO2_emissions.ipynb │ ├── Illustrations.zip │ └── run_and_test.py ├── 54.Word ladders │ ├── Illustrations.zip │ ├── dictionary.txt │ ├── run_and_test.py │ └── word_ladders.ipynb ├── 55.Word search puzzle │ ├── run_and_test.py │ ├── word_grid_1.txt │ ├── word_grid_2.txt │ └── word_search_puzzle.ipynb ├── 56.Election methods │ ├── election_1.xlsx │ ├── election_2.xlsx │ ├── election_3.xlsx │ ├── election_4.xlsx │ ├── election_5.xlsx │ ├── election_methods.ipynb │ └── run_and_test.py ├── 57.Queen puzzle │ ├── queen_puzzle.ipynb │ └── run_and_test.py ├── 58.Change making with unlimited supply │ ├── change_making_unlimited_supply.ipynb │ └── run_and_test.py ├── 59.Change making with limited supply │ ├── change_making_limited_supply.ipynb │ └── run_and_test.py └── 60.Calkin-Wilf tree │ ├── Calkin-Wilf tree.ipynb │ ├── calkin_wilf_tree.pdf │ └── run_and_test.py ├── 04.Labs └── 03 │ ├── Lab 3.ipynb │ ├── exercise_3_1_template.py │ ├── exercise_3_2_template.py │ ├── exercise_3_3_template.py │ ├── exercise_3_4_template.py │ ├── exercise_3_5_template.py │ ├── exercise_3_6_template.py │ ├── readme.md │ └── run_and_test.py └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/.DS_Store -------------------------------------------------------------------------------- /02.Notes/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/.DS_Store -------------------------------------------------------------------------------- /02.Notes/01.From Problem Description to Python Program Example/From Problem Description to Python Program Example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/01.From Problem Description to Python Program Example/From Problem Description to Python Program Example.pdf -------------------------------------------------------------------------------- /02.Notes/01.From Problem Description to Python Program Example/example.py: -------------------------------------------------------------------------------- 1 | exit_chosen = False 2 | while not exit_chosen: 3 | print("1. Multiply the given number by 1 to 12") 4 | print('2. Sum two given numbers') 5 | print('3. Exit') 6 | choice = input('Please enter your choice: ') 7 | if choice == '1': 8 | num = float(input('Give a number: ')) 9 | i = 1 10 | while i <= 12: 11 | print(num*i,end=' ') # use print(num*i) if we want to display one per line 12 | i = i + 1 13 | print() 14 | elif choice == '2': 15 | num1 = float(input('Give your first number: ')) 16 | num2 = float(input('Give your second number: ')) 17 | res = num1 + num2 18 | print(res) 19 | elif choice == '3': 20 | print("Goodbye") 21 | exit_chosen = True 22 | else: 23 | print("Invalid choice") 24 | 25 | -------------------------------------------------------------------------------- /02.Notes/01.From Problem Description to Python Program Example/example2.py: -------------------------------------------------------------------------------- 1 | choice = '' # or any value different from '3' 2 | while choice != '3': 3 | print("1. Multiply the given number by 1 to 12") 4 | print('2. Sum two given numbers') 5 | print('3. Exit') 6 | choice = input('Please enter your choice: ') 7 | if choice == '1': 8 | num = float(input('Give a number: ')) 9 | i = 1 10 | while i <= 12: 11 | print(num*i,end=' ') # use print(num*i) if we want to display one per line 12 | i = i + 1 13 | print() 14 | elif choice == '2': 15 | num1 = float(input('Give your first number: ')) 16 | num2 = float(input('Give your second number: ')) 17 | res = num1 + num2 18 | print(res) 19 | elif choice == '3': 20 | print("Goodbye") 21 | else: 22 | print("Invalid choice") 23 | -------------------------------------------------------------------------------- /02.Notes/01.From Problem Description to Python Program Example/example3.py: -------------------------------------------------------------------------------- 1 | while True: 2 | print("1. Multiply the given number by 1 to 12") 3 | print('2. Sum two given numbers') 4 | print('3. Exit') 5 | choice = input('Please enter your choice: ') 6 | if choice == '1': 7 | num = float(input('Give a number: ')) 8 | i = 1 9 | while i <= 12: 10 | print(num*i,end=' ') # use print(num*i) if we want to display one per line 11 | i = i + 1 12 | print() 13 | elif choice == '2': 14 | num1 = float(input('Give your first number: ')) 15 | num2 = float(input('Give your second number: ')) 16 | res = num1 + num2 17 | print(res) 18 | elif choice == '3': 19 | print("Goodbye") 20 | break 21 | else: 22 | print("Invalid choice") 23 | -------------------------------------------------------------------------------- /02.Notes/02.Turing machines/Turing machines.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/02.Turing machines/Turing machines.pdf -------------------------------------------------------------------------------- /02.Notes/02.Turing machines/addition.txt: -------------------------------------------------------------------------------- 1 | # Initial state: q0 2 | 3 | q0 1 q1 0 R 4 | q1 1 q1 1 R 5 | q1 0 q2 1 L 6 | q2 1 q2 1 L 7 | q2 0 q3 0 R 8 | 9 | -------------------------------------------------------------------------------- /02.Notes/02.Turing machines/division_by_2.txt: -------------------------------------------------------------------------------- 1 | # Initial state: del1 2 | 3 | del1 1 del2 0 R 4 | del2 1 mov1R 0 R 5 | mov1R 1 mov1R 1 R 6 | mov1R 0 mov2R 0 R 7 | mov2R 1 mov2R 1 R 8 | mov2R 0 mov1L 1 L 9 | mov1L 1 mov1L 1 L 10 | mov1L 0 mov2L 0 L 11 | mov2L 1 mov2L 1 L 12 | mov2L 0 del1 0 R 13 | del1 0 end 0 R 14 | del2 0 end 0 R 15 | -------------------------------------------------------------------------------- /02.Notes/02.Turing machines/multiplication.txt: -------------------------------------------------------------------------------- 1 | # Initial state: q0 2 | 3 | q0 0 q1 0 R 4 | q0 1 q1 0 R 5 | q1 0 q15 0 R 6 | q1 1 q2 1 R 7 | q2 0 q3 0 R 8 | q2 1 q2 1 R 9 | q3 0 q3 0 R 10 | q3 1 q4 0 R 11 | q4 0 q13 1 L 12 | q4 1 q7 1 R 13 | q7 0 q8 0 R 14 | q7 1 q7 1 R 15 | q8 0 q10 1 L 16 | q8 1 q9 1 R 17 | q9 0 q10 1 L 18 | q9 1 q9 1 R 19 | q10 0 q11 0 L 20 | q10 1 q10 1 L 21 | q11 0 q3 0 R 22 | q11 1 q11 1 L 23 | q13 0 q13 0 L 24 | q13 1 q14 1 L 25 | q14 0 q0 0 R 26 | q14 1 q14 1 L 27 | q15 0 q15 1 R 28 | q15 1 q17 1 L 29 | q17 1 q17 1 L 30 | q17 0 q18 0 R 31 | -------------------------------------------------------------------------------- /02.Notes/02.Turing machines/parity.txt: -------------------------------------------------------------------------------- 1 | # Initial state: even 2 | 3 | even 1 odd 0 R 4 | odd 1 even 0 R 5 | odd 0 end 1 L 6 | end 0 end 0 R 7 | -------------------------------------------------------------------------------- /02.Notes/02.Turing machines/readme.md: -------------------------------------------------------------------------------- 1 | ## Useful link about Turing machines 2 | 3 | https://en.wikipedia.org/wiki/Turing_machine 4 | 5 | ## 有用的视频 6 | 7 | 01. https://www.youtube.com/watch?v=iToLe5gZXiQ 8 | 02. https://www.youtube.com/watch?v=dQkLZmr9Ui4 -------------------------------------------------------------------------------- /02.Notes/02.Turing machines/successor.txt: -------------------------------------------------------------------------------- 1 | # Initial state: q0 2 | 3 | q0 1 q0 1 L 4 | q0 0 q1 1 L 5 | q1 0 q1 0 R 6 | -------------------------------------------------------------------------------- /02.Notes/03.The Monty Hall problem/The Monty Hall problem.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/03.The Monty Hall problem/The Monty Hall problem.pdf -------------------------------------------------------------------------------- /02.Notes/03.The Monty Hall problem/readme.md: -------------------------------------------------------------------------------- 1 | ## outline 2 | 3 | Week 2 Monday Outline 4 | 5 | 6 | Notes: 7 | 8 | 1. Python Reference - Jupyter Notebook Sheets 9 | 2. Using "Code Snippet" when posting in Ed Discussion forums 10 | 3. Quiz 1 worth 3.5 marks will be released Wednesday and due Friday 9pm (nine days to do it). 11 | 4. Assignment 1 worth 14 marks will be released in Week 3 12 | 13 | 14 | Topics covered: 15 | 16 | 1. Reading from files (from Week 1) 17 | 2. startwith(), isspace(), and split() str class methods (from Week 1) 18 | 3. dictionaries (from Week 1) 19 | 4. tuples (from Week 1) 20 | 5. mutable and immutable objects/collections (from Week 1) 21 | 6. continue statement (from Week 1) 22 | 7. functions from the random module (random(), choice(), randrange(), seed(), ...) 23 | 8. input() function 24 | 9. int() function 25 | 10. exceptions 26 | 11. break statement 27 | 12. istitle() and lower() str class methods 28 | 13. sets, sets vs dictionaries 29 | 14. choice() 30 | 15. randrange() 31 | 16. remove() and pop() list class methods 32 | 17. multiple assignments 33 | 18. functions with default parameter values 34 | 19. formatted strings 35 | 36 | 37 | 12 possible outcomes: 38 | 39 | winning door A A A A B B B B C C C C 40 | first chosen A A B C B B A C C C A B 41 | opened door B C C B A C C A A B B A 42 | 43 | 24 possible outcomes: 44 | 45 | winning door A A A A A A A A B B B B B B B B C C C C C C C C 46 | first chosen A A A A B B C C B B B B A A C C C C C C A A B B 47 | opened door B B C C C C B B A A C C C C A A A A B B B B A A 48 | 2nd chosen door A C A B A B A C B C B A B A B C C B C A C A C B 49 | 50 | ## Useful links about Monty Hall problem 51 | 52 | Monty Hall problem 53 | https://en.wikipedia.org/wiki/Monty_Hall_problem 54 | 55 | 56 | The Monty Hall Problem (from Khan Academy) 57 | https://www.khanacademy.org/partner-content/wi-phi/wiphi-metaphysics-epistemology/probability-philosophy/v/the-monty-hall-problem 58 | 59 | 60 | Monty Hall Problem Express Explanation 61 | https://www.youtube.com/watch?v=C4vRTzsv4os 62 | 63 | 64 | Monty Hall Problem - Numberphile 65 | https://www.youtube.com/watch?v=4Lb-6rxZxx0 66 | 67 | ## Youtube 68 | 69 | https://www.youtube.com/watch?v=onEVIBcG4zk -------------------------------------------------------------------------------- /02.Notes/04.From decimal expansions to reduced fractions/From decimal expansions to reduced fractions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/04.From decimal expansions to reduced fractions/From decimal expansions to reduced fractions.pdf -------------------------------------------------------------------------------- /02.Notes/04.From decimal expansions to reduced fractions/readme.md: -------------------------------------------------------------------------------- 1 | ## outline 2 | 3 | Week 2 Wednesday Outline 4 | 5 | 6 | Notes: 7 | 8 | 1. From decimal expansions to reduced fractions 9 | 2. Release Coding Quiz 1 and discuss it. 10 | 3. Python Part 1 - Basic control structures (if, while, for, ...) 11 | 4. Python Part 2 - Lists, Tuples, Sets, Dictionaries, ... 12 | 13 | Topics covered: 14 | 15 | 1. Using _ as thousands separator 10_000 16 | 2. gcd (greatest common divisor) function from math module 17 | 3. /, //, and % operators 18 | 4. divmod() function 19 | 5. Condition is not a boolean expression 20 | 6. Unpacking tuple elements into function arguments 21 | 7. Using * in function definition preceding a parameter name 22 | 8. Python Part 1 - Basic control structures (if, while, for, ...) 23 | 9. Python Part 2 - Lists, Tuples, Sets, Dictionaries, ... 24 | 25 | ## useful links 26 | 27 | https://www.youtube.com/watch?v=_j5C00srKcw 28 | -------------------------------------------------------------------------------- /02.Notes/05.Eratosthenes sieve/Eratosthenes_sieve.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/05.Eratosthenes sieve/Eratosthenes_sieve.pdf -------------------------------------------------------------------------------- /02.Notes/05.Eratosthenes sieve/readme.md: -------------------------------------------------------------------------------- 1 | ## outline 2 | 3 | Week 3 Monday Outline 4 | 5 | 6 | Notes: 7 | 8 | 1. Eratosthenes' sieve 9 | 2. Quiz 1 - Execution Output for 12 38 as Input 10 | 3. Assigment 1 - Discussion 11 | 12 | Topics covered: 13 | 14 | 1. Show example of execution of rational_number.py (from Week 2) 15 | 2. sorted([4,7,4,3,8,6,2]) -> [2, 3, 4, 4, 6, 7, 8] 16 | sorted({4,7,4,3,8,6,2}) -> [2, 3, 4, 6, 7, 8] (from Week 2) 17 | 3. imprecision of floating point calculation 18 | 4. int() vs round(), rounding half to even 19 | 5. string formatting 20 | 4. range([first],last,[step]) 21 | 5. iterables vs iterators, iter() 22 | 6. chain() function from itertools library 23 | 7. timeit() 24 | 8. See Python sleep() (https://www.programiz.com/python-programming/time/sleep) 25 | to fix Ed time delay issue. However, remove that while submitting the last 26 | version to be marked 27 | 28 | ## Useful links about Eratosthenes' sieve 29 | 30 | https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 31 | 32 | http://csharphelper.com/blog/2014/08/use-the-sieve-of-eratosthenes-to-find-prime-numbers-in-c/ 33 | 34 | ## youtube links 35 | 36 | https://www.youtube.com/watch?v=3YUUwiQPLw8 37 | https://www.youtube.com/watch?v=Rk0tZ5IDjrg 38 | 39 | -------------------------------------------------------------------------------- /02.Notes/05.Eratosthenes sieve/v1/eratosthenes_sieve_v1.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Generates an initial segment of the list of prime numbers based on 6 | Eratosthenes sieve using the most straightforward approach. 7 | ''' 8 | 9 | 10 | from math import sqrt 11 | 12 | from input_output import * 13 | 14 | 15 | def generate_primes(): 16 | print('I will generate all prime numbers in the range [2, n] ' 17 | 'for the n of your choice.' 18 | ) 19 | nicely_display(*sequence_and_max_size_from( 20 | sieve_of_primes_up_to(input_int(min_value=2))) 21 | ) 22 | 23 | 24 | def sieve_of_primes_up_to(n): 25 | sieve = [True] * (n + 1) 26 | for p in range(2, round(sqrt(n)) + 1): 27 | if sieve[p]: 28 | for i in range(p * p, n + 1, p): 29 | sieve[i] = False 30 | return sieve 31 | 32 | 33 | def sequence_and_max_size_from(sieve): 34 | largest_prime = len(sieve) - 1 35 | while not sieve[largest_prime]: 36 | largest_prime -= 1 37 | return (p for p in range(2, len(sieve)) if sieve[p]),\ 38 | len(str(largest_prime)) 39 | 40 | 41 | if __name__ == '__main__': 42 | generate_primes() 43 | -------------------------------------------------------------------------------- /02.Notes/05.Eratosthenes sieve/v1/input_output.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Utility to prompt the user for an integer with a range that can be 6 | specified, until the user input is of the expected type, and to 7 | nicely display the list of prime numbers from various sieves. 8 | ''' 9 | 10 | 11 | def input_int(prompt = 'What do you want it to be? ', 12 | min_value = float('-inf'), max_value = float('inf') 13 | ): 14 | while True: 15 | try: 16 | input_value = int(input(prompt)) 17 | if input_value < min_value or input_value > max_value: 18 | raise ValueError 19 | return input_value 20 | except ValueError: 21 | print('Incorrect input. ', end='') 22 | 23 | 24 | def nicely_display(sequence, max_size): 25 | field_width = max_size + 2 26 | nb_of_fields = 80 // field_width 27 | count = 0 28 | for e in sequence: 29 | print(f'{e:{field_width}d}', end='') 30 | count += 1 31 | if count % nb_of_fields == 0: 32 | print() 33 | if count % nb_of_fields: 34 | print() 35 | -------------------------------------------------------------------------------- /02.Notes/05.Eratosthenes sieve/v2/eratosthenes_sieve_v2.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Generates an initial segment of the list of prime numbers based on Eratosthenes sieve 6 | without encoding the even numbers greater than 2. 7 | ''' 8 | 9 | 10 | from math import sqrt 11 | from itertools import chain 12 | 13 | from input_output import * 14 | 15 | 16 | def generate_primes(): 17 | print('I will generate all prime numbers in the range [2, n] ' 18 | 'for the n of your choice.' 19 | ) 20 | nicely_display(*sequence_and_max_size_from( 21 | sieve_of_primes_up_to(input_int(min_value=2))) 22 | ) 23 | 24 | 25 | def sieve_of_primes_up_to(n): 26 | # We let primes_sieve encode the sequence 27 | # (2, 3, 5, 7, 9, 11, ..., n') with n' equal to n if n is odd 28 | # and n - 1 is n is even. The index of n' is n_index. 29 | n_index = (n - 1) // 2 30 | sieve = [True] * (n_index + 1) 31 | for k in range(1, (round(sqrt(n)) + 1) // 2): 32 | if sieve[k]: 33 | # If k is the index of p then 34 | # 2 * k * (k + 1) is the index of p ** 2; 35 | # Also, we increment the value by 2p, 36 | # which corresponds to increasing the index by 2 * k + 1. 37 | for i in range(2 * k * (k + 1), n_index + 1, 2 * k + 1): 38 | sieve[i] = False 39 | return sieve 40 | 41 | 42 | def sequence_and_max_size_from(sieve): 43 | largest_prime = len(sieve) - 1 44 | while not sieve[largest_prime]: 45 | largest_prime -= 1 46 | return chain((2,), (2 * p + 1 for p in range(1, len(sieve)) if sieve[p])),\ 47 | len(str(largest_prime)) 48 | 49 | 50 | if __name__ == '__main__': 51 | generate_primes() 52 | -------------------------------------------------------------------------------- /02.Notes/05.Eratosthenes sieve/v2/input_output.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Utility to prompt the user for an integer with a range that can be 6 | specified, until the user input is of the expected type, and to 7 | nicely display the list of prime numbers from various sieves. 8 | ''' 9 | 10 | 11 | def input_int(prompt = 'What do you want it to be? ', 12 | min_value = float('-inf'), max_value = float('inf') 13 | ): 14 | while True: 15 | try: 16 | input_value = int(input(prompt)) 17 | if input_value < min_value or input_value > max_value: 18 | raise ValueError 19 | return input_value 20 | except ValueError: 21 | print('Incorrect input. ', end='') 22 | 23 | 24 | def nicely_display(sequence, max_size): 25 | field_width = max_size + 2 26 | nb_of_fields = 80 // field_width 27 | count = 0 28 | for e in sequence: 29 | print(f'{e:{field_width}d}', end='') 30 | count += 1 31 | if count % nb_of_fields == 0: 32 | print() 33 | if count % nb_of_fields: 34 | print() 35 | -------------------------------------------------------------------------------- /02.Notes/06.Euler sieve/Euler_sieve.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/06.Euler sieve/Euler_sieve.pdf -------------------------------------------------------------------------------- /02.Notes/06.Euler sieve/readme.md: -------------------------------------------------------------------------------- 1 | ## outline 2 | 3 | Week 3 Wednesday Outline 4 | 5 | 6 | Notes: 7 | 8 | 1. Euler's sieve 9 | 2. Quiz 1 - Due Friday 1 October @ 9pm (Sydney time) 10 | 3. Quiz 2 - Release 11 | 4. Assignment 1 12 | 13 | Topics covered: 14 | 15 | 1. round(), rounding half to even (from Week 3 Monday class) 16 | 2. Run Eratosthenes' sieve programs (from Week 3 Monday class) 17 | 3. timeit() returns a time the execution takes in seconds as a float 18 | 4. Matplotlib library - see examples in Ed Workspace - link given below: 19 | https://edstem.org/au/courses/7084/workspaces/pkbR9vBbBFuz2zaEJdiAF2b6uz1Md2Dg 20 | 5. global variable 21 | 6. Show sleep() example for practice exercises to fix Ed time delay 22 | 23 | ## Useful links about Euler's sieve 24 | 25 | Sieve Of Euler 26 | https://programmingpraxis.com/2011/02/25/sieve-of-euler/#:~:text=The%20great%20Swiss%20mathematician%20Leonhard,cost%20of%20some%20additional%20bookkeeping.&text=Third%2C%20%E2%80%9Csubtract%E2%80%9D%20the%20new,appear%20in%20the%20new%20list 27 | 28 | Use Euler’s Sieve to find prime numbers in C# 29 | http://csharphelper.com/blog/2014/08/use-eulers-sieve-to-find-prime-numbers-in-c/ 30 | 31 | ## youtube links 32 | 33 | https://www.youtube.com/watch?v=1tyK8Mw8_ro -------------------------------------------------------------------------------- /02.Notes/06.Euler sieve/v1/euler_sieve_v1.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Generates an initial segment of the list of prime numbers based on 6 | Euler sieve using the most straightforward approach. 7 | ''' 8 | 9 | 10 | from math import sqrt 11 | 12 | from input_output import * 13 | 14 | 15 | def generate_primes(): 16 | print('I will generate all prime numbers in the range [2, n] ' 17 | 'for the n of your choice.' 18 | ) 19 | nicely_display(*sequence_and_max_size_from( 20 | sieve_of_primes_up_to(input_int(min_value=2))) 21 | ) 22 | 23 | 24 | def sieve_of_primes_up_to(n): 25 | sieve = list(range(2, n + 1)) 26 | i = 0 27 | while sieve[i] <= round(sqrt(n)): 28 | k = 0 29 | while True: 30 | factor = sieve[i] * sieve[i + k] 31 | if factor > n: 32 | break 33 | while factor <= n: 34 | sieve.remove(factor) 35 | factor *= sieve[i] 36 | k += 1 37 | i += 1 38 | return sieve 39 | 40 | 41 | def sequence_and_max_size_from(sieve): 42 | return sieve, len(str(sieve[-1])) 43 | 44 | 45 | if __name__ == '__main__': 46 | generate_primes() 47 | -------------------------------------------------------------------------------- /02.Notes/06.Euler sieve/v1/input_output.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2020 2 | 3 | 4 | ''' 5 | Utility to prompt the user for an integer with a range that can be 6 | specified, until the user input is of the expected type, and to 7 | nicely display the list of prime numbers from various sieves. 8 | ''' 9 | 10 | 11 | def input_int(prompt = 'What do you want it to be? ', 12 | min_value = float('-inf'), max_value = float('inf') 13 | ): 14 | while True: 15 | try: 16 | input_value = int(input(prompt)) 17 | if input_value < min_value or input_value > max_value: 18 | raise ValueError 19 | return input_value 20 | except ValueError: 21 | print('Incorrect input. ', end='') 22 | 23 | 24 | def nicely_display(sequence, max_size): 25 | field_width = max_size + 2 26 | nb_of_fields = 80 // field_width 27 | count = 0 28 | for e in sequence: 29 | print(f'{e:{field_width}d}', end='') 30 | count += 1 31 | if count % nb_of_fields == 0: 32 | print() 33 | if count % nb_of_fields: 34 | print() 35 | -------------------------------------------------------------------------------- /02.Notes/06.Euler sieve/v2/euler_sieve_v2.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Generates an initial segment of the list of prime numbers based on 6 | Euler sieve switching between sets and sorted lists for a more effective 7 | implementation. 8 | ''' 9 | 10 | 11 | from math import sqrt 12 | 13 | from input_output import * 14 | 15 | 16 | def generate_primes(): 17 | print('I will generate all prime numbers in the range [2, n] ' 18 | 'for the n of your choice.' 19 | ) 20 | nicely_display(*sequence_and_max_size_from( 21 | sieve_of_primes_up_to(input_int(min_value=2))) 22 | ) 23 | 24 | 25 | def sieve_of_primes_up_to(n): 26 | sieve = list(range(2, n + 1)) 27 | i = 0 28 | while sieve[i] <= round(sqrt(n)): 29 | sieve_as_set = set(sieve) 30 | k = 0 31 | while True: 32 | factor = sieve[i] * sieve[i + k] 33 | if factor > n: 34 | break 35 | sieve_as_set.remove(factor) 36 | k += 1 37 | sieve = sorted(sieve_as_set) 38 | i += 1 39 | return sieve 40 | 41 | 42 | def sequence_and_max_size_from(sieve): 43 | return sieve, len(str(sieve[-1])) 44 | 45 | 46 | if __name__ == '__main__': 47 | generate_primes() 48 | -------------------------------------------------------------------------------- /02.Notes/06.Euler sieve/v2/input_output.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2020 2 | 3 | 4 | ''' 5 | Utility to prompt the user for an integer with a range that can be 6 | specified, until the user input is of the expected type, and to 7 | nicely display the list of prime numbers from various sieves. 8 | ''' 9 | 10 | 11 | def input_int(prompt = 'What do you want it to be? ', 12 | min_value = float('-inf'), max_value = float('inf') 13 | ): 14 | while True: 15 | try: 16 | input_value = int(input(prompt)) 17 | if input_value < min_value or input_value > max_value: 18 | raise ValueError 19 | return input_value 20 | except ValueError: 21 | print('Incorrect input. ', end='') 22 | 23 | 24 | def nicely_display(sequence, max_size): 25 | field_width = max_size + 2 26 | nb_of_fields = 80 // field_width 27 | count = 0 28 | for e in sequence: 29 | print(f'{e:{field_width}d}', end='') 30 | count += 1 31 | if count % nb_of_fields == 0: 32 | print() 33 | if count % nb_of_fields: 34 | print() 35 | -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Card shuffling.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Card shuffling.pdf -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/1.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/10.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/11.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/12.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/13.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/14.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/15.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/16.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/17.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/18.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/19.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/2.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/20.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/21.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/22.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/23.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/24.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/25.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/25.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/26.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/26.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/27.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/27.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/28.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/28.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/29.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/3.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/30.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/31.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/32.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/32.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/33.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/33.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/34.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/34.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/35.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/35.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/36.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/36.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/37.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/37.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/38.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/38.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/39.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/39.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/4.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/40.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/40.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/41.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/41.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/42.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/42.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/43.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/43.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/44.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/44.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/45.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/45.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/46.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/46.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/47.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/47.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/48.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/48.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/49.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/49.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/5.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/50.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/50.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/51.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/51.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/52.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/52.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/6.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/7.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/8.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/Cards/9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/07.Card shuffling/Cards/9.gif -------------------------------------------------------------------------------- /02.Notes/07.Card shuffling/readme.md: -------------------------------------------------------------------------------- 1 | ## outline 2 | 3 | Week 4 Wednesday Outline 4 | 5 | 6 | Notes: 7 | 8 | 1. Quizzes late submission allowed up to 3 days - Closes Monday 9.00pm the following Week 9 | 2. Quiz 1 - Plagiarism - Do not share your code until after release of a sample solution 10 | 3. Quiz 2 - Discussion 11 | 4. Assignment 1 - Discussion 12 | 5. Release Quiz 3 and Discusion 13 | 6. Card shuffling 14 | 7. US Social Security data on given names 15 | 16 | 17 | Topics covered: 18 | 19 | 1. Card shuffling 20 | 2. Unicode character set 21 | 3. List comprehension 22 | 4. String join() method 23 | 5. List extend() method 24 | 6. slices 25 | 7. getsizeof() from the sys module 26 | 8. Command line arguments 27 | 9. US Social Security data on given names 28 | 10. Files and folders manipulation 29 | 30 | ## Useful link about playing cards in Unicode 31 | 32 | Playing cards in Unicode 33 | https://en.wikipedia.org/wiki/Playing_cards_in_Unicode 34 | 35 | ## youtube links 36 | 37 | https://www.youtube.com/watch?v=4LVGWGZwzPs -------------------------------------------------------------------------------- /02.Notes/08.US Social Security data on given names/US Social Security data on given names.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/08.US Social Security data on given names/US Social Security data on given names.pdf -------------------------------------------------------------------------------- /02.Notes/08.US Social Security data on given names/names.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/08.US Social Security data on given names/names.zip -------------------------------------------------------------------------------- /02.Notes/08.US Social Security data on given names/names_per_gender.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Uses data from the American Social Security Administration available 6 | at https://www.ssa.gov/OACT/babynames/limits.html. 7 | Splits the data on the relative frequency of given names in the 8 | population of U.S. births into females and males, removing the field 9 | that determines the classification. 10 | The data are stored in a directory "names", in files named "yobxxxx.txt" 11 | with xxxx (the year of birth) ranging from 1880 to 2018. 12 | They will be copied in a directory "names_per_gender", otherwise keeping 13 | the same file structure. 14 | ''' 15 | 16 | 17 | from pathlib import Path 18 | import csv 19 | import sys 20 | import os 21 | 22 | 23 | names_dirname = Path('/course/data/names') 24 | if not names_dirname.exists(): 25 | print(f'There is no directory named {names_dirname}, giving up...') 26 | sys.exit() 27 | names_per_gender_dirname = Path('names_per_gender') 28 | if names_per_gender_dirname.exists(): 29 | print('A directory named', names_per_gender_dirname, 'already ' 30 | 'exists.\nBetter safe than sorry, giving up.' 31 | ) 32 | sys.exit() 33 | female_subdirname = names_per_gender_dirname / 'female' 34 | male_subdirname = names_per_gender_dirname / 'male' 35 | os.mkdir(names_per_gender_dirname) 36 | os.mkdir(female_subdirname) 37 | os.mkdir(male_subdirname) 38 | for filename in names_dirname.glob('*.txt'): 39 | with open(filename) as file,\ 40 | open(female_subdirname / filename.name, 'w') as female_file,\ 41 | open(male_subdirname / filename.name, 'w') as male_file: 42 | csv_file = csv.reader(file) 43 | female_csv_file = csv.writer(female_file) 44 | male_csv_file = csv.writer(male_file) 45 | csv_file_per_gender = {'F': female_csv_file, 'M': male_csv_file} 46 | for name, gender, tally in csv_file: 47 | csv_file_per_gender[gender].writerow((name, tally)) 48 | -------------------------------------------------------------------------------- /02.Notes/08.US Social Security data on given names/names_revivals.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Uses data from the American Social Security Administration available 6 | at https://www.ssa.gov/OACT/babynames/limits.html. 7 | Determines from the relative frequency of given names in the population 8 | of U.S. births the top 10 names that have disappeared and reappeared for 9 | the longest period of time. 10 | The data are stored in a directory "names", in files named "yobxxxx.txt" 11 | with xxxx (the year of birth) ranging from 1880 to 2018. 12 | ''' 13 | 14 | 15 | from collections import defaultdict 16 | from pathlib import Path 17 | import csv 18 | import sys 19 | 20 | 21 | names_dirname = Path('/course/data/names') 22 | if not names_dirname.exists(): 23 | print(f'There is no directory named {names_dirname}, giving up...') 24 | sys.exit() 25 | # A dictionnary where a key is a name and a value is the list of all 26 | # years when the name was given. 27 | years_per_name = defaultdict(list) 28 | for filename in sorted(names_dirname.glob('*.txt')): 29 | year = int(filename.name[3 : 7]) 30 | with open(filename) as file: 31 | csv_file = csv.reader(file) 32 | for name, _, _ in csv_file: 33 | years_per_name[name].append(year) 34 | # A list of triples consisting of: 35 | # - difference between year when a name was last given and first given 36 | # again, 37 | # - year when name was last given, 38 | # - name 39 | revivals = [[years_per_name[name][i + 1] - years_per_name[name][i], 40 | years_per_name[name][i], name 41 | ] for name in years_per_name 42 | for i in range(len(years_per_name[name]) - 1) 43 | ] 44 | revivals.sort(key=lambda x: (-x[0], x[1], x[2])) 45 | for i in range(10): 46 | print(f'{revivals[i][2]} was last used in {revivals[i][1]} ' 47 | f'and then again in {revivals[i][1] + revivals[i][0]}, ' 48 | f'{revivals[i][0]} years later.' 49 | ) 50 | 51 | -------------------------------------------------------------------------------- /02.Notes/08.US Social Security data on given names/readme.md: -------------------------------------------------------------------------------- 1 | ## useful links 2 | 3 | https://www.youtube.com/watch?v=gtOIiOtpb3Y 4 | https://www.youtube.com/watch?v=65F3tbY2UF8 -------------------------------------------------------------------------------- /02.Notes/09.The tower and marbles puzzle/The tower and marbles puzzle.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/09.The tower and marbles puzzle/The tower and marbles puzzle.pdf -------------------------------------------------------------------------------- /02.Notes/09.The tower and marbles puzzle/readme.md: -------------------------------------------------------------------------------- 1 | ## outline 2 | 3 | Week 5 Monday Outline 4 | 5 | 6 | Notes: 7 | 8 | 1. The tower and marbles puzzle 9 | 2. Week 5 Practice Exercises 10 | 3. Quiz 3 - Discussion 11 | 4. Assignment 1 - Discussion 12 | 13 | 14 | Topics covered: 15 | 16 | 1. The tower and marbles puzzle - n levels and m marbles 17 | 2. Particular Case m = 2 18 | 3. random.randint() 19 | 4. dict.fromkeys() 20 | 5. General case 21 | 6. list comprehension 22 | 7. nicely dispaly a rectangle - string formatting 23 | 24 | ## useful links 25 | 26 | https://www.youtube.com/watch?v=Z5yRNKhrgEw -------------------------------------------------------------------------------- /02.Notes/10.K-means clustering/k-means clustering.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/10.K-means clustering/k-means clustering.pdf -------------------------------------------------------------------------------- /02.Notes/10.K-means clustering/readme.md: -------------------------------------------------------------------------------- 1 | ## youtube 2 | 3 | https://www.youtube.com/watch?v=Z5yRNKhrgEw -------------------------------------------------------------------------------- /02.Notes/11.The game of life/The game of life.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/11.The game of life/The game of life.pdf -------------------------------------------------------------------------------- /02.Notes/11.The game of life/gosperglidergun.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/11.The game of life/gosperglidergun.mp4 -------------------------------------------------------------------------------- /02.Notes/11.The game of life/gosperglidergun.rle: -------------------------------------------------------------------------------- 1 | #N Gosper glider gun 2 | #O Bill Gosper 3 | #C A true period 30 glider gun. 4 | #C The first known gun and the first known finite pattern with unbounded growth. 5 | #C www.conwaylife.com/wiki/index.php?title=Gosper_glider_gun 6 | x = 36, y = 9, rule = B3/S23 7 | 24bo11b$22bobo11b$12b2o6b2o12b2o$11bo3bo4b2o12b2o$2o8bo5bo3b2o14b$2o8b 8 | o3bob2o4bobo11b$10bo5bo7bo11b$11bo3bo20b$12b2o! -------------------------------------------------------------------------------- /02.Notes/11.The game of life/readme.md: -------------------------------------------------------------------------------- 1 | ## Useful links about game of life 2 | 3 | Conway's Game of Life 4 | https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life 5 | 6 | Gun (cellular automaton) 7 | https://en.wikipedia.org/wiki/Gun_(cellular_automaton) 8 | 9 | ## youtube 10 | 11 | https://www.youtube.com/watch?v=-Xn6VCJELnc 12 | https://www.youtube.com/watch?v=QcPLk4pSZsE 13 | https://www.youtube.com/watch?v=jGXTHTtvUi4 14 | https://www.youtube.com/watch?v=7K4Kf1VSeIc -------------------------------------------------------------------------------- /02.Notes/12.The Fibonacci sequence/The Fibonacci sequence.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/12.The Fibonacci sequence/The Fibonacci sequence.pdf -------------------------------------------------------------------------------- /02.Notes/12.The Fibonacci sequence/add2numbers.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | # Rachid Hamadi 3 | 4 | def add(a,b): 5 | if b == 0: 6 | return a 7 | return add(a,b-1) + 1 8 | 9 | print(add(4,9)) 10 | -------------------------------------------------------------------------------- /02.Notes/12.The Fibonacci sequence/factorial.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | # Rachid Hamadi 3 | 4 | def fact(n): 5 | if n <= 1: 6 | return 1 7 | return n*fact(n-1) 8 | print(fact(4)) 9 | 10 | def facti(n): 11 | res = 1 12 | for i in range(2,n+1): 13 | res*=i 14 | return res 15 | print(facti(4)) 16 | -------------------------------------------------------------------------------- /02.Notes/12.The Fibonacci sequence/fib_vs_fibi_runit.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | # Rachid Hamadi 3 | 4 | from timeit import Timer 5 | 6 | t1 = Timer("fib(10)","from fibonacci import fib") 7 | 8 | for i in range(1,41): 9 | s = "fib(" + str(i) + ")" 10 | t1 = Timer(s,"from fibonacci import fib") 11 | time1 = t1.timeit(3) 12 | s = "fibi(" + str(i) + ")" 13 | t2 = Timer(s,"from fibonacci import fibi") 14 | time2 = t2.timeit(3) 15 | print("n=%2d, fib: %8.6f, fibi: %7.6f, percent: %10.2f" % (i, time1, time2, time1/time2)) 16 | -------------------------------------------------------------------------------- /02.Notes/12.The Fibonacci sequence/fibm_vs_fibi_runit.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | # Rachid Hamadi 3 | 4 | from timeit import Timer 5 | 6 | t1 = Timer("fib(10)","from fibonacci import fib") 7 | 8 | for i in range(1,41): 9 | s = "fibm(" + str(i) + ")" 10 | t1 = Timer(s,"from fibonacci import fibm") 11 | time1 = t1.timeit(3) 12 | s = "fibi(" + str(i) + ")" 13 | t2 = Timer(s,"from fibonacci import fibi") 14 | time2 = t2.timeit(3) 15 | print("n=%2d, fib: %8.6f, fibi: %7.6f, percent: %10.2f" % (i, time1, time2, time1/time2)) 16 | -------------------------------------------------------------------------------- /02.Notes/12.The Fibonacci sequence/fibonacci.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Computes the (n+1)st Fibonacci number iteratively and recursively, 6 | with and without memoisation. 7 | ''' 8 | 9 | 10 | from math import sqrt 11 | 12 | 13 | def fibonacci_sequence(): 14 | ''' 15 | >>> S = fibonacci_sequence() 16 | >>> list(next(S) for _ in range(20)) 17 | [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, \ 18 | 2584, 4181] 19 | ''' 20 | yield 0 21 | yield 1 22 | previous, current = 0, 1 23 | while True: 24 | previous, current = current, previous + current 25 | yield current 26 | 27 | def iterative_fibonacci(n): 28 | ''' 29 | >>> [iterative_fibonacci(n) for n in range(20)] 30 | [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, \ 31 | 2584, 4181] 32 | ''' 33 | if n < 2: 34 | return n 35 | previous, current = 0, 1 36 | for _ in range(2, n + 1): 37 | previous, current = current, previous + current 38 | return current 39 | 40 | def recursive_fibonacci(n): 41 | ''' 42 | >>> [recursive_fibonacci(n) for n in range(20)] 43 | [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, \ 44 | 2584, 4181] 45 | ''' 46 | if n >= 2: 47 | return recursive_fibonacci(n - 2) + recursive_fibonacci(n - 1) 48 | return n 49 | 50 | def memoise_fibonacci(n, fibonacci={0: 0, 1: 1}): 51 | ''' 52 | >>> [memoise_fibonacci(n) for n in range(20)] 53 | [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, \ 54 | 2584, 4181] 55 | ''' 56 | if n not in fibonacci: 57 | fibonacci[n] = memoise_fibonacci(n - 1) + memoise_fibonacci(n - 2) 58 | return fibonacci[n] 59 | 60 | def closed_form_fibonacci(n): 61 | ''' 62 | >>> [closed_form_fibonacci(n) for n in range(20)] 63 | [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, \ 64 | 2584, 4181] 65 | ''' 66 | sqrt_5 = sqrt(5) 67 | return round(1 / sqrt_5 * ((1 + sqrt_5) / 2) ** n) 68 | 69 | 70 | if __name__ == '__main__': 71 | import doctest 72 | doctest.testmod() 73 | -------------------------------------------------------------------------------- /02.Notes/12.The Fibonacci sequence/mult4rec.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | # Rachid Hamadi 3 | 4 | def mult4(n): 5 | if n == 1: 6 | return 4 7 | return mult4(n-1) + 4 8 | 9 | print(mult4(5)) 10 | -------------------------------------------------------------------------------- /02.Notes/12.The Fibonacci sequence/readme.md: -------------------------------------------------------------------------------- 1 | 2 | https://www.youtube.com/watch?v=9ebkrsSNCTY -------------------------------------------------------------------------------- /02.Notes/13.The towers of Hanoi/The towers of Hanoi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/13.The towers of Hanoi/The towers of Hanoi.pdf -------------------------------------------------------------------------------- /02.Notes/13.The towers of Hanoi/readme.md: -------------------------------------------------------------------------------- 1 | ## Useful links about the towers of Hanoi 2 | 3 | Tower of Hanoi - Wikipedia 4 | https://en.wikipedia.org/wiki/Tower_of_Hanoi 5 | 6 | Tower of Hanoi - Game 7 | https://www.mathsisfun.com/games/towerofhanoi.html 8 | 9 | ## 10 | 11 | https://www.youtube.com/watch?v=_kp8HxpaNto 12 | https://www.youtube.com/watch?v=Ad7K-9CH0dg 13 | https://www.youtube.com/watch?v=Un8gCbN7Lig -------------------------------------------------------------------------------- /02.Notes/13.The towers of Hanoi/recursive_hanoi.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Recursive solution to the Tower of Hanoi puzzle. 6 | ''' 7 | 8 | 9 | def move_towers(n, start_position, end_position, extra_position): 10 | ''' 11 | Move a tower of n disks from start_position to end_position, 12 | with extra_position available. 13 | 14 | >>> move_towers(4, 0, 2, 1) 15 | Move smallest disk from position 0 to position 1 16 | Move disk of size 2 from position 0 to position 2 17 | Move smallest disk from position 1 to position 2 18 | Move disk of size 3 from position 0 to position 1 19 | Move smallest disk from position 2 to position 0 20 | Move disk of size 2 from position 2 to position 1 21 | Move smallest disk from position 0 to position 1 22 | Move disk of size 4 from position 0 to position 2 23 | Move smallest disk from position 1 to position 2 24 | Move disk of size 2 from position 1 to position 0 25 | Move smallest disk from position 2 to position 0 26 | Move disk of size 3 from position 1 to position 2 27 | Move smallest disk from position 0 to position 1 28 | Move disk of size 2 from position 0 to position 2 29 | Move smallest disk from position 1 to position 2 30 | ''' 31 | if n == 1: 32 | print('Move smallest disk from position', start_position, 33 | 'to position', end_position 34 | ) 35 | else: 36 | move_towers(n - 1, start_position, extra_position, end_position) 37 | print('Move disk of size', n, 'from position', start_position, 38 | 'to position', end_position 39 | ) 40 | move_towers(n - 1, extra_position, end_position, start_position) 41 | 42 | 43 | if __name__ == '__main__': 44 | import doctest 45 | doctest.testmod() 46 | -------------------------------------------------------------------------------- /02.Notes/14.Quadratic equations/Quadratic equations.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/14.Quadratic equations/Quadratic equations.pdf -------------------------------------------------------------------------------- /02.Notes/15.Levenshtein distance/Levenshtein distance.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/15.Levenshtein distance/Levenshtein distance.pdf -------------------------------------------------------------------------------- /02.Notes/15.Levenshtein distance/readme.md: -------------------------------------------------------------------------------- 1 | ## Useful links about Levenshtein distance 2 | 3 | Levenshtein distance 4 | https://en.wikipedia.org/wiki/Levenshtein_distance 5 | 6 | Levenshtein Distance, in Three Flavors https://people.cs.pitt.edu/~kirk/cs1501/Pruhs/Spring2006/assignments/editdistance/Levenshtein%20Distance.htm 7 | 8 | Another Python version of Levenshtein distance https://folk.idi.ntnu.no/mlh/hetland_org/coding/python/levenshtein.py 9 | 10 | Levenshtein Distance 11 | https://python-course.eu/levenshtein_distance.php -------------------------------------------------------------------------------- /02.Notes/16.Context free grammars/Context free grammars.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/16.Context free grammars/Context free grammars.pdf -------------------------------------------------------------------------------- /02.Notes/16.Context free grammars/readme.md: -------------------------------------------------------------------------------- 1 | ## Useful links about context-free grammars 2 | 3 | Context-free grammar 4 | https://en.wikipedia.org/wiki/Context-free_grammar -------------------------------------------------------------------------------- /02.Notes/17.Loans and savings/Loans and savings.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/17.Loans and savings/Loans and savings.pdf -------------------------------------------------------------------------------- /02.Notes/17.Loans and savings/readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/17.Loans and savings/readme.md -------------------------------------------------------------------------------- /02.Notes/18.Three special perfect squares/Three special perfect squares.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/18.Three special perfect squares/Three special perfect squares.pdf -------------------------------------------------------------------------------- /02.Notes/18.Three special perfect squares/readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | https://www.youtube.com/watch?v=rwgxiQoVTfw -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/batcher_sort.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | # Assumes that len(L) is a power of 2 8 | def batcher_sort(L): 9 | ''' 10 | >>> L = [] 11 | >>> batcher_sort(L) 12 | >>> L 13 | [] 14 | >>> L = [0] 15 | >>> batcher_sort(L) 16 | >>> L 17 | [0] 18 | >>> L = [0, 1] 19 | >>> batcher_sort(L) 20 | >>> L 21 | [0, 1] 22 | >>> L = [1, 0] 23 | >>> batcher_sort(L) 24 | >>> L 25 | [0, 1] 26 | >>> L = list(range(8)) 27 | >>> batcher_sort(L) 28 | >>> L 29 | [0, 1, 2, 3, 4, 5, 6, 7] 30 | >>> L.reverse() 31 | >>> batcher_sort(L) 32 | >>> L 33 | [0, 1, 2, 3, 4, 5, 6, 7] 34 | >>> shuffle(L) 35 | >>> batcher_sort(L) 36 | >>> L 37 | [0, 1, 2, 3, 4, 5, 6, 7] 38 | ''' 39 | half_size, size = 1, 2 40 | while half_size < len(L): 41 | for group in range(0, len(L) // size): 42 | top = group * size 43 | for i in range(half_size): 44 | if L[top + i] > L[top + i + half_size]: 45 | L[top + i], L[top + i + half_size] = L[top + i + half_size], L[top + i] 46 | span, double_span = half_size // 2, half_size 47 | while span: 48 | skip = half_size // span 49 | for group in range(len(L) // double_span): 50 | if (group + 1) % skip == 0: 51 | continue 52 | top = span + group * double_span; 53 | for i in range(span): 54 | if L[top + i] > L[top + i + span]: 55 | L[top + i], L[top + i + span] = L[top + i + span], L[top + i] 56 | span //= 2 57 | double_span //= 2 58 | half_size *= 2 59 | size *= 2 60 | 61 | 62 | if __name__ == '__main__': 63 | import doctest 64 | doctest.testmod() 65 | -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/binary_search.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | def binary_search(alist, key): 5 | """Search key in alist[start... end - 1].""" 6 | start = 0 7 | end = len(alist) 8 | while start < end: 9 | mid = (start + end)//2 10 | if alist[mid] > key: 11 | end = mid 12 | elif alist[mid] < key: 13 | start = mid + 1 14 | else: 15 | return mid 16 | return -1 17 | 18 | 19 | alist = input('Enter the sorted list of numbers: ') 20 | alist = alist.split() 21 | alist = [int(x) for x in alist] 22 | key = int(input('The number to search for: ')) 23 | 24 | index = binary_search(alist, key) 25 | if index < 0: 26 | print('{} was not found.'.format(key)) 27 | else: 28 | print('{} was found at index {}.'.format(key, index)) 29 | -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/binary_search_recursive.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | def binary_search(alist, start, end, key): 5 | """Search key in alist[start... end - 1].""" 6 | if not start < end: 7 | return -1 8 | 9 | mid = (start + end)//2 10 | if alist[mid] < key: 11 | return binary_search(alist, mid + 1, end, key) 12 | elif alist[mid] > key: 13 | return binary_search(alist, start, mid, key) 14 | else: 15 | return mid 16 | 17 | 18 | alist = input('Enter the sorted list of numbers: ') 19 | alist = alist.split() 20 | alist = [int(x) for x in alist] 21 | key = int(input('The number to search for: ')) 22 | 23 | index = binary_search(alist, 0, len(alist), key) 24 | if index < 0: 25 | print('{} was not found.'.format(key)) 26 | else: 27 | print('{} was found at index {}.'.format(key, index)) 28 | -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/bubble_sort.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def bubble_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> bubble_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> bubble_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> bubble_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> bubble_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> bubble_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> bubble_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> bubble_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | bound = len(L) - 1 39 | swapped = True 40 | while swapped and bound: 41 | swapped = False 42 | for i in range(bound): 43 | if L[i] > L[i + 1]: 44 | L[i], L[i + 1] = L[i + 1], L[i] 45 | swapped = True 46 | bound = i 47 | 48 | 49 | if __name__ == '__main__': 50 | import doctest 51 | doctest.testmod() 52 | -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/heap_sort.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def heap_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> heap_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> heap_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> heap_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> heap_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> heap_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> heap_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> heap_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | if len(L) < 2: 39 | return 40 | for i in range(len(L) // 2 - 1, -1, -1): 41 | bubble_down(L, i, len(L)) 42 | for i in range(len(L) - 1, 2, -1): 43 | L[0], L[i] = L[i], L[0] 44 | bubble_down(L, 0, i) 45 | if len(L) > 2: 46 | L[0], L[2] = L[2], L[0] 47 | if L[0] > L[1]: 48 | L[0], L[1] = L[1], L[0] 49 | 50 | def bubble_down(L, i, length): 51 | while True: 52 | index_of_greatest_child = 2 * i + 1 53 | if index_of_greatest_child >= length: 54 | return 55 | if (index_of_greatest_child < length - 1 and 56 | L[index_of_greatest_child] < L[index_of_greatest_child + 1]): 57 | index_of_greatest_child = index_of_greatest_child + 1 58 | if L[i] >= L[index_of_greatest_child]: 59 | return 60 | else: 61 | L[i], L[index_of_greatest_child] = L[index_of_greatest_child], L[i] 62 | i = index_of_greatest_child 63 | 64 | 65 | if __name__ == '__main__': 66 | import doctest 67 | doctest.testmod() 68 | -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/insertion_sort.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def insertion_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> insertion_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> insertion_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> insertion_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> insertion_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> insertion_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> insertion_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> insertion_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | for i in range(1, len(L)): 39 | j = i 40 | while j and L[j - 1] > L[j]: 41 | L[j - 1], L[j] = L[j], L[j - 1] 42 | j -= 1 43 | 44 | 45 | if __name__ == '__main__': 46 | import doctest 47 | doctest.testmod() 48 | -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/linear_search.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | def linear_search(alist, key): 5 | """Return index of key in alist. Return -1 if key not present.""" 6 | for i in range(len(alist)): 7 | if alist[i] == key: 8 | return i 9 | return -1 10 | 11 | 12 | alist = input('Enter the list of numbers: ') 13 | alist = alist.split() 14 | alist = [int(x) for x in alist] 15 | key = int(input('The number to search for: ')) 16 | 17 | index = linear_search(alist, key) 18 | if index < 0: 19 | print('{} was not found.'.format(key)) 20 | else: 21 | print('{} was found at index {}.'.format(key, index)) 22 | -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/merge_sort.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def merge_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> merge_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> merge_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> merge_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> merge_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> merge_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> merge_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> merge_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | L_copy = list(L) 39 | mergesort(L, L_copy, 0, len(L)) 40 | 41 | def mergesort(L1, L2, start, end): 42 | if end - start < 2: 43 | return 44 | half_length = start + (end - start) // 2 45 | mergesort(L2, L1, start, half_length) 46 | mergesort(L2, L1, half_length, end) 47 | i = start 48 | i1 = start 49 | i2 = half_length 50 | while i1 < half_length and i2 < end: 51 | if L2[i1] <= L2[i2]: 52 | L1[i] = L2[i1] 53 | i1 += 1 54 | else: 55 | L1[i] = L2[i2] 56 | i2 += 1 57 | i += 1 58 | while i1 < half_length: 59 | L1[i] = L2[i1] 60 | i1 += 1 61 | i += 1 62 | while i2 < end: 63 | L1[i] = L2[i2] 64 | i2 += 1 65 | i += 1 66 | 67 | 68 | if __name__ == '__main__': 69 | import doctest 70 | doctest.testmod() 71 | -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/quick_sort.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def quick_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> quick_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> quick_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> quick_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> quick_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> quick_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> quick_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> quick_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | quicksort(L, 0, len(L) - 1) 39 | 40 | def quicksort(L, start, last): 41 | if last - start < 1: 42 | return 43 | split_point = partition(L, start, last) 44 | quicksort(L, start, split_point - 1) 45 | quicksort(L, split_point + 1, last) 46 | 47 | def partition(L, start, end): 48 | pivot_value = L[start] 49 | left_mark = start + 1 50 | right_mark = end 51 | while True: 52 | while left_mark <= right_mark and L[left_mark] <= pivot_value: 53 | left_mark += 1 54 | while right_mark > left_mark and L[right_mark] >= pivot_value: 55 | right_mark -= 1 56 | if right_mark <= left_mark: 57 | break 58 | L[left_mark], L[right_mark] = L[right_mark], L[left_mark] 59 | left_mark += 1 60 | right_mark -= 1 61 | if left_mark == right_mark: 62 | right_mark -= 1 63 | if right_mark > start: 64 | L[start], L[right_mark] = L[right_mark], L[start] 65 | return right_mark 66 | 67 | 68 | if __name__ == '__main__': 69 | import doctest 70 | doctest.testmod() 71 | -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/readme.md: -------------------------------------------------------------------------------- 1 | Useful links about Searching and Sorting 2 | The Quick Sort https://runestone.academy/runestone/books/published/pythonds/SortSearch/TheQuickSort.html 3 | 4 | Sorting, searching and algorithm analysis 5 | https://python-textbok.readthedocs.io/en/1.0/Sorting_and_Searching_Algorithms.html 6 | 7 | Python Programming Examples on Searching and Sorting 8 | https://www.sanfoundry.com/python-programming-examples-searching-sorting/ 9 | 10 | A tour of the top 5 sorting algorithms with Python code 11 | https://medium.com/@george.seif94/a-tour-of-the-top-5-sorting-algorithms-with-python-code-43ea9aa02889 12 | 13 | Sorting and Searching in Python 14 | https://code.tutsplus.com/tutorials/sorting-and-searching-in-python--cms-25668 15 | 16 | Batcher odd–even mergesort 17 | https://en.wikipedia.org/wiki/Batcher_odd%E2%80%93even_mergesort -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/selection_sort.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def selection_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> selection_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> selection_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> selection_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> selection_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> selection_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> selection_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> selection_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | for i in range(len(L) - 1): 39 | index_of_min = i 40 | for j in range(i + 1, len(L)): 41 | if L[j] < L[index_of_min]: 42 | index_of_min = j 43 | if index_of_min != i: 44 | L[i], L[index_of_min] = L[index_of_min], L[i] 45 | 46 | 47 | if __name__ == '__main__': 48 | import doctest 49 | doctest.testmod() 50 | -------------------------------------------------------------------------------- /02.Notes/19.Searching and Sorting/shell_sort.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def shell_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> shell_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> shell_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> shell_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> shell_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> shell_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> shell_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> shell_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | for n in range(len(L) // 2, 0, -1): 39 | # We use Pratt's method which uses as gaps all numbers of the form 2^i * 3^j 40 | p = n 41 | while p % 2 == 0: 42 | p //= 2 43 | while p % 3 == 0: 44 | p //= 3 45 | if p != 1: 46 | continue 47 | for i in range(n, 2 * n): 48 | for j in range(i, len(L), n): 49 | k = j 50 | while k >= n and L[k - n] > L[k]: 51 | L[k - n], L[k] = L[k], L[k - n] 52 | k -= n 53 | 54 | 55 | if __name__ == '__main__': 56 | import doctest 57 | doctest.testmod() 58 | -------------------------------------------------------------------------------- /02.Notes/20.Elementary cellular automata/Elementary cellular automata.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/20.Elementary cellular automata/Elementary cellular automata.pdf -------------------------------------------------------------------------------- /02.Notes/20.Elementary cellular automata/readme.md: -------------------------------------------------------------------------------- 1 | 2 | https://www.youtube.com/watch?v=VMFRD-WNQIw 3 | https://www.youtube.com/watch?v=0QFtTqS9SXQ -------------------------------------------------------------------------------- /02.Notes/21.The Babylonian method for computing square roots/The Babylonian method for computing square roots.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/21.The Babylonian method for computing square roots/The Babylonian method for computing square roots.pdf -------------------------------------------------------------------------------- /02.Notes/21.The Babylonian method for computing square roots/readme.md: -------------------------------------------------------------------------------- 1 | 2 | https://www.youtube.com/watch?v=sRDJ4jA-P2s -------------------------------------------------------------------------------- /02.Notes/21.The Babylonian method for computing square roots/sqrt_approximation.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | Estimates the square root of a given number, up to a given precision, 6 | using the Babylonian method. 7 | 8 | ''' 9 | 10 | 11 | def square_root(a, ε): 12 | ''' 13 | >>> square_root(2, 0.0001) 14 | 1.4142135623746899 15 | >>> square_root(3, 0.000001) 16 | 1.7320508075688772 17 | >>> square_root(4, 0.0000001) 18 | 2.000000000000002 19 | ''' 20 | def iterate(f, x): 21 | while True: 22 | next_x = f(x) 23 | yield next_x 24 | x = next_x 25 | 26 | x = 1 27 | approximating_sequence = iterate(lambda x: (x + a / x) / 2 , x) 28 | next_x = next(approximating_sequence) 29 | while abs(next_x - x) > ε: 30 | next_x, x = next(approximating_sequence), next_x 31 | return next_x 32 | 33 | 34 | if __name__ == '__main__': 35 | import doctest 36 | doctest.testmod() 37 | -------------------------------------------------------------------------------- /02.Notes/22.ASCII art/ASCII art.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/22.ASCII art/ASCII art.pdf -------------------------------------------------------------------------------- /02.Notes/22.ASCII art/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/22.ASCII art/Illustrations.zip -------------------------------------------------------------------------------- /02.Notes/22.ASCII art/Illustrations/10_as_block_size_35_32_as_character_ramp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/22.ASCII art/Illustrations/10_as_block_size_35_32_as_character_ramp.pdf -------------------------------------------------------------------------------- /02.Notes/22.ASCII art/Illustrations/3_as_block_size_64_37_35_42_43_61_45_58_46_32_as_character_ramp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/22.ASCII art/Illustrations/3_as_block_size_64_37_35_42_43_61_45_58_46_32_as_character_ramp.pdf -------------------------------------------------------------------------------- /02.Notes/22.ASCII art/mona_lisa.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/22.ASCII art/mona_lisa.jpeg -------------------------------------------------------------------------------- /02.Notes/22.ASCII art/mona_lisa_10_as_block_size_35_32_as_character_ramp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/22.ASCII art/mona_lisa_10_as_block_size_35_32_as_character_ramp.pdf -------------------------------------------------------------------------------- /02.Notes/22.ASCII art/mona_lisa_3_as_block_size_64_37_35_42_43_61_45_58_46_32_as_character_ramp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/22.ASCII art/mona_lisa_3_as_block_size_64_37_35_42_43_61_45_58_46_32_as_character_ramp.pdf -------------------------------------------------------------------------------- /02.Notes/23.The Vigenere cipher/The Vigenere cipher.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/23.The Vigenere cipher/The Vigenere cipher.pdf -------------------------------------------------------------------------------- /02.Notes/24.Nash equilibrium/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/24.Nash equilibrium/Illustrations.zip -------------------------------------------------------------------------------- /02.Notes/24.Nash equilibrium/Illustrations/charlie_graph.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/24.Nash equilibrium/Illustrations/charlie_graph.pdf -------------------------------------------------------------------------------- /02.Notes/24.Nash equilibrium/Illustrations/chicken.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/24.Nash equilibrium/Illustrations/chicken.pdf -------------------------------------------------------------------------------- /02.Notes/24.Nash equilibrium/Illustrations/ruth_graph.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/24.Nash equilibrium/Illustrations/ruth_graph.pdf -------------------------------------------------------------------------------- /02.Notes/24.Nash equilibrium/Illustrations/table_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/24.Nash equilibrium/Illustrations/table_1.pdf -------------------------------------------------------------------------------- /02.Notes/24.Nash equilibrium/Illustrations/table_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/24.Nash equilibrium/Illustrations/table_2.pdf -------------------------------------------------------------------------------- /02.Notes/24.Nash equilibrium/Illustrations/table_3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/24.Nash equilibrium/Illustrations/table_3.pdf -------------------------------------------------------------------------------- /02.Notes/24.Nash equilibrium/Nash equilibrium.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/24.Nash equilibrium/Nash equilibrium.pdf -------------------------------------------------------------------------------- /02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Illustrations.zip -------------------------------------------------------------------------------- /02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Illustrations/cycle.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Illustrations/cycle.pdf -------------------------------------------------------------------------------- /02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Illustrations/iterative_example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Illustrations/iterative_example.pdf -------------------------------------------------------------------------------- /02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Illustrations/principle.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Illustrations/principle.pdf -------------------------------------------------------------------------------- /02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Illustrations/recursive_example.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Illustrations/recursive_example.pdf -------------------------------------------------------------------------------- /02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Permutations, Heap's algorithm and cryptarithms.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/25.Permutations, Heaps algorithm and cryptarithms/Permutations, Heap's algorithm and cryptarithms.pdf -------------------------------------------------------------------------------- /02.Notes/25.Permutations, Heaps algorithm and cryptarithms/iterative_heap_permute.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | An iterative implementation of Heap's algorithms to generate the 6 | permutations of a list. 7 | ''' 8 | 9 | 10 | def iterative_heap_permute(L): 11 | ''' 12 | >>> list(list(L) for L in iterative_heap_permute([0])) 13 | [[0]] 14 | >>> list(list(L) for L in iterative_heap_permute([0, 1])) 15 | [[0, 1], [1, 0]] 16 | >>> list(list(L) for L in iterative_heap_permute([0, 1, 2])) 17 | [[0, 1, 2], [1, 0, 2], [2, 0, 1], [0, 2, 1], [1, 2, 0], [2, 1, 0]] 18 | >>> list(list(L) for L in iterative_heap_permute([0, 1, 2, 3])) 19 | [[0, 1, 2, 3], [1, 0, 2, 3], [2, 0, 1, 3], [0, 2, 1, 3], \ 20 | [1, 2, 0, 3], [2, 1, 0, 3], [3, 1, 0, 2], [1, 3, 0, 2], [0, 3, 1, 2], \ 21 | [3, 0, 1, 2], [1, 0, 3, 2], [0, 1, 3, 2], [0, 2, 3, 1], [2, 0, 3, 1], \ 22 | [3, 0, 2, 1], [0, 3, 2, 1], [2, 3, 0, 1], [3, 2, 0, 1], [3, 2, 1, 0], \ 23 | [2, 3, 1, 0], [1, 3, 2, 0], [3, 1, 2, 0], [2, 1, 3, 0], [1, 2, 3, 0]] 24 | ''' 25 | yield L 26 | stack = [(0, i) for i in range(len(L) - 1, 0, -1)] 27 | while stack: 28 | low, high = stack.pop() 29 | if high % 2: 30 | L[low], L[high] = L[high], L[low] 31 | else: 32 | L[0], L[high] = L[high], L[0] 33 | yield L 34 | if low + 1 != high: 35 | stack.append((low + 1, high)) 36 | for i in range(high - 1, 0, -1): 37 | stack.append((0, i)) 38 | 39 | 40 | if __name__ == '__main__': 41 | import doctest 42 | doctest.testmod() 43 | -------------------------------------------------------------------------------- /02.Notes/25.Permutations, Heaps algorithm and cryptarithms/naive_recursive_permute.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | A naive recursive method to generate all permutations of a set. 6 | ''' 7 | 8 | 9 | def naive_recursive_permute(S): 10 | ''' 11 | >>> list(naive_recursive_permute({0})) 12 | [[0]] 13 | >>> list(naive_recursive_permute({0, 1})) 14 | [[0, 1], [1, 0]] 15 | >>> list(naive_recursive_permute({0, 1, 2})) 16 | [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]] 17 | >>> list(naive_recursive_permute({0, 1, 2, 3})) 18 | [[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1], \ 19 | [0, 3, 1, 2], [0, 3, 2, 1], [1, 0, 2, 3], [1, 0, 3, 2], [1, 2, 0, 3], \ 20 | [1, 2, 3, 0], [1, 3, 0, 2], [1, 3, 2, 0], [2, 0, 1, 3], [2, 0, 3, 1], \ 21 | [2, 1, 0, 3], [2, 1, 3, 0], [2, 3, 0, 1], [2, 3, 1, 0], [3, 0, 1, 2], \ 22 | [3, 0, 2, 1], [3, 1, 0, 2], [3, 1, 2, 0], [3, 2, 0, 1], [3, 2, 1, 0]] 23 | ''' 24 | if len(S) <= 1: 25 | yield list(S) 26 | else: 27 | for x in S: 28 | for P in naive_recursive_permute(S - {x}): 29 | yield [x] + P 30 | 31 | 32 | if __name__ == '__main__': 33 | import doctest 34 | doctest.testmod() 35 | -------------------------------------------------------------------------------- /02.Notes/25.Permutations, Heaps algorithm and cryptarithms/recursive_heap_permute.py: -------------------------------------------------------------------------------- 1 | # COMP9021 Term 3 2021 2 | 3 | 4 | ''' 5 | A recursive implementation of Heap's algorithms to generate the 6 | permutations of a list. 7 | ''' 8 | 9 | 10 | def heap_permute_by_recursion(L): 11 | ''' 12 | >>> list(list(L) for L in heap_permute_by_recursion([0])) 13 | [[0]] 14 | >>> list(list(L) for L in heap_permute_by_recursion([0, 1])) 15 | [[0, 1], [1, 0]] 16 | >>> list(list(L) for L in heap_permute_by_recursion([0, 1, 2])) 17 | [[0, 1, 2], [1, 0, 2], [2, 0, 1], [0, 2, 1], [1, 2, 0], [2, 1, 0]] 18 | >>> list(list(L) for L in heap_permute_by_recursion([0, 1, 2, 3])) 19 | [[0, 1, 2, 3], [1, 0, 2, 3], [2, 0, 1, 3], [0, 2, 1, 3], \ 20 | [1, 2, 0, 3], [2, 1, 0, 3], [3, 1, 0, 2], [1, 3, 0, 2], [0, 3, 1, 2], \ 21 | [3, 0, 1, 2], [1, 0, 3, 2], [0, 1, 3, 2], [0, 2, 3, 1], [2, 0, 3, 1], \ 22 | [3, 0, 2, 1], [0, 3, 2, 1], [2, 3, 0, 1], [3, 2, 0, 1], [3, 2, 1, 0], \ 23 | [2, 3, 1, 0], [1, 3, 2, 0], [3, 1, 2, 0], [2, 1, 3, 0], [1, 2, 3, 0]] 24 | ''' 25 | yield from recursive_heap_permute(L, len(L)) 26 | 27 | 28 | def recursive_heap_permute(L, length): 29 | if length <= 1: 30 | yield L 31 | else: 32 | length -= 1 33 | for i in range(length): 34 | yield from recursive_heap_permute(L, length) 35 | if length % 2: 36 | L[i], L[length] = L[length], L[i] 37 | else: 38 | L[0], L[length] = L[length], L[0] 39 | yield from recursive_heap_permute(L, length) 40 | 41 | 42 | if __name__ == '__main__': 43 | import doctest 44 | doctest.testmod() 45 | -------------------------------------------------------------------------------- /02.Notes/26.Cryptography/Cryptography.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/26.Cryptography/Cryptography.pdf -------------------------------------------------------------------------------- /02.Notes/27.Discrete probability distributions/Discrete probability distributions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/27.Discrete probability distributions/Discrete probability distributions.pdf -------------------------------------------------------------------------------- /02.Notes/28.Continued fractions/Continued fractions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/28.Continued fractions/Continued fractions.pdf -------------------------------------------------------------------------------- /02.Notes/28.Continued fractions/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/28.Continued fractions/Illustrations.zip -------------------------------------------------------------------------------- /02.Notes/28.Continued fractions/Illustrations/equations_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/28.Continued fractions/Illustrations/equations_1.pdf -------------------------------------------------------------------------------- /02.Notes/28.Continued fractions/Illustrations/equations_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/28.Continued fractions/Illustrations/equations_2.pdf -------------------------------------------------------------------------------- /02.Notes/28.Continued fractions/Illustrations/fraction.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/28.Continued fractions/Illustrations/fraction.pdf -------------------------------------------------------------------------------- /02.Notes/28.Continued fractions/Illustrations/squares_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/28.Continued fractions/Illustrations/squares_1.pdf -------------------------------------------------------------------------------- /02.Notes/28.Continued fractions/Illustrations/squares_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/28.Continued fractions/Illustrations/squares_2.pdf -------------------------------------------------------------------------------- /02.Notes/29.Fractals/Fractals.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/29.Fractals/Fractals.pdf -------------------------------------------------------------------------------- /02.Notes/29.Fractals/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/29.Fractals/Illustrations.zip -------------------------------------------------------------------------------- /02.Notes/29.Fractals/Illustrations/colored_barnsley_fern.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/29.Fractals/Illustrations/colored_barnsley_fern.pdf -------------------------------------------------------------------------------- /02.Notes/29.Fractals/Illustrations/sierpinsky_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/29.Fractals/Illustrations/sierpinsky_1.pdf -------------------------------------------------------------------------------- /02.Notes/29.Fractals/Illustrations/sierpinsky_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/29.Fractals/Illustrations/sierpinsky_2.pdf -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/30.Pure Prolog/Illustrations.zip -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/Illustrations/tree_1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/30.Pure Prolog/Illustrations/tree_1.pdf -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/Illustrations/tree_2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/30.Pure Prolog/Illustrations/tree_2.pdf -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/Illustrations/tree_3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/30.Pure Prolog/Illustrations/tree_3.pdf -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/Illustrations/tree_4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/30.Pure Prolog/Illustrations/tree_4.pdf -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/Illustrations/tree_5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/30.Pure Prolog/Illustrations/tree_5.pdf -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/Pure Prolog.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/30.Pure Prolog/Pure Prolog.pdf -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/prolog_ex_1.pl: -------------------------------------------------------------------------------- 1 | % Test queries: 2 | 3 | % father(X, jack). 4 | % X = bob. 5 | 6 | % grandparent(john, X). 7 | % X = jack ; 8 | % X = sandra ; 9 | 10 | father(bob, jack). 11 | father(bob, sandra). 12 | father(john, bob). 13 | father(john, mary). 14 | mother(jane, jack). 15 | mother(jane, sandra). 16 | mother(emily, bob). 17 | mother(emily, mary). 18 | 19 | parent(X, Y) :- father(X, Y). 20 | parent(X, Y) :- mother(X, Y). 21 | son(X, Y) :- parent(Y, X), male(X). 22 | daughter(X, Y) :- parent(Y, X), female(X). 23 | brother(X, Y) :- male(X), parent(Z, X), parent(Z, Y). 24 | grandparent(X, Y) :- parent(X, Z), parent(Z, Y). 25 | -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/prolog_ex_2.pl: -------------------------------------------------------------------------------- 1 | join(e, X, X). 2 | join(l(H, T), X, l(H, Y)) :- join(T, X, Y). 3 | -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/prolog_ex_3.pl: -------------------------------------------------------------------------------- 1 | concat(a, Y, Y). 2 | concat(f(X), Y, f(Z)) :- concat(X, Y, Z). 3 | concat(g(X), Y, g(Z)) :- concat(X, Y, Z). 4 | 5 | compress(a, a). 6 | compress(f(a), f(a)). 7 | compress(g(a), g(a)). 8 | compress(f(f(X)), Y) :- compress(f(X), Y). 9 | compress(g(g(X)), Y) :- compress(g(X), Y). 10 | compress(f(g(X)), f(Y)) :- compress(g(X), Y). 11 | compress(g(f(X)), g(Y)) :- compress(f(X), Y). 12 | 13 | accumulator_reverse(a, X, X). 14 | accumulator_reverse(f(X), Y, Z) :- accumulator_reverse(X, f(Y), Z). 15 | accumulator_reverse(g(X), Y, Z) :- accumulator_reverse(X, g(Y), Z). 16 | reverse(X, Y) :- accumulator_reverse(X, a, Y). 17 | 18 | relation(X, Y, Z) :- concat(X, Y, U), compress(U, V), reverse(V, Z). 19 | relation(X, Y, Z) :- concat(Y, X, U), compress(U, V), reverse(V, Z). 20 | -------------------------------------------------------------------------------- /02.Notes/30.Pure Prolog/prolog_ex_4.pl: -------------------------------------------------------------------------------- 1 | num(o). 2 | num(s(X)) :- num(X). 3 | 4 | plus(o, Y, Y). 5 | plus(s(X), Y, s(Z)) :- plus(X, Y, Z). 6 | 7 | times(o, _, o). 8 | times(s(X), Y, Z) :- times(X, Y, U), plus(U, Y, Z). 9 | 10 | reduce(add(mult(A, x), B), add(mult(A, x), B)) :- num(A), num(B). 11 | reduce(s(X), add(Y, s(Z))) :- reduce(X, add(Y, Z)). 12 | reduce(o, add(mult(o, x), o)). 13 | reduce(x, add(mult(s(o), x), o)). 14 | reduce(add(X, Y), add(mult(N, x), M)) :- reduce(X, add(mult(N1, x), M1)), reduce(Y, add(mult(N2, x), M2)), plus(N1, N2, N), plus(M1, M2, M). 15 | reduce(mult(X, Y), add(mult(N, x), M)) :- reduce(X, add(mult(o, x), M1)), reduce(Y, add(mult(N, x), M2)), plus(M1, M2, M). 16 | reduce(mult(X, Y), add(mult(N, x), M)) :- reduce(X, add(mult(N, x), M1)), reduce(Y, add(mult(o, x), M2)), plus(M1, M2, M). 17 | 18 | equiv(X, Y) :- reduce(X, Z), reduce(Y, Z). 19 | 20 | -------------------------------------------------------------------------------- /02.Notes/31.Sorting/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/02.Notes/31.Sorting/Illustrations.zip -------------------------------------------------------------------------------- /02.Notes/31.Sorting/batcher_sort.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | # Assumes that len(L) is a power of 2 8 | def batcher_sort(L): 9 | ''' 10 | >>> L = [] 11 | >>> batcher_sort(L) 12 | >>> L 13 | [] 14 | >>> L = [0] 15 | >>> batcher_sort(L) 16 | >>> L 17 | [0] 18 | >>> L = [0, 1] 19 | >>> batcher_sort(L) 20 | >>> L 21 | [0, 1] 22 | >>> L = [1, 0] 23 | >>> batcher_sort(L) 24 | >>> L 25 | [0, 1] 26 | >>> L = list(range(8)) 27 | >>> batcher_sort(L) 28 | >>> L 29 | [0, 1, 2, 3, 4, 5, 6, 7] 30 | >>> L.reverse() 31 | >>> batcher_sort(L) 32 | >>> L 33 | [0, 1, 2, 3, 4, 5, 6, 7] 34 | >>> shuffle(L) 35 | >>> batcher_sort(L) 36 | >>> L 37 | [0, 1, 2, 3, 4, 5, 6, 7] 38 | ''' 39 | half_size, size = 1, 2 40 | while half_size < len(L): 41 | for group in range(0, len(L) // size): 42 | top = group * size 43 | for i in range(half_size): 44 | if L[top + i] > L[top + i + half_size]: 45 | L[top + i], L[top + i + half_size] =\ 46 | L[top + i + half_size], L[top + i] 47 | span, double_span = half_size // 2, half_size 48 | while span: 49 | skip = half_size // span 50 | for group in range(len(L) // double_span): 51 | if (group + 1) % skip == 0: 52 | continue 53 | top = span + group * double_span; 54 | for i in range(span): 55 | if L[top + i] > L[top + i + span]: 56 | L[top + i], L[top + i + span] =\ 57 | L[top + i + span], L[top + i] 58 | span //= 2 59 | double_span //= 2 60 | half_size *= 2 61 | size *= 2 62 | 63 | 64 | if __name__ == '__main__': 65 | import doctest 66 | doctest.testmod() 67 | -------------------------------------------------------------------------------- /02.Notes/31.Sorting/bubble_sort.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def bubble_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> bubble_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> bubble_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> bubble_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> bubble_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> bubble_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> bubble_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> bubble_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | bound = len(L) - 1 39 | swapped = True 40 | while swapped and bound: 41 | swapped = False 42 | for i in range(bound): 43 | if L[i] > L[i + 1]: 44 | L[i], L[i + 1] = L[i + 1], L[i] 45 | swapped = True 46 | bound = i 47 | 48 | 49 | if __name__ == '__main__': 50 | import doctest 51 | doctest.testmod() 52 | -------------------------------------------------------------------------------- /02.Notes/31.Sorting/heap_sort.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def heap_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> heap_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> heap_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> heap_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> heap_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> heap_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> heap_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> heap_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | if len(L) < 2: 39 | return 40 | for i in range(len(L) // 2 - 1, -1, -1): 41 | bubble_down(L, i, len(L)) 42 | for i in range(len(L) - 1, 2, -1): 43 | L[0], L[i] = L[i], L[0] 44 | bubble_down(L, 0, i) 45 | if len(L) > 2: 46 | L[0], L[2] = L[2], L[0] 47 | if L[0] > L[1]: 48 | L[0], L[1] = L[1], L[0] 49 | 50 | def bubble_down(L, i, length): 51 | while True: 52 | index_of_greatest_child = 2 * i + 1 53 | if index_of_greatest_child >= length: 54 | return 55 | if (index_of_greatest_child < length - 1 and 56 | L[index_of_greatest_child] < L[index_of_greatest_child + 1]): 57 | index_of_greatest_child = index_of_greatest_child + 1 58 | if L[i] >= L[index_of_greatest_child]: 59 | return 60 | else: 61 | L[i], L[index_of_greatest_child] = L[index_of_greatest_child], L[i] 62 | i = index_of_greatest_child 63 | 64 | 65 | if __name__ == '__main__': 66 | import doctest 67 | doctest.testmod() 68 | -------------------------------------------------------------------------------- /02.Notes/31.Sorting/insertion_sort.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def insertion_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> insertion_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> insertion_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> insertion_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> insertion_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> insertion_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> insertion_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> insertion_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | for i in range(1, len(L)): 39 | j = i 40 | while j and L[j - 1] > L[j]: 41 | L[j - 1], L[j] = L[j], L[j - 1] 42 | j -= 1 43 | 44 | 45 | if __name__ == '__main__': 46 | import doctest 47 | doctest.testmod() 48 | -------------------------------------------------------------------------------- /02.Notes/31.Sorting/merge_sort.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def merge_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> merge_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> merge_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> merge_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> merge_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> merge_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> merge_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> merge_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | L_copy = list(L) 39 | mergesort(L, L_copy, 0, len(L)) 40 | 41 | def mergesort(L1, L2, start, end): 42 | if end - start < 2: 43 | return 44 | half_length = start + (end - start) // 2 45 | mergesort(L2, L1, start, half_length) 46 | mergesort(L2, L1, half_length, end) 47 | i = start 48 | i1 = start 49 | i2 = half_length 50 | while i1 < half_length and i2 < end: 51 | if L2[i1] <= L2[i2]: 52 | L1[i] = L2[i1] 53 | i1 += 1 54 | else: 55 | L1[i] = L2[i2] 56 | i2 += 1 57 | i += 1 58 | while i1 < half_length: 59 | L1[i] = L2[i1] 60 | i1 += 1 61 | i += 1 62 | while i2 < end: 63 | L1[i] = L2[i2] 64 | i2 += 1 65 | i += 1 66 | 67 | 68 | if __name__ == '__main__': 69 | import doctest 70 | doctest.testmod() 71 | -------------------------------------------------------------------------------- /02.Notes/31.Sorting/quick_sort.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def quick_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> quick_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> quick_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> quick_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> quick_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> quick_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> quick_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> quick_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | quicksort(L, 0, len(L) - 1) 39 | 40 | def quicksort(L, start, last): 41 | if last - start < 1: 42 | return 43 | split_point = partition(L, start, last) 44 | quicksort(L, start, split_point - 1) 45 | quicksort(L, split_point + 1, last) 46 | 47 | def partition(L, start, end): 48 | pivot_value = L[start] 49 | left_mark = start + 1 50 | right_mark = end 51 | while True: 52 | while left_mark <= right_mark and L[left_mark] <= pivot_value: 53 | left_mark += 1 54 | while right_mark > left_mark and L[right_mark] >= pivot_value: 55 | right_mark -= 1 56 | # All values till position left_mark excluded are 57 | # at most equal to the pivot. 58 | # All values from position right_mark excluded are 59 | # at least equal to the pivot. 60 | # The value at position right_mark is greater than the pivot. 61 | if left_mark == right_mark: 62 | right_mark -= 1 63 | if right_mark == start: 64 | return start 65 | # Either the penultimate if statement was true 66 | # and its body has been executed, or two values 67 | # next to each other have just been swapped. 68 | if left_mark == right_mark + 1: 69 | L[start], L[right_mark] = L[right_mark], L[start] 70 | return right_mark 71 | L[left_mark], L[right_mark] = L[right_mark], L[left_mark] 72 | 73 | 74 | if __name__ == '__main__': 75 | import doctest 76 | doctest.testmod() 77 | -------------------------------------------------------------------------------- /02.Notes/31.Sorting/selection_sort.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def selection_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> selection_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> selection_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> selection_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> selection_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> selection_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> selection_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> selection_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | for i in range(len(L) - 1): 39 | index_of_min = i 40 | for j in range(i + 1, len(L)): 41 | if L[j] < L[index_of_min]: 42 | index_of_min = j 43 | if index_of_min != i: 44 | L[i], L[index_of_min] = L[index_of_min], L[i] 45 | 46 | 47 | if __name__ == '__main__': 48 | import doctest 49 | doctest.testmod() 50 | -------------------------------------------------------------------------------- /02.Notes/31.Sorting/shell_sort.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from random import shuffle 5 | 6 | 7 | def shell_sort(L): 8 | ''' 9 | >>> L = [] 10 | >>> shell_sort(L) 11 | >>> L 12 | [] 13 | >>> L = [0] 14 | >>> shell_sort(L) 15 | >>> L 16 | [0] 17 | >>> L = [0, 1] 18 | >>> shell_sort(L) 19 | >>> L 20 | [0, 1] 21 | >>> L = [1, 0] 22 | >>> shell_sort(L) 23 | >>> L 24 | [0, 1] 25 | >>> L = list(range(8)) 26 | >>> shell_sort(L) 27 | >>> L 28 | [0, 1, 2, 3, 4, 5, 6, 7] 29 | >>> L.reverse() 30 | >>> shell_sort(L) 31 | >>> L 32 | [0, 1, 2, 3, 4, 5, 6, 7] 33 | >>> shuffle(L) 34 | >>> shell_sort(L) 35 | >>> L 36 | [0, 1, 2, 3, 4, 5, 6, 7] 37 | ''' 38 | for h in range(len(L) - 1, 0, -1): 39 | # We use Pratt's method which uses as gaps all numbers of the form 40 | # 2^i * 3^j 41 | p = h 42 | while p % 2 == 0: 43 | p //= 2 44 | while p % 3 == 0: 45 | p //= 3 46 | if p != 1: 47 | continue 48 | for i in range(len(L) - h): 49 | if L[i + h] < L[i]: 50 | L[i + h], L[i] = L[i], L[i + h] 51 | 52 | 53 | if __name__ == '__main__': 54 | import doctest 55 | doctest.testmod() 56 | -------------------------------------------------------------------------------- /03.exercies/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/.DS_Store -------------------------------------------------------------------------------- /03.exercies/01.Temperature conversions/celsius_to_fahrenheit.py: -------------------------------------------------------------------------------- 1 | # Prints out a conversion table of temperatures from Celsius to 2 | # Fahrenheit degrees, the former ranging from 0 to 100 in steps 3 | # of 10. 4 | 5 | 6 | # Insert your code here 7 | -------------------------------------------------------------------------------- /03.exercies/01.Temperature conversions/commands_and_expected_outputs.txt: -------------------------------------------------------------------------------- 1 | TEST 1 BEGIN 2 | $ python3 celsius_to_fahrenheit.py 3 | Celsius Fahrenheit 4 | 0 32 5 | 10 50 6 | 20 68 7 | 30 86 8 | 40 104 9 | 50 122 10 | 60 140 11 | 70 158 12 | 80 176 13 | 90 194 14 | 100 212 15 | TEST 1 END 16 | 17 | -------------------------------------------------------------------------------- /03.exercies/01.Temperature conversions/fahrenheit_to_celsius.py: -------------------------------------------------------------------------------- 1 | # Prints out a conversion table of temperatures from Fahrenheit 2 | # to Celsius degrees, with the former ranging from 0 to 300 in 3 | # steps of 20. 4 | 5 | 6 | min_temperature = 0 7 | max_temperature = 300 8 | step = 20 9 | # \t: A tab 10 | print('Fahrenheit\tCelsius') 11 | # We let fahrenheit take the values 12 | # - min_temperature 13 | # - min_temperature + step 14 | # - min_temperature + 2 * step 15 | # - min_temperature + 3 * step 16 | # ... 17 | # up to the largest value smaller than max_temperature + step 18 | for fahrenheit in range(min_temperature, max_temperature + step, step): 19 | celsius = 5 * (fahrenheit - 32) / 9 20 | # {:10d} or {:10}: fahrenheit as a decimal number in a field 21 | # of width 10. 22 | # {:7.1f}: celsius as a floating point number in a field of 23 | # width 7 with 1 digit after the decimal point. 24 | print(f'{fahrenheit:10}\t{celsius:7.1f}') 25 | -------------------------------------------------------------------------------- /03.exercies/01.Temperature conversions/readme.md: -------------------------------------------------------------------------------- 1 | ## Temperature conversions 2 | 3 | Study the program fahrenheit_to_celsius.py and run it in the Terminal window, executing "python3 fahrenheit_to_celsius.py". Then complete the program celsius_to_fahrenheit.py that displays a conversion table from Celsius degrees to Fahrenheit degrees, with the former ranging from 0 to 100 in steps of 10; run it and check your solution with the Run and Submit buttons, respectively. 4 | 5 | See commands_and_expected_outputs.txt for expected output. -------------------------------------------------------------------------------- /03.exercies/02.Max element and span in a list/commands_and_expected_outputs.txt: -------------------------------------------------------------------------------- 1 | TEST 1 BEGIN 2 | $ echo -e '0\n8' | python3 span.py 3 | Input a seed for the random number generator: 0 4 | How many elements do you want to generate? 8 5 | 6 | The list is: [49, 97, 53, 5, 33, 65, 62, 51] 7 | 8 | The maximum difference between largest and smallest values in this list is: 92 9 | Confirming with builtin operations: 92 10 | TEST 1 END 11 | 12 | TEST 2 BEGIN 13 | $ echo -e '1\n12' | python3 span.py 14 | Input a seed for the random number generator: 1 15 | How many elements do you want to generate? 12 16 | 17 | The list is: [17, 72, 97, 8, 32, 15, 63, 97, 57, 60, 83, 48] 18 | 19 | The maximum difference between largest and smallest values in this list is: 89 20 | Confirming with builtin operations: 89 21 | TEST 2 END 22 | 23 | -------------------------------------------------------------------------------- /03.exercies/02.Max element and span in a list/max_in_list.py: -------------------------------------------------------------------------------- 1 | from random import seed, randint 2 | import sys 3 | 4 | 5 | # Prompts the user for an integer to provide as argument to the 6 | # seed() function. 7 | try: 8 | arg_for_seed = int(input('Feed the seed with an integer: ')) 9 | except ValueError: 10 | print('Input is not an integer, giving up.') 11 | sys.exit() 12 | # Prompts the user a strictly positive number, nb_of_elements. 13 | try: 14 | nb_of_elements = int(input('How many elements do you want to generate? ')) 15 | except ValueError: 16 | print('Input is not an integer, giving up.') 17 | sys.exit() 18 | if nb_of_elements <= 0: 19 | print('Input should be strictly positive, giving up.') 20 | sys.exit() 21 | seed(arg_for_seed) 22 | # Generates a list of nb_of_elements random integers between 0 and 99. 23 | L = [randint(0, 99) for _ in range(nb_of_elements)] 24 | # Prints out the list. 25 | print('\nThe list is:', L) 26 | # Computes the maximum element of the list without using the 27 | # builtin max(). 28 | max_element = 0 29 | for e in L: 30 | if e > max_element: 31 | max_element = e 32 | # Prints out the value of the maximum element within text out. 33 | print('\nThe maximum number in this list is:', max_element) 34 | # Confirms the value with the builtin max(). 35 | print('Confirming with builtin operation:', max(L)) 36 | -------------------------------------------------------------------------------- /03.exercies/02.Max element and span in a list/readme.md: -------------------------------------------------------------------------------- 1 | Max element and span in a list 2 | 3 | Study the program max_in_list.py and run it in the Terminal window, executing "python3 max_in_list.py". Then complete the program span.py that prompts the user for a seed for the random number generator, and for a strictly positive number, nb_of_elements, generates a list of nb_of_elements random integers between 0 and 99, prints out the list, computes the difference between the largest and smallest values in the list without using the builtins min() and max(), prints it out, and check that the result is correct using the builtins; run it and check your solution with the Run and Submit buttons, respectively. 4 | 5 | See commands_and_expected_outputs.txt for expected outputs and sample inputs. -------------------------------------------------------------------------------- /03.exercies/02.Max element and span in a list/span.py: -------------------------------------------------------------------------------- 1 | from random import seed, randint 2 | import sys 3 | 4 | 5 | # Insert your code here 6 | -------------------------------------------------------------------------------- /03.exercies/03.Classifying elements in a list/commands_and_expected_outputs.txt: -------------------------------------------------------------------------------- 1 | TEST 1 BEGIN 2 | $ echo -e '0\n1' | python3 intervals.py 3 | Input a seed for the random number generator: 0 4 | How many elements do you want to generate? 1 5 | 6 | The list is: [12] 7 | 8 | There is no element between 0 and 4. 9 | There is no element between 5 and 9. 10 | There is 1 element between 10 and 14. 11 | There is no element between 15 and 19. 12 | TEST 1 END 13 | 14 | TEST 2 BEGIN 15 | $ echo -e '1\n3' | python3 intervals.py 16 | Input a seed for the random number generator: 1 17 | How many elements do you want to generate? 3 18 | 19 | The list is: [4, 18, 2] 20 | 21 | There are 2 elements between 0 and 4. 22 | There is no element between 5 and 9. 23 | There is no element between 10 and 14. 24 | There is 1 element between 15 and 19. 25 | TEST 2 END 26 | 27 | TEST 3 BEGIN 28 | $ echo -e '2\n14' | python3 intervals.py 29 | Input a seed for the random number generator: 2 30 | How many elements do you want to generate? 14 31 | 32 | The list is: [1, 2, 2, 11, 5, 9, 8, 19, 6, 19, 1, 18, 5, 13] 33 | 34 | There are 4 elements between 0 and 4. 35 | There are 5 elements between 5 and 9. 36 | There are 2 elements between 10 and 14. 37 | There are 3 elements between 15 and 19. 38 | TEST 3 END 39 | 40 | -------------------------------------------------------------------------------- /03.exercies/03.Classifying elements in a list/intervals.py: -------------------------------------------------------------------------------- 1 | from random import seed, randrange 2 | import sys 3 | 4 | 5 | # Insert your code here 6 | -------------------------------------------------------------------------------- /03.exercies/03.Classifying elements in a list/modulo_4.py: -------------------------------------------------------------------------------- 1 | from random import seed, randrange 2 | import sys 3 | 4 | 5 | # Prompts the user for an integer to provide as argument to the 6 | # seed() function. 7 | try: 8 | arg_for_seed = int(input('Feed the seed with an integer: ')) 9 | except ValueError: 10 | print('Input is not an integer, giving up.') 11 | sys.exit() 12 | # Prompts the user a strictly positive number, nb_of_elements. 13 | try: 14 | nb_of_elements = int(input('How many elements do you want to generate? ')) 15 | except ValueError: 16 | print('Input is not an integer, giving up.') 17 | sys.exit() 18 | if nb_of_elements <= 0: 19 | print('Input should be strictly positive, giving up.') 20 | sys.exit() 21 | seed(arg_for_seed) 22 | # Generates a list of nb_of_elements random integers between 0 and 99. 23 | L = [randrange(100) for _ in range(nb_of_elements)] 24 | # Prints out the list. 25 | print('\nThe list is:' , L) 26 | print() 27 | # Computes the number of elements equal to 0, 1, 2 3 modulo 4. 28 | # - remainders_modulo_4[0] to record the number of elements 29 | # equal to 0 modulo 4, 30 | # - remainders_modulo_4[1] to record the number of elements 31 | # equal to 1 modulo 4, 32 | # - remainders_modulo_4[2] to record the number of elements 33 | # equal to 2 modulo 4, 34 | # - remainders_modulo_4[3] to record the number of elements 35 | # equal to 3 modulo 4. 36 | remainders_modulo_4 = [0] * 4 37 | for e in L: 38 | remainders_modulo_4[e % 4] += 1 39 | # Prints those numbers within some text out. 40 | for i in range(4): 41 | if remainders_modulo_4[i] == 0: 42 | print('There is no element', end=' ') 43 | elif remainders_modulo_4[i] == 1: 44 | print('There is 1 element', end=' ') 45 | else: 46 | print(f'There are', remainders_modulo_4[i], 'elements', end=' ') 47 | print('equal to', i, 'modulo 4.') 48 | -------------------------------------------------------------------------------- /03.exercies/03.Classifying elements in a list/readme.md: -------------------------------------------------------------------------------- 1 | ## Classifying elements in a list 2 | 3 | The operators /, // and % are used for floating point division, integer division, and remainder, respectively. 4 | 5 | Study the program modulo_4.py and run it in the Terminal window, executing "python3 modulo_4.py". Then complete program intervals.py that prompts the user for a strictly positive integer, nb_of_elements, generates a list of nb_of_elements random integers between 0 and 19, prints out the list, computes the number of elements strictly less than 5, 10, 15 and 20, and prints those out; run it and check your solution with the Run and Mark (or Submit) buttons, respectively. 6 | 7 | See commands_and_expected_outputs.txt for expected outputs and sample inputs. -------------------------------------------------------------------------------- /03.exercies/04.Mean median standard deviation/commands_and_expected_outputs.txt: -------------------------------------------------------------------------------- 1 | TEST 1 BEGIN 2 | $ echo -e '0\n1' | python3 mean_median_standard_deviation.py 3 | Input a seed for the random number generator: 0 4 | How many elements do you want to generate? 1 5 | 6 | The list is: [-1] 7 | 8 | The mean is -1.00. 9 | The median is -1.00. 10 | The standard deviation is 0.00. 11 | 12 | Confirming with functions from the statistics module: 13 | The mean is -1.00. 14 | The median is -1.00. 15 | The standard deviation is 0.00. 16 | TEST 1 END 17 | 18 | TEST 2 BEGIN 19 | $ echo -e '1\n8' | python3 mean_median_standard_deviation.py 20 | Input a seed for the random number generator: 1 21 | How many elements do you want to generate? 8 22 | 23 | The list is: [-33, 22, 47, -42, -18, -35, 13, 47] 24 | 25 | The mean is 0.12. 26 | The median is -2.50. 27 | The standard deviation is 34.41. 28 | 29 | Confirming with functions from the statistics module: 30 | The mean is 0.12. 31 | The median is -2.50. 32 | The standard deviation is 34.41. 33 | TEST 2 END 34 | 35 | TEST 3 BEGIN 36 | $ echo -e '2\n13' | python3 mean_median_standard_deviation.py 37 | Input a seed for the random number generator: 2 38 | How many elements do you want to generate? 13 39 | 40 | The list is: [-43, -39, -40, -4, -29, 44, 35, -11, -18, 27, -23, 27, -46] 41 | 42 | The mean is -9.23. 43 | The median is -18.00. 44 | The standard deviation is 30.92. 45 | 46 | Confirming with functions from the statistics module: 47 | The mean is -9.23. 48 | The median is -18.00. 49 | The standard deviation is 30.92. 50 | TEST 3 END 51 | 52 | -------------------------------------------------------------------------------- /03.exercies/04.Mean median standard deviation/mean_median_standard_deviation.py: -------------------------------------------------------------------------------- 1 | from random import seed, randint 2 | from math import sqrt 3 | from statistics import mean, median, pstdev 4 | import sys 5 | 6 | 7 | # Insert your code here 8 | -------------------------------------------------------------------------------- /03.exercies/04.Mean median standard deviation/readme.md: -------------------------------------------------------------------------------- 1 | 2 | ## Mean, median, standard deviation 3 | 4 | Complete the program mean_median_standard_deviation.py that prompts the user for a strictly positive integer, nb_of_elements, generates a list of nb_of_elements random integers between - 50 and 50, prints out the list, computes the mean, the median and the standard deviation in two ways, that is, using or not the functions from the statistics module, and prints them out. 5 | 6 | To compute the median, the easiest way is to first sort the list with the built-in sort() method. 7 | 8 | See commands_and_expected_outputs.txt for expected outputs and sample inputs. -------------------------------------------------------------------------------- /03.exercies/05.Drawing polygons with Turtle/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/05.Drawing polygons with Turtle/Illustrations.zip -------------------------------------------------------------------------------- /03.exercies/05.Drawing polygons with Turtle/Illustrations/dodecagon.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/05.Drawing polygons with Turtle/Illustrations/dodecagon.mov -------------------------------------------------------------------------------- /03.exercies/05.Drawing polygons with Turtle/Illustrations/dodecagrams.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/05.Drawing polygons with Turtle/Illustrations/dodecagrams.mov -------------------------------------------------------------------------------- /03.exercies/05.Drawing polygons with Turtle/Illustrations/hexagram.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/05.Drawing polygons with Turtle/Illustrations/hexagram.mov -------------------------------------------------------------------------------- /03.exercies/05.Drawing polygons with Turtle/Illustrations/octagram.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/05.Drawing polygons with Turtle/Illustrations/octagram.mov -------------------------------------------------------------------------------- /03.exercies/05.Drawing polygons with Turtle/dodecagon.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | # Draws a dodecadon with the colour of each sector alternating 5 | # red and blue. 6 | 7 | 8 | from turtle import * 9 | 10 | 11 | def draw_triangle(i, colour, vertices): 12 | color(colour) 13 | begin_fill() 14 | goto(vertices[i]) 15 | goto(vertices[i + 1]) 16 | end_fill() 17 | 18 | def draw_dodecagon(): 19 | edge_length = 100 20 | angle = 30 21 | vertices = [] 22 | penup() 23 | # Determine the positions of the 12 vertices of the dodecagon 24 | # by going to each of them (moving a distance of 100 from the 25 | # origin, in a direction of 0, -30, -60, -90,... degrees), 26 | # recording the position, and appending that position to the 27 | # list of vertices. So vertices is eventually the list 28 | # [(x_0, y_0), (x_1, y_1), (x_2, y_2),..., (x_{11}, x_{11})] 29 | # where (x_i, y_i) are the x and y coordinates of the (i+1)st 30 | # vertice. 31 | for i in range(12): 32 | right(i * angle) 33 | forward(edge_length) 34 | vertices.append(pos()) 35 | # A shortchut for: get back to the origin 36 | home() 37 | # Add to the end of the list vertices the coordinates of the 38 | # first vertice in order to "close" the picture. So vertices 39 | # becomes [(x_0, y_0), (x_1, y_1), (x_2, y_2),..., 40 | # (x_{11}, x_{11}), (x_0, y_0)]. 41 | vertices.append(vertices[0]) 42 | pendown() 43 | for i in range(12): 44 | home() 45 | # If i is odd because the division of i by 2 yields a 46 | # remainder of 1 then make colour 'red'; otherwise make 47 | # it 'blue'. 48 | draw_triangle(i, 'red' if i % 2 else 'blue', vertices) 49 | 50 | 51 | draw_dodecagon() 52 | # Used to have control over the start of the video recording. 53 | # onkey(draw_dodecagon, 'Up') 54 | # listen() 55 | -------------------------------------------------------------------------------- /03.exercies/05.Drawing polygons with Turtle/dodecagrams.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | # Draws three coloured dodecagrams, separed by a distance of 5 | # one third the length of the edges, and centred in the window 6 | # that displays them. 7 | 8 | 9 | from turtle import * 10 | 11 | 12 | edge_length = 150 13 | angle = 150 14 | 15 | 16 | def draw_dodecagram(colour): 17 | color(colour) 18 | begin_fill() 19 | for _ in range(12): 20 | forward(edge_length) 21 | left(angle) 22 | end_fill() 23 | 24 | def teleport(distance): 25 | penup() 26 | forward(distance) 27 | pendown() 28 | 29 | def draw_dodecagrams(): 30 | # Make sure that the dodecagrams are centred horizontally 31 | # in the window that displays them. 32 | # Without the following statement, the left end of the horizontal 33 | # edge of the green dodecagram, from which the drawing starts, 34 | # would be at the centre of the screen (so the dodecagrams are 35 | # not quite centred vertically). 36 | teleport(- edge_length // 2) 37 | # Draw the middle dodecagram, then the left dodecagram, 38 | # then the right dodecagram. 39 | draw_dodecagram('green') 40 | teleport(- 4 * edge_length // 3) 41 | draw_dodecagram('red') 42 | teleport(8 * edge_length // 3) 43 | draw_dodecagram('blue') 44 | 45 | 46 | draw_dodecagrams() 47 | # Used to have control over the start of the video recording. 48 | # onkey(draw_dodecagrams, 'Up') 49 | # listen() 50 | -------------------------------------------------------------------------------- /03.exercies/06.Characters triangle/characters_triangle.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | while True: 5 | try: 6 | height = int(input('Enter a strictly positive integer: ')) 7 | if height <= 0: 8 | raise ValueError 9 | break 10 | except ValueError: 11 | print('Incorrect input, try again.') 12 | A_code = ord('A') 13 | c = A_code 14 | for i in range(height): 15 | # Displays spaces on the left 16 | print(' ' * (height - i - 1), end='') 17 | # Displays letters before middle column 18 | for _ in range(i): 19 | print(chr(c), end='') 20 | # Code of next letter 21 | c = (c - A_code + 1) % 26 + A_code 22 | # Displays middle column 23 | print(chr(c), end='') 24 | # Displays letters after middle column 25 | for _ in range(i): 26 | # Code of previous letter 27 | c = (c - A_code - 1) % 26 + A_code 28 | print(chr(c), end='') 29 | print() 30 | # Code of first letter to be input on next line 31 | c = ((2 + i) * (1 + i) // 2) % 26 + A_code 32 | -------------------------------------------------------------------------------- /03.exercies/06.Decoding a multiplication/commands_and_expected_outputs.txt: -------------------------------------------------------------------------------- 1 | TEST 1 BEGIN 2 | A solution with all columns adding up to 10: 3 | 4 1 1 4 | x 1 3 5 | ------- 6 | 1 2 3 3 7 | 4 1 1 8 | ------- 9 | 5 3 4 3 10 | 11 | A solution with all columns adding up to 18: 12 | 4 2 5 13 | x 2 3 14 | ------- 15 | 1 2 7 5 16 | 8 5 0 17 | ------- 18 | 9 7 7 5 19 | TEST 1 END 20 | 21 | -------------------------------------------------------------------------------- /03.exercies/06.Decoding a multiplication/decoded_multiplication.py: -------------------------------------------------------------------------------- 1 | # Decodes all multiplications of the form 2 | # 3 | # * * * 4 | # x * * 5 | # ---------- 6 | # * * * * 7 | # * * * 8 | # ---------- 9 | # * * * * 10 | # 11 | # such that the sum of all digits in all 4 columns is constant. 12 | 13 | 14 | # Insert your code here. 15 | 16 | -------------------------------------------------------------------------------- /03.exercies/06.Decoding a multiplication/decoded_multiplication_scaffold.py: -------------------------------------------------------------------------------- 1 | # Decodes all multiplications of the form 2 | # 3 | # * * * 4 | # x * * 5 | # ---------- 6 | # * * * * 7 | # * * * 8 | # ---------- 9 | # * * * * 10 | # 11 | # such that the sum of all digits in all 4 columns is constant. 12 | 13 | 14 | for x in range(100, 1_000): 15 | for y in range(10, 100): 16 | pass 17 | # Replace pass above with your code. 18 | # Compute the first partial product product0, namely, x * (y % 10), 19 | # and make sure it is at least equal to 1000. 20 | # Compute the second partial product product1 and make sure it is smaller than 1000. 21 | # Perform all other necessary tests... 22 | -------------------------------------------------------------------------------- /03.exercies/06.Decoding a multiplication/readme.md: -------------------------------------------------------------------------------- 1 | ## Decoding a multiplication 2 | 3 | We want to decode all multiplications of the form 4 | 5 | 6 | such that the sum of all digits in all 4 columns is constant. 7 | 8 | Insert your code into decoded_multiplication.py. There are actually two solutions, see expected output for details on what it should be. If you are stuck, but only when you are stuck, then use decoded_multiplication_scaffold.py. -------------------------------------------------------------------------------- /03.exercies/07.Diophantine equations/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/07.Diophantine equations/.DS_Store -------------------------------------------------------------------------------- /03.exercies/08.Mediants/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/08.Mediants/.DS_Store -------------------------------------------------------------------------------- /03.exercies/08.Mediants/stern_brocot_tree.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/08.Mediants/stern_brocot_tree.pdf -------------------------------------------------------------------------------- /03.exercies/09.Trailing zeroes in factorial/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/09.Trailing zeroes in factorial/.DS_Store -------------------------------------------------------------------------------- /03.exercies/09.Trailing zeroes in factorial/trailing_0s_in_factorial.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from math import factorial 5 | 6 | 7 | def first_computation(x): 8 | print(f'Computing the number of trailing 0s in {x}! ' 9 | 'dividing by 10 long enough...' 10 | ) 11 | x = factorial(x) 12 | nb_of_trailing_0s = 0 13 | while x % 10 == 0: 14 | nb_of_trailing_0s += 1 15 | x //= 10 16 | return nb_of_trailing_0s 17 | 18 | def second_computation(x): 19 | print(f'Computing the number of trailing 0s in {x}! ' 20 | 'by conversion to a string...' 21 | ) 22 | x = str(factorial(x)) 23 | for i in range(1, len(x) + 1): 24 | if x[-i] != '0': 25 | return i - 1 26 | 27 | def third_computation(x): 28 | print(f'Computing the number of trailing 0s in {x}! the smart way...') 29 | nb_of_trailing_0s = 0 30 | power_of_five = 5 31 | while x >= power_of_five: 32 | nb_of_trailing_0s += x // power_of_five 33 | power_of_five *= 5 34 | return nb_of_trailing_0s 35 | -------------------------------------------------------------------------------- /03.exercies/10.Cycloidal curves/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/10.Cycloidal curves/.DS_Store -------------------------------------------------------------------------------- /03.exercies/10.Cycloidal curves/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/10.Cycloidal curves/Illustrations.zip -------------------------------------------------------------------------------- /03.exercies/11.Mysterious multiplication/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/11.Mysterious multiplication/.DS_Store -------------------------------------------------------------------------------- /03.exercies/11.Mysterious multiplication/mysterious_multiplication.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | seen_solution = False 5 | for x in range(100, 1_000): 6 | for y in range(10, 100): 7 | product_0 = x * (y % 10) 8 | if product_0 < 1_000: 9 | continue 10 | product_1 = x * (y // 10) 11 | if product_1 >= 1_000: 12 | continue 13 | total = product_0 + 10 * product_1 14 | if total >= 10_000: 15 | continue 16 | the_sum = x % 10 + y % 10 + product_0 % 10 + total % 10 17 | if x // 10 % 10 + y // 10 + product_0 // 10 % 10 + product_1 % 10\ 18 | + total // 10 % 10 != the_sum: 19 | continue 20 | if x // 100 + product_0 // 100 % 10 + product_1 // 10 % 10\ 21 | + total // 100 % 10 != the_sum: 22 | continue 23 | if product_0 // 1_000 + product_1 // 100 + total // 1_000 == the_sum: 24 | if seen_solution: 25 | print() 26 | seen_solution = True 27 | print(f'A solution with all columns adding up to {the_sum}:') 28 | print(' ', ' '.join(c for c in str(x))) 29 | print(' ', 'x ', ' '.join(c for c in str(y))) 30 | print(' -------') 31 | print(' ', ' '.join(c for c in str(product_0))) 32 | print(' ', ' '.join(c for c in str(product_1))) 33 | print(' -------') 34 | print(' ', ' '.join(c for c in str(total))) 35 | -------------------------------------------------------------------------------- /03.exercies/12.Pascal triangle/pascal1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/12.Pascal triangle/pascal1.png -------------------------------------------------------------------------------- /03.exercies/12.Pascal triangle/pascal2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/12.Pascal triangle/pascal2.png -------------------------------------------------------------------------------- /03.exercies/12.Pascal triangle/pascal3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/12.Pascal triangle/pascal3.png -------------------------------------------------------------------------------- /03.exercies/12.Pascal triangle/pascal_triangle.py: -------------------------------------------------------------------------------- 1 | # Prompts the user for a number N and prints out the first N + 1 lines of Pascal triangle. 2 | 3 | 4 | 5 | # Insert you code here 6 | -------------------------------------------------------------------------------- /03.exercies/12.Pascal triangle/pascal_triangle_scaffold_1.py: -------------------------------------------------------------------------------- 1 | # Prompts the user for a number N and prints out the first N + 1 lines of Pascal triangle. 2 | 3 | 4 | 5 | while True: 6 | try: 7 | N = int(input('Enter a nonnegative integer: ')) 8 | if N < 0: 9 | raise ValueError 10 | break 11 | except ValueError: 12 | print('Incorrect input, try again') 13 | 14 | pascal_triangle = [[1] * (n + 1) for n in range(N + 1)] 15 | for n in range(2, N + 1): 16 | # Insert your code to compute Pascal triangle 17 | width = len(str(pascal_triangle[N][N // 2])) 18 | # Insert yoru code to display Pascal triangle 19 | -------------------------------------------------------------------------------- /03.exercies/12.Pascal triangle/readme.md: -------------------------------------------------------------------------------- 1 | Write a program pascal_triangle.py that prompts the user for a number N and prints out the first N + 1 lines of Pascal triangle, making sure the numbers are nicely aligned, as illustrated below for N = 3, 7 and 11 respectively: 2 | 3 | 4 | 5 | 6 | Insert your code into pascal_triangle.py 7 | 8 | If you are stuck, but only when you are stuck, then use pascal_triangle_scaffold_1.py. -------------------------------------------------------------------------------- /03.exercies/12.Special triples/special_triples.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | def nb_of_consecutive_squares(n): 5 | if not sums_of_two_squares[n]: 6 | return 0 7 | if not sums_of_two_squares[n + 1]: 8 | return 1 9 | if not sums_of_two_squares[n + 2]: 10 | return 2 11 | return 3 12 | 13 | 14 | # The smallest integer whose square is a 4-digit number. 15 | upper_bound = 32 16 | # For all n in [100, 999], if n is found to be of the form a^2 + b^2 17 | # then sums_of_two_squares[n] will be set to (a, b) for the minimal 18 | # such pair (a, b) w.r.t. the natural ordering of pairs of integers. 19 | # Note that we waste the 100 first elements of the list; 20 | # we can afford it and this choice makes the program simpler. 21 | sums_of_two_squares = [None] * 1_000 22 | for i in range(upper_bound): 23 | for j in range(i, upper_bound): 24 | n = i * i + j * j 25 | if n < 100: 26 | continue 27 | if n >= 1_000: 28 | break 29 | if not sums_of_two_squares[n]: 30 | sums_of_two_squares[n] = i, j 31 | n = 100 32 | while n < 1_000: 33 | i = nb_of_consecutive_squares(n) 34 | if i < 3: 35 | # There is no potential triple before n + i + 1. 36 | n += i + 1 37 | continue 38 | print(f'({n}, {n + 1}, {n + 2}) ' 39 | f'(equal to ({sums_of_two_squares[n][0]}^2+' 40 | f'{sums_of_two_squares[n][1]}^2, ' 41 | f'{sums_of_two_squares[n + 1][0]}^2' 42 | f'+{sums_of_two_squares[n + 1][1]}^2, ' 43 | f'{sums_of_two_squares[n + 2][0]}^2' 44 | f'+{sums_of_two_squares[n + 2][1]}^2)) ' 45 | 'is a solution.' 46 | ) 47 | # We assume we could have two solutions of the form 48 | # (n, n + 1, n + 2) and (n + 1, n + 2, n + 3) 49 | # (but as the solution shows, this never happens...), 50 | # hence n is incremented by only 1 in the next iteration 51 | # of the loop. 52 | # We could avoid checking that sums_of_two_squares[n + 1] and 53 | # sums_of_two_squares[n + 2] are not equal to 0, but why make 54 | # the program more complicated for no significant gain? 55 | n += 1 56 | -------------------------------------------------------------------------------- /03.exercies/13.Taxicab numbers/taxicab.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from math import pow 5 | 6 | 7 | def taxicab(n, starting_from=2): 8 | solutions = [None] * n 9 | target = starting_from 10 | # Number of solutions found so far; should eventually reach n. 11 | m = 0 12 | while m < n: 13 | m = 0 14 | target += 1 15 | # Let a_cube be i ** 3 with i = 1, 2, 3... 16 | # If target - a_cube is also a cube, 17 | # then we have one decomposition of target 18 | # as a sum of two cubes. 19 | i = 1 20 | a_cube = 1 21 | while a_cube < target // 2: 22 | j = round(pow(target - a_cube, 1 / 3)) 23 | if a_cube + j ** 3 == target: 24 | solutions[m] = (i, j) 25 | m += 1 26 | if m == n: 27 | break 28 | i += 1 29 | a_cube = i ** 3 30 | print(f'The smallest integer greater than', starting_from, 31 | 'that can be written' 32 | ) 33 | print(f'in {n} different ways as the sum of two cubes is {target}:') 34 | for m in range(n): 35 | print(f' {target} = {solutions[m][0]}^3 + {solutions[m][1]}^3') 36 | -------------------------------------------------------------------------------- /03.exercies/14.Balanced single type brackets/balanced_single_type_brackets.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | def balanced_brackets_in(pattern): 5 | pattern = iter(pattern) 6 | for symbol in pattern: 7 | if not symbol.isspace(): 8 | break 9 | else: 10 | return True 11 | brackets = dict(zip('([{', ')]}')) 12 | if symbol not in brackets: 13 | for bracket in brackets: 14 | if symbol == brackets[bracket]: 15 | return extra_symbols_or_imbalanced(pattern, 16 | (bracket, brackets[bracket]) 17 | ) 18 | return 19 | nb_of_opening_brackets = 1 20 | for c in pattern: 21 | if c == symbol: 22 | nb_of_opening_brackets += 1 23 | elif c == brackets[symbol]: 24 | if not nb_of_opening_brackets: 25 | return extra_symbols_or_imbalanced(pattern, 26 | (symbol, brackets[symbol]) 27 | ) 28 | nb_of_opening_brackets -= 1 29 | elif not c.isspace(): 30 | return 31 | return not nb_of_opening_brackets 32 | 33 | def extra_symbols_or_imbalanced(pattern, brackets): 34 | if all(c.isspace() or c in brackets for c in pattern): 35 | return False 36 | return 37 | -------------------------------------------------------------------------------- /03.exercies/14.Encoding pairs of integers as natural numbers/plane_encoding.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Implements a function encode(a, b) and a function decode(n) for the one-to-one mapping 3 | from the set of pairs of integers onto the set of natural numbers described as follows: 4 | 5 | 16 15 14 13 12 6 | 17 4 3 2 11 7 | 18 5 0 1 10 8 | 19 6 7 8 9 9 | 20 21 ... 10 | 11 | That is, starting from the point (0,0) of the plane, we move to (1,0) 12 | and then spiral counterclockwise. 13 | ''' 14 | 15 | from math import sqrt 16 | 17 | 18 | def encode(a, b): 19 | pass 20 | # Replace pass above with your code 21 | 22 | 23 | def decode(n): 24 | pass 25 | # Replace pass above with your code 26 | 27 | -------------------------------------------------------------------------------- /03.exercies/14.Encoding pairs of integers as natural numbers/readme.md: -------------------------------------------------------------------------------- 1 | ## Encoding pairs of integers as natural numbers 2 | 3 | Complete the program plane_encoding.py that implements a function encode(a, b) and a function decode(n) for the one-to-one mapping from the set of pairs of integers onto the set of natural numbers, that can be graphically described as follows: 4 | 5 | 6 | That is, starting from the point (0, 0) of the plane, we move to (1, 0) and then spiral counterclockwise: 7 | 8 | encode(0,0) returns 0 and decode(0) returns (0,0) 9 | 10 | encode(1,0) returns 1 and decode(1) returns (1,0) 11 | 12 | encode(1,1) returns 2 and decode(2) returns (1,1) 13 | 14 | encode(0,1) returns 3 and decode(3) returns (0,1) 15 | 16 | encode(-1,1) returns 4 and decode(4) returns (-1,1) 17 | 18 | encode(-1,0) returns 5 and decode(5) returns (-1,0) 19 | 20 | encode(-1,-1) returns 6 and decode(6) returns (-1,-1) 21 | 22 | encode(0,-1) returns 7 and decode(7) returns (0,-1) 23 | 24 | encode(1,-1) returns 8 and decode(8) returns (1,-1) 25 | 26 | encode(2,-1) returns 9 and decode(9) returns (2,-1) 27 | . . . -------------------------------------------------------------------------------- /03.exercies/15.Roman numerals/readme.md: -------------------------------------------------------------------------------- 1 | Write a program that prints out the decimal value of a Roman numeral. 2 | 3 | Your program should accept the Roman numeral from the command line arguments. You may assume the Roman numeral is in the "standard" form, i.e., any digits involving 4 and 9 will always appear in the subtractive form. 4 | 5 | Sample interactions 6 | python roman_numerals.py II 7 | 2 8 | python roman_numerals.py IV 9 | 4 10 | python roman_numerals.py IX 11 | 9 12 | python roman_numerals.py XIX 13 | 19 14 | python roman_numerals.py XX 15 | 20 16 | python roman_numerals.py MDCCLXXVI 17 | 1776 18 | python roman_numerals.py MMXIX 19 | 2019 20 | Hints: 21 | 22 | Use a loop to iterate through the Roman numeral to figure out their value. 23 | 24 | Use a list of tuples to store the string characters and their respective values, compare the characters from the input to this list. 25 | 26 | Use a while loop so you can manually control the indices. -------------------------------------------------------------------------------- /03.exercies/15.Roman numerals/roman_numerals.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | numeral = sys.argv[1] 4 | 5 | # INSERT YOUR CODE HERE 6 | -------------------------------------------------------------------------------- /03.exercies/16.Canonical coin systems/canonical_coin_systems.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | try: 5 | amount = int(input('Input the amount: ')) 6 | if amount < 0: 7 | raise ValueError 8 | except ValueError: 9 | print('Incorrect value, try again.') 10 | face_values = [1, 2, 5, 10, 20, 50, 100] 11 | coins = {} 12 | amount_left = amount 13 | while amount_left: 14 | value = face_values.pop() 15 | if amount_left >= value: 16 | coins[value] = amount_left // value 17 | amount_left %= value 18 | nb_of_coins = sum(coins.values()) 19 | if nb_of_coins == 0: 20 | print('\nNo coin is needed.') 21 | elif nb_of_coins == 1: 22 | print(f'\nOne coin of value ${amount} is needed.') 23 | else: 24 | print(f'\n{nb_of_coins} coins are needed. The detail is:') 25 | for value in coins: 26 | print(f'{"$" + str(value):>8}: {coins[value]}') 27 | -------------------------------------------------------------------------------- /03.exercies/16.Canonical coin systems/readme.md: -------------------------------------------------------------------------------- 1 | Write a program that prompts the user for an amount, and outputs the minimal number of coins needed to yield that amount, as well as the detail of how many coins of each value are used. The available coins have a face value which is one of $1, $2, $5, $10, $20, $50, and $100. 2 | 3 | Insert your code into canonical_coin_systems.py. 4 | 5 | Here are examples of interactions: 6 | 7 | $ python3 canonical_coin_systems.py 8 | Input the desired amount: 10 9 | 10 | 1 banknote is needed. 11 | The detail is: 12 | $10: 1 13 | 14 | $ python3 canonical_coin_systems.py 15 | Input the desired amount: 739 16 | 17 | 12 banknotes are needed 18 | The detail is: 19 | $100: 7 20 | $20: 1 21 | $10: 1 22 | $5: 1 23 | $2: 2 24 | 25 | $ python3 canonical_coin_systems.py 26 | Input the desired amount: 35642 27 | 28 | 359 banknotes are needed 29 | The detail is: 30 | $100: 356 31 | $20: 2 32 | $2: 1 -------------------------------------------------------------------------------- /03.exercies/16.Longest sequence of consecutive letters/longest_sequence.py: -------------------------------------------------------------------------------- 1 | # Prompts the user for a string w of lowercase letters and outputs the 2 | # longest sequence of consecutive letters that occur in w, 3 | # but with possibly other letters in between, starting as close 4 | # as possible to the beginning of w. 5 | 6 | 7 | import sys 8 | 9 | # Insert your code here 10 | -------------------------------------------------------------------------------- /03.exercies/16.Longest sequence of consecutive letters/longest_sequence_scaffold_1.py: -------------------------------------------------------------------------------- 1 | # Prompts the user for a string w of lowercase letters and outputs the 2 | # longest sequence of consecutive letters that occur in w, 3 | # but with possibly other letters in between, starting as close 4 | # as possible to the beginning of w. 5 | 6 | 7 | import sys 8 | 9 | word = input('Please input a string of lowercase letters: ') 10 | if not all(c.islower() for c in word): 11 | print('Incorrect input.') 12 | sys.exit() 13 | word = [ord(c) for c in word] 14 | longest_length = 0 15 | start = None 16 | current_start = 0 17 | while current_start < len(word) - longest_length: 18 | pass 19 | # Replace pass above with your code 20 | 21 | print('The solution is:', ''.join(chr(word[start] + i) 22 | for i in range(longest_length) 23 | ) 24 | 25 | -------------------------------------------------------------------------------- /03.exercies/16.Longest sequence of consecutive letters/readme.md: -------------------------------------------------------------------------------- 1 | Write a program longest_sequence.py that prompts the user for a string w of lowercase letters and outputs the longest sequence of consecutive letters that occur in w, but with possibly other letters in between, starting as close as possible to the beginning of w. 2 | 3 | Insert your code into longest_sequence.py. 4 | 5 | See more details in the associated Jupyter notebook sheet longest_sequence.ipynb. 6 | 7 | If you are stuck, but only when you are stuck, then use longest_sequence_scaffold.py. -------------------------------------------------------------------------------- /03.exercies/17.Special products/special_products.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | # If i, j and k are numbers in the range [10, 99], i < j < k, 5 | # and every digit occurs at most once in i, j and k, then 6 | # 10 <= i <= 76, j <= 87, and k <= 98. 7 | min_i = 10 8 | max_i = 76 9 | max_j = 87 10 | max_k = 98 11 | for i in range(min_i, max_i + 1): 12 | i_digits = {i // 10, i % 10} 13 | if len(i_digits) != 2: 14 | continue 15 | for j in range(i + 1, max_j + 1): 16 | i_and_j_digits = i_digits.union((j // 10, j % 10)) 17 | if len(i_and_j_digits) != 4: 18 | continue 19 | for k in range(j + 1, max_k + 1): 20 | i_and_j_and_k_digits = i_and_j_digits.union((k // 10, k % 10)) 21 | if len(i_and_j_and_k_digits) != 6: 22 | continue 23 | product = i * j * k 24 | if product >= 1_000_000: 25 | break 26 | if set(int(i) for i in str(product)) == i_and_j_and_k_digits: 27 | print(f'{i} x {j} x {k} = {product} is a solution.') 28 | -------------------------------------------------------------------------------- /03.exercies/18.Closed paths/closed_paths.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | def closed_path(*x_y_coordinates): 5 | black_points = set() 6 | for i in range(1, len(x_y_coordinates), 2): 7 | y = x_y_coordinates[i] 8 | x_1, x_2 = sorted((x_y_coordinates[i - 1], 9 | x_y_coordinates[(i + 1) % len(x_y_coordinates)] 10 | ) 11 | ) 12 | for x in range(x_1, x_2): 13 | black_points.add((2 * y - 1, 2 * x - 1)) 14 | black_points.add((2 * y - 1, 2 * x)) 15 | black_points.add((2 * y - 1, 2 * x + 1)) 16 | for i in range(0, len(x_y_coordinates), 2): 17 | x = x_y_coordinates[i] 18 | y_1, y_2 = sorted((x_y_coordinates[(i - 1) % len(x_y_coordinates)], 19 | x_y_coordinates[i + 1] 20 | ) 21 | ) 22 | for y in range(y_1, y_2): 23 | black_points.add((2 * y - 1, 2 * x - 1)) 24 | black_points.add((2 * y, 2 * x - 1)) 25 | black_points.add((2 * y + 1, 2 * x - 1)) 26 | for y in range(2 * len(x_y_coordinates) + 1): 27 | for x in range(2 * len(x_y_coordinates) + 1): 28 | print('\N{Black Large Square}', end='')\ 29 | if (y, x) in black_points\ 30 | else print('\N{White Large Square}', end='') 31 | print() 32 | -------------------------------------------------------------------------------- /03.exercies/18.Mediants/mediant.py: -------------------------------------------------------------------------------- 1 | def mediants_to(p, q): 2 | pass 3 | # REPLACE pass ABOVE WITH YOUR CODE 4 | 5 | # POSSIBLY DEFINE OTHER FUNCTIONS 6 | 7 | -------------------------------------------------------------------------------- /03.exercies/19.Obtaining a sum from a subsequence of digits/readme.md: -------------------------------------------------------------------------------- 1 | ## Obtaining a sum from a subsequence of digits 2 | Write a program sum_of_digits.py that prompts the user for two natural numbers, say available_digits and desired_sum, and outputs the number of ways of selecting digits from available_digits that sum up to desired_sum. For instance, if available_digits is 12234 and sum is 5 then there are four (4) solutions: 3 | 4 | one solution is obtained by selecting 1 and both occurrences of 2 (1+2+2 = 5); 5 | 6 | one solution is obtained by selecting 1 and 4 (1+4 = 5); 7 | 8 | one solution is obtained by selecting the first occurrence of 2 and 3 (2+3 = 5); 9 | 10 | one solution is obtained by selecting the second occurrence of 2 and 3 (2+3 = 5). 11 | 12 | Here are possible interactions: 13 | 14 | Input a number that we will use as available digits: 12234 15 | Input a number that represents the desired sum: 5 16 | There are 4 solutions. 17 | Input a number that we will use as available digits: 11111 18 | Input a number that represents the desired sum: 5 19 | There is a unique solution. 20 | Input a number that we will use as available digits: 11111 21 | Input a number that represents the desired sum: 6 22 | There is no solution. 23 | Input a number that we will use as available digits: 1234321 24 | Input a number that represents the desired sum: 5 25 | There are 10 solutions. 26 | Insert your code into sum_of_digits.py 27 | 28 | If you are stuck, but only when you are stuck, then use sum_of_digits_scaffold.py -------------------------------------------------------------------------------- /03.exercies/19.Obtaining a sum from a subsequence of digits/sum_of_digits.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | # Insert your code here 4 | 5 | -------------------------------------------------------------------------------- /03.exercies/19.Obtaining a sum from a subsequence of digits/sum_of_digits_scaffold_1.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | def solve(digits, desired_sum): 5 | if desired_sum < 0: 6 | pass 7 | # Replace pass above with your code 8 | return 0 9 | if digits == 0: 10 | pass 11 | # Replace pass above with your code 12 | # Either take the last digit d from digits and try to 13 | # get desired_sum - d from the remaining digits, or do not take 14 | # the last digit and try to get desired_sum from the remaining 15 | # digits. 16 | # 17 | # Insert code here 18 | 19 | try: 20 | digits = int(input('Input a natural number for the available digits: ')) 21 | if digits < 0: 22 | raise ValueError 23 | except ValueError: 24 | print('Incorrect input, giving up.') 25 | sys.exit() 26 | try: 27 | desired_sum = int(input('Input a natural number for the desired sum: ')) 28 | if desired_sum < 0: 29 | raise ValueError 30 | except ValueError: 31 | print('Incorrect input, giving up.') 32 | sys.exit() 33 | nb_of_solutions = solve(digits, desired_sum) 34 | if nb_of_solutions == 0: 35 | print('There is no solution.') 36 | elif nb_of_solutions == 1: 37 | print('There is a unique solution.') 38 | else: 39 | print('There are', nb_of_solutions, 'solutions.') 40 | 41 | -------------------------------------------------------------------------------- /03.exercies/20.Merging two strings into a third one /merging_strings.py: -------------------------------------------------------------------------------- 1 | # Say that two strings s_1 and s_2 can be merged into a third 2 | # string s_3 if s_3 is obtained from s_1 by inserting 3 | # arbitrarily in s_1 the characters in s_2, respecting their 4 | # order. For instance, the two strings ab and cd can be merged 5 | # into abcd, or cabd, or cdab, or acbd, or acdb..., but not into 6 | # adbc nor into cbda. 7 | # 8 | # Prompts the user for 3 strings and displays the output as follows: 9 | # - If no string can be obtained from the other two by merging, 10 | # then the program outputs that there is no solution. 11 | # - Otherwise, the program outputs which of the strings can be obtained 12 | # from the other two by merging. 13 | 14 | 15 | # Insert your code here 16 | 17 | 18 | -------------------------------------------------------------------------------- /03.exercies/20.Merging two strings into a third one /merging_strings_scaffold.py: -------------------------------------------------------------------------------- 1 | # Say that two strings s_1 and s_2 can be merged into a third 2 | # string s_3 if s_3 is obtained from s_1 by inserting 3 | # arbitrarily in s_1 the characters in s_2, respecting their 4 | # order. For instance, the two strings ab and cd can be merged 5 | # into abcd, or cabd, or cdab, or acbd, or acdb..., but not into 6 | # adbc nor into cbda. 7 | # 8 | # Prompts the user for 3 strings and displays the output as follows: 9 | # - If no string can be obtained from the other two by merging, 10 | # then the program outputs that there is no solution. 11 | # - Otherwise, the program outputs which of the strings can be obtained 12 | # from the other two by merging. 13 | 14 | 15 | def can_merge(string_1, string_2, string_3): 16 | pass 17 | # Replace pass above with your code. 18 | # Think recursively 19 | 20 | 21 | ranks = 'first', 'second', 'third' 22 | shortest, in_between, longest =\ 23 | sorted(zip(ranks, 24 | (input(f'Please input the {rank} string: ') for rank in ranks), 25 | ), key=lambda x: len(x[1]) 26 | ) 27 | if not longest[1]: 28 | print('Any string can be obtained from the other two.') 29 | elif not shortest[1]: 30 | if in_between[1] == longest[1]: 31 | print(f'The {in_between[0]} and {longest[0]} strings can be obtained ' 32 | 'by merging the other two.' 33 | ) 34 | else: 35 | report_failure() 36 | elif len(longest[1]) != len(shortest[1]) + len(in_between[1])\ 37 | or not can_merge(shortest[1], in_between[1], longest[1]): 38 | report_failure() 39 | else: 40 | print(f'The {longest[0]} string can be obtained by merging the other two.') 41 | 42 | 43 | -------------------------------------------------------------------------------- /03.exercies/20.Merging two strings into a third one /readme.md: -------------------------------------------------------------------------------- 1 | Say that two strings s1 and s2 can be merged into a third string s3 if s3 is obtained from s1 by inserting arbitrarily in s1 the characters in s2, respecting their order. For instance, the two strings ab and cd can be merged into abcd, or cabd, or cdab, or acbd, or acdb, ..., but not into adbc nor into cbda. Write a program merging_strings.py that prompts the user for 3 strings and displays the output as follows: 2 | 3 | If no string can be obtained from the other two by merging, then the program outputs that there is no solution. 4 | 5 | Otherwise, the program outputs which of the strings can be obtained from the other two by merging. 6 | 7 | Here are possible interactions: 8 | 9 | Please input the first string: ab 10 | Please input the second string: cd 11 | Please input the third string: abcd 12 | The third string can be obtained by merging the other two. 13 | Please input the first string: ab 14 | Please input the second string: cdab 15 | Please input the third string: cd 16 | The second string can be obtained by merging the other two. 17 | Please input the first string: abcd 18 | Please input the second string: cd 19 | Please input the third string: ab 20 | The first string can be obtained by merging the other two. 21 | Please input the first string: ab 22 | Please input the second string: cd 23 | Please input the third string: adcb 24 | No string can be merged from the other two. 25 | Please input the first string: aaaaa 26 | Please input the second string: a 27 | Please input the third string: aaaa 28 | The first string can be obtained by merging the other two. 29 | Please input the first string: aaab 30 | Please input the second string: abcab 31 | Please input the third string: aaabcaabb 32 | The third string can be obtained by merging the other two. 33 | Please input the first string: ??got 34 | Please input the second string: ?it?go#t## 35 | Please input the third string: it### 36 | The second string can be obtained by merging the other two. 37 | Insert your code into merging_strings.py. 38 | 39 | If you are stuck, but only when you are stuck, then use merging_strings_scaffold.py. -------------------------------------------------------------------------------- /03.exercies/20.Powers in range/powers_in_range.py: -------------------------------------------------------------------------------- 1 | ## Written by Eric Martin for COMP9021 2 | 3 | 4 | from math import log, ceil 5 | 6 | 7 | m, n = (int(x) for x in input('Input two positive integers: ').split()) 8 | solutions = set() 9 | base = 2 10 | while base ** 2 <= n: 11 | power = ceil(log(m, base)) 12 | # For the case where log(m, base) is an integer, 13 | # but floating point computation overshoots it. 14 | if base ** (power - 1) >= m: 15 | power -= 1 16 | k = base ** power 17 | while k <= n: 18 | solutions.add((k, base, power)) 19 | power += 1 20 | k = base ** power 21 | base += 1 22 | solutions = sorted(solutions) 23 | if solutions: 24 | field_width = len(str(max(k for (k, _, _) in solutions))) 25 | for (k, base, power) in solutions: 26 | print(f'{k:{field_width}} = {base}^{power}') 27 | -------------------------------------------------------------------------------- /03.exercies/21.The 8 puzzle/9_puzzle_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/21.The 8 puzzle/9_puzzle_1.png -------------------------------------------------------------------------------- /03.exercies/21.The 8 puzzle/9_puzzle_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/21.The 8 puzzle/9_puzzle_2.png -------------------------------------------------------------------------------- /03.exercies/21.The 8 puzzle/eight_puzzle.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | 4 | def grid_if_valid_and_solvable_8_puzzle(grid): 5 | pass 6 | # Replace pass above with your code 7 | 8 | 9 | def validate_8_puzzle(grid): 10 | if grid_if_valid_and_solvable_8_puzzle(grid): 11 | print('This is a valid eight puzzle, and it is solvable.') 12 | else: 13 | print('This is an invalid or unsolvable eight puzzle.') 14 | 15 | def solve_8_puzzle(grid): 16 | grid = grid_if_valid_and_solvable_8_puzzle(grid) 17 | if not grid: 18 | return 19 | # Insert your code here 20 | 21 | 22 | -------------------------------------------------------------------------------- /03.exercies/21.The 8 puzzle/readme.md: -------------------------------------------------------------------------------- 1 | The 8 puzzle 2 | Dispatch the integers from 0 to 8, with 0 possibly changed to None, as a list of 3 lists of size 3, to represent a 9 puzzle. 3 | 4 | For instance, let [[4, 0, 8], [1, 3, 7], [5, 2, 6]] or [[4, None ,8], [1, 3, 7], [5, 2, 6]] represent the 9 puzzle 5 | 6 | 7 | with the 8 integers being printed on 8 tiles that are placed in a frame with one location being tile free. 8 | 9 | The aim is to slide tiles horizontally or vertically so as to eventually reach the configuration 10 | 11 | 12 | It can be shown that the puzzle is solvable iff the permutation of the integers 1, ..., 8, determined by reading those integers off the puzzle from top to bottom and from left to right, is even. This is clearly a necessary condition since: 13 | 14 | sliding a tile horizontally does not change the number of inversions; 15 | 16 | sliding a tile vertically changes the number of inversions by -2, 0 or 2; 17 | 18 | the parity of the identity is even. 19 | 20 | Complete the program eight_puzzle.py so as to have the functionality of the two functions: 21 | 22 | validate_8_puzzle(grid) that prints out whether or not grid is a valid representation of a solvable 8 puzzle; 23 | 24 | solve_8_puzzle(grid) that, assuming that grid is a valid representation of a solvable 8 puzzle, outputs a solution to the puzzle characterised as follows: 25 | 26 | the number of moves is minimal; 27 | 28 | at every stage, the preferences of the tile to slide are, from most preferred to least preferred: 29 | 30 | the tile above the empty cell (provided the latter is not in the top row), then 31 | 32 | the tile to the left of the empty cell (provided the latter is not in the left column), then 33 | 34 | the tile to the right of the empty cell (provided the latter is not in the right column), then 35 | 36 | the tile below the empty cell (provided the latter is not in the bottom row). 37 | 38 | Also see the corresponding Jupyter notebook sheet for a description of a possible algorithmic approach to implement solve_8_puzzle(grid). -------------------------------------------------------------------------------- /03.exercies/22.Dice rolls/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/22.Dice rolls/Illustrations.zip -------------------------------------------------------------------------------- /03.exercies/22.Dice rolls/dice_rolls.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from random import randint, seed 5 | 6 | from pygal import Bar 7 | from pygal.style import Style 8 | 9 | 10 | input_values = input('Enter N strictly positive integers ' 11 | '(number of sides of N dice): ' 12 | ).split() 13 | if input_values: 14 | dice = [] 15 | incorrect_input = False 16 | for i in input_values: 17 | try: 18 | nb_of_sides = int(i) 19 | if nb_of_sides <= 0: 20 | raise ValueError 21 | dice.append(nb_of_sides) 22 | except ValueError: 23 | dice.append(6) 24 | incorrect_input = True 25 | if incorrect_input: 26 | print('Some of the values, incorrect, have been replaced ' 27 | 'with the default value of 6.' 28 | ) 29 | else: 30 | print('You did not enter any value, a single standard ' 31 | 'six-sided die will be cast.' 32 | ) 33 | dice = [6] 34 | try: 35 | nb_of_rolls = int(input('Enter the desired number of rolls: ')) 36 | if nb_of_rolls < 1: 37 | raise ValueError 38 | except ValueError: 39 | print('No valid input was provided, so the default value of ' 40 | '1,000 will be used.' 41 | ) 42 | nb_of_rolls = 1_000 43 | try: 44 | for_seed = int(input('Feed the seed if desired: ')) 45 | except ValueError: 46 | for_seed = 0 47 | seed(for_seed) 48 | rolls = [sum(randint(1, nb_of_sides) for nb_of_sides in dice) 49 | for _ in range(nb_of_rolls) 50 | ] 51 | range_of_sums = range(len(dice), sum(dice) + 1) 52 | counts = [{'value': count, 'label': f'Frequency: {count / nb_of_rolls:.2f}'} 53 | for count in (rolls.count(i) for i in range_of_sums) 54 | ] 55 | histogram = Bar(style=Style(colors=('#228B22',), major_label_font_size=12), 56 | show_legend=False 57 | ) 58 | histogram.title = f'Simulation for {nb_of_rolls} rolls of the dice: '\ 59 | f'{sorted(dice)}' 60 | histogram.x_labels = [str(i) for i in range_of_sums] 61 | histogram.x_title = 'Possible sums' 62 | histogram.y_title = 'Counts' 63 | histogram.add('', counts) 64 | histogram.render_to_file('dice_rolls__' + '_'.join(str(die) for die in dice) 65 | + f'__{nb_of_rolls}.svg' 66 | ) 67 | -------------------------------------------------------------------------------- /03.exercies/22.Magic squares/magic_squares.py: -------------------------------------------------------------------------------- 1 | # Given a positive integer n, a magic square of order n is a matrix of size n x n 2 | # that stores all numbers from 1 up to n^2 and such that the sum of the n rows, 3 | # the sum of the n columns, and the sum of the two diagonals is constant, 4 | # hence equal to n(n^2+1)/2. 5 | 6 | 7 | def is_magic_square(square): 8 | pass 9 | # Replace pass above with your code 10 | 11 | # Possibly define other functions 12 | 13 | def print_square(square): 14 | pass 15 | # Replace pass above with your code 16 | 17 | -------------------------------------------------------------------------------- /03.exercies/22.Magic squares/readme.md: -------------------------------------------------------------------------------- 1 | Given a positive integer nn, a magic square of order nn is a matrix of size n \times nn×n that stores all numbers from 1 up to n^2n 2 | 2 3 | and such that the sum of the nn rows, the sum of the nn columns, and the sum of the two diagonals is constant, hence equal to n(n^2+1)/2n(n 4 | 2 5 | +1)/2. 6 | 7 | Implement in the file magic_squares.py the function print_square(square), that prints a list of lists that represents a square, and the function is_magic_square(square), that checks whether a list of lists is a magic square. 8 | 9 | See the corresponding Jupyter notebook sheet for much more on magic squares. -------------------------------------------------------------------------------- /03.exercies/23.Colombo sequence/colombo.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | def colombo(n): 5 | sequence = [1, 2, 2] 6 | i = 3 7 | while n > len(sequence): 8 | sequence.extend([i] * sequence[i - 1]) 9 | i += 1 10 | return sequence[: n] 11 | -------------------------------------------------------------------------------- /03.exercies/23.Unit fractions/unit_fractions.py: -------------------------------------------------------------------------------- 1 | 2 | from math import gcd 3 | 4 | 5 | # Possibly define other functions 6 | 7 | def fibonacci_decomposition(N, D): 8 | pass 9 | # Replace pass above with your code 10 | 11 | def shortest_length_decompositions(N, D): 12 | pass 13 | # Replace pass above with your code 14 | 15 | 16 | -------------------------------------------------------------------------------- /03.exercies/24.Diophantine equations/diophantine_equation.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | def diophantine(equation): 5 | pass 6 | # REPLACE pass ABOVE WITH YOUR CODE 7 | 8 | # POSSIBLY DEFINE OTHER FUNCTIONS 9 | 10 | -------------------------------------------------------------------------------- /03.exercies/24.Look-and-say sequences/look_and_say.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from itertools import chain 5 | 6 | 7 | def look_and_say(d, n): 8 | digits = [d] 9 | for i in range(n): 10 | boundaries = list(chain((0,), (i for i in range(1, len(digits)) 11 | if digits[i] != digits[i - 1] 12 | ), (len(digits),) 13 | ) 14 | ) 15 | digits = list(chain(*zip((boundaries[i + 1] - boundaries[i] 16 | for i in range(len(boundaries) - 1) 17 | ), (digits[boundaries[i]] 18 | for i in range(len(boundaries) - 1) 19 | ) 20 | ) 21 | ) 22 | ) 23 | return int(''.join(str(d) for d in digits)) 24 | -------------------------------------------------------------------------------- /03.exercies/25.Decomposition in prime factors/prime_factors.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict 2 | from math import sqrt 3 | 4 | 5 | def prime_factors_of(n): 6 | if n < 2: 7 | return 8 | factors = defaultdict(int) 9 | rest = n 10 | while not rest % 2: 11 | rest //= 2 12 | factors[2] += 1 13 | potential_factor = 1 14 | while rest > 1: 15 | try: 16 | upper_bound = round(sqrt(rest)) 17 | # We could implement our own square root function to work on 18 | # integers, but if n is massively large, then our only hope is 19 | # that its prime decomposition consists of not too large primes 20 | # with high multiplicities, hence it is not worth bothering. 21 | # Bounding the search for prime factors at most equal to the 22 | # square root of rest is only valuable if the greatest prime 23 | # factor of rest is large (though of course not excessively so) 24 | # and significantly larger than the second greatest prime factor 25 | # of n. 26 | except OverflowError: 27 | upper_bound = rest 28 | while (potential_factor := potential_factor + 2) <= upper_bound: 29 | if not rest % potential_factor: 30 | while not rest % potential_factor: 31 | rest //= potential_factor 32 | factors[potential_factor] += 1 33 | break 34 | # No factor at most equal to upper_bound was found for rest, 35 | # hence rest is prime. 36 | else: 37 | factors[rest] = 1 38 | rest = 1 39 | print(n, '=', ' x '.join(f'{factor}^{e}' if e > 1 else f'{factor}' 40 | for (factor, e) in factors.items() 41 | ) 42 | ) 43 | -------------------------------------------------------------------------------- /03.exercies/26.Change making/change_making.py: -------------------------------------------------------------------------------- 1 | # Prompts the user for the face values of coins and their associated quantities, 2 | # as well as for an amount, and if possible, outputs the minimal number of coins 3 | # needed to match that amount, as well as the detail of how many coins 4 | # of each type value are used. 5 | 6 | 7 | # Insert your code here 8 | -------------------------------------------------------------------------------- /03.exercies/26.Sydney temperatures/sydney_temperatures.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/26.Sydney temperatures/sydney_temperatures.pdf -------------------------------------------------------------------------------- /03.exercies/26.Sydney temperatures/sydney_temperatures.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | # Data downloaded from 4 | # http://www.bom.gov.au/climate/averages/tables/cw_066062.shtml 5 | 6 | 7 | import csv 8 | from calendar import month_name 9 | from math import floor, ceil 10 | import sys 11 | 12 | from matplotlib import pyplot as plt 13 | 14 | 15 | datafile = 'IDCJCM0037_066062.csv' 16 | try: 17 | with open(datafile) as csvfile: 18 | file = csv.reader(csvfile) 19 | for _ in range(12): 20 | next(file) 21 | mean_max_temperatures = [float(i) for i in next(file)[1 : 13]] 22 | for _ in range(9): 23 | next(file) 24 | mean_min_temperatures = [float(i) for i in next(file)[1 : 13]] 25 | except FileNotFoundError: 26 | print(f'Could not open {datafile}, giving up.') 27 | sys.exit() 28 | min_temperature = floor(min(mean_min_temperatures)) 29 | max_temperature = ceil(max(mean_max_temperatures)) 30 | min_dec_jan = (mean_min_temperatures[0] + mean_min_temperatures[-1]) / 2 31 | max_dec_jan = (mean_max_temperatures[0] + mean_max_temperatures[-1]) / 2 32 | mean_min_temperatures = [min_dec_jan] + mean_min_temperatures + [min_dec_jan] 33 | mean_max_temperatures = [max_dec_jan] + mean_max_temperatures + [max_dec_jan] 34 | 35 | temperatures = plt.figure(dpi=220, figsize=(5, 3.5)) 36 | plt.axis([0.5, 12.5, min_temperature - 1, max_temperature + 1]) 37 | plt.xticks(range(1, 13), [month_name[i] for i in range(1, 13)], fontsize=8) 38 | plt.yticks([i / 2 for i in range(min_temperature * 2, max_temperature * 2 + 1) 39 | ], fontsize=4) 40 | xrange = [0.5] + list(range(1, 13)) + [12.5] 41 | plt.plot(xrange, mean_max_temperatures, c='red') 42 | plt.plot(xrange, mean_min_temperatures, c='blue') 43 | plt.fill_between(xrange, mean_min_temperatures, mean_max_temperatures, 44 | facecolor='grey', alpha=0.1 45 | ) 46 | plt.title('Mean min and max temperatures in Sydney', fontsize=10) 47 | plt.grid(True) 48 | temperatures.autofmt_xdate() 49 | plt.show() 50 | -------------------------------------------------------------------------------- /03.exercies/27.Balanced multiple type brackets/balanced_multiple_type_brackets.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | def balanced_brackets_in(pattern): 5 | pattern = iter(pattern) 6 | for c in pattern: 7 | if not c.isspace(): 8 | break 9 | else: 10 | return True 11 | brackets = dict(zip('([{', ')]}')) 12 | stack = [] 13 | while True: 14 | if c in brackets: 15 | stack.append(brackets[c]) 16 | elif c in brackets.values(): 17 | try: 18 | if stack.pop() != c: 19 | raise IndexError 20 | except IndexError: 21 | if all(c.isspace() or c in brackets or c in brackets.values() 22 | for c in pattern 23 | ): 24 | return False 25 | return 26 | elif not c.isspace(): 27 | return 28 | try: 29 | c = next(pattern) 30 | except StopIteration: 31 | return not stack 32 | -------------------------------------------------------------------------------- /03.exercies/28.Minimal word extensions/minimal_word_extensions.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | letters = input('Enter uppercase letters: ') 5 | if not all(c.isupper() for c in letters): 6 | letters = ''.join(c for c in letters if c.isupper()) 7 | print(f"I only keep the uppercase letters, so work with '{letters}'.") 8 | with open('dictionary.txt') as dictionary: 9 | min_length = float('inf') 10 | words = [] 11 | for word in dictionary: 12 | if len(word) > min_length + 1: 13 | continue 14 | word = word.rstrip() 15 | index = 0 16 | for e in letters: 17 | index = word.find(e, index) 18 | if index == -1: 19 | break 20 | else: 21 | if len(word) < min_length: 22 | min_length = len(word) 23 | words = [word] 24 | elif len(word) == min_length: 25 | words.append(word) 26 | if not words: 27 | print('No word in the dictionary embeds', letters, end='.\n') 28 | elif len(words) == 1 and words[0] == letters: 29 | print(letters, 'is a word in the dictionary.') 30 | else: 31 | print(f"The shortest words in the dictionary that embed '{letters}' are:") 32 | for word in words: 33 | print(' ', word) 34 | -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/Practice Exercises_Week10.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/28.Practice Exercises/Practice Exercises_Week10.pdf -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/Week 10 - Practice Exercises Solutions.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/28.Practice Exercises/Week 10 - Practice Exercises Solutions.zip -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/Week 10 - Practice Exercises.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/28.Practice Exercises/Week 10 - Practice Exercises.zip -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/election_1.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/28.Practice Exercises/election_1.xlsx -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/election_2.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/28.Practice Exercises/election_2.xlsx -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/election_3.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/28.Practice Exercises/election_3.xlsx -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/election_4.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/28.Practice Exercises/election_4.xlsx -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/election_5.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/28.Practice Exercises/election_5.xlsx -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/election_6.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/28.Practice Exercises/election_6.xlsx -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/word_search_1.txt: -------------------------------------------------------------------------------- 1 | N D A O E L D L O G B M N E 2 | I T D C M E A I N R U T S L 3 | C L U U E I C G G G O L I I 4 | K M U I M U I D I R I A L T 5 | E U R T U N G S T E N B V H 6 | L I L S L T T U L R U O E I 7 | C M A T E T I U R D R C R U 8 | I D S C A M A G N E S I U M 9 | M A M P D M U I N A T I T I 10 | P C N P L A T I N U M D L L 11 | H Z E M A N G A N E S E I G 12 | M G I T I N R U N O R I T C 13 | R I A N N A M E R C U R Y N 14 | U O T C C R E P P O C E E R 15 | -------------------------------------------------------------------------------- /03.exercies/28.Practice Exercises/word_search_2.txt: -------------------------------------------------------------------------------- 1 | 2 | W M B R W P P O P E R R I W 3 | 4 | E L M N N M L B I A P C I K 5 | 6 | B E O R R O Y G R E P W E O 7 | 8 | K N G E R R M O A E P A R G 9 | 10 | I I R E M Y E E O R P R Y R 11 | 12 | W O K L M I R A L G A A O A 13 | 14 | I B M M S O L L E L P P A S 15 | 16 | E A O W O R A N G E R O E P 17 | 18 | W A T E R M E L O N L R R B 19 | 20 | P A N M A L B R R A W P P E 21 | 22 | B A N A N A E A A G B N R R 23 | 24 | A P B Y R R E B K C A L B R 25 | 26 | B A N W B L U E B E R R Y Y 27 | 28 | A O I L U A T P T E A N N E 29 | 30 | 31 | -------------------------------------------------------------------------------- /03.exercies/29.Hasse diagrams/hasse_diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/29.Hasse diagrams/hasse_diagram.png -------------------------------------------------------------------------------- /03.exercies/29.Hasse diagrams/hasse_diagram.py: -------------------------------------------------------------------------------- 1 | from collections import defaultdict, namedtuple 2 | from functools import reduce 3 | from itertools import product 4 | from operator import mul, itemgetter 5 | 6 | 7 | def make_hasse_diagram(n): 8 | pass 9 | -------------------------------------------------------------------------------- /03.exercies/29.Hasse diagrams/hasse_diagrams.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/29.Hasse diagrams/hasse_diagrams.pdf -------------------------------------------------------------------------------- /03.exercies/29.Hasse diagrams/hasse_diagrams.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from collections import defaultdict, namedtuple 5 | from functools import reduce 6 | from itertools import product 7 | from operator import mul, itemgetter 8 | 9 | 10 | def make_hasse_diagram(n): 11 | prime_factors = {} 12 | p = 2 13 | while n != 1: 14 | if n % p == 0: 15 | k = 1 16 | while n % p == 0: 17 | n //= p 18 | k += 1 19 | # prime_factors[p] is 1 + p's multiplicity in n 20 | prime_factors[p] = k 21 | p += 1 22 | factors = {1: '1'} 23 | edges = {p: set() for p in prime_factors} 24 | vertices = defaultdict(lambda: (set(), set())) 25 | vertices[1][1].update(prime_factors) 26 | possible_powers = product(*(range(i) for i in prime_factors.values())) 27 | # Discard (0, ..., 0): 1 is special 28 | next(possible_powers) 29 | for powers in possible_powers: 30 | factor = reduce(mul, (p ** m for (p, m) in zip(prime_factors, powers))) 31 | factors[factor] = 'x'.join(m == 1 and str(p) 32 | or '^'.join((str(p), str(m))) 33 | for (p, m) in zip(prime_factors, powers) 34 | if m 35 | ) 36 | for (p, m) in filter(itemgetter(1), zip(prime_factors, powers)): 37 | smaller_factor = factor // p 38 | edges[p].add((smaller_factor, factor)) 39 | vertices[smaller_factor][1].add(factor) 40 | vertices[factor][0].add(smaller_factor) 41 | sorted_factors = sorted(factors) 42 | return namedtuple('HasseDiagram', 43 | ['factors', 'edges', 'vertices'] 44 | )({factor: factors[factor] for factor in sorted_factors}, 45 | {p: sorted(edges[p]) for p in prime_factors}, 46 | {v: (sorted(vertices[v][0]), sorted(vertices[v][1])) 47 | for v in sorted_factors 48 | } 49 | ) 50 | -------------------------------------------------------------------------------- /03.exercies/29.Hasse diagrams/readme.md: -------------------------------------------------------------------------------- 1 | Let a strictly positive integer n be given. Let D be the set of divisors of n. Let k be the number of prime divisors of n (that is, the number of prime numbers in D). The members of D can be arranged as the vertices of a solid in a k-dimensional space as illustrated below for n = 12 (in which case D = {1,2,3,4,6,12} and k = 2) and for n = 30 (in which case D = {1,2,3,5,6,10,15,30} and k = 3). 2 | 3 | Each of the solids' vertices is associated with two collections of nodes: those "directly below'' it, and those "directly above'' it. In particular, the prime divisors of n are "directly above'' 1, and no vertex is below 1; n has exactly k vertices "directly below'' it, and no vertex is above n. This suggests considering a dictionary whose keys are the members of D (inserted from smallest to largest), and as value for a given key d, the pair of ordered lists of members of D "directly below'' d and "directly above'' d, respectively. 4 | 5 | The solids exhibit k distinct "edge directions'', one for each prime divisor of n, defining a partition of the solids' edges. One can represent this partition as a dictionary whose keys are the prime divisors of n (inserted from smallest to largest), and as value for a given key p, the ordered list of ordered pairs of members of D that make up the endpoints of the edges whose "direction'' is associated with p. 6 | 7 | 8 | The program hasse_diagram.py defines a function make_hasse_diagram() that returns a named tuple HasseDiagram with three attributes: 9 | 10 | factors, for a dictionary whose keys are the members of D, and as value for a given key d (1 excepted), a string that represents the prime decomposition of d, using x for multiplication and ^ for exponentiation, displaying only exponents greater than 1; 11 | 12 | vertices, for the first dictionary previously defined; 13 | 14 | edges, for the second dictionary previously defined. 15 | 16 | Replace pass in hasse_diagram.py with your code. 17 | 18 | Except for namedtuple, hasse_diagram.py imports a number of classes and functions from various modules that are used in the solution, but that other good solutions will make no use of. -------------------------------------------------------------------------------- /03.exercies/30.Sierpinski triangle/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/30.Sierpinski triangle/Illustrations.zip -------------------------------------------------------------------------------- /03.exercies/30.Sierpinski triangle/sierpinski_triangle.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | dim = 128 5 | 6 | 7 | with open('sierpinski_triangle.tex', 'w') as latex_file: 8 | print('\\documentclass[10pt]{article}\n' 9 | '\\usepackage{tikz}\n' 10 | '\\pagestyle{empty}\n' 11 | '\n' 12 | '\\begin{document}\n' 13 | '\n' 14 | '\\vspace*{\\fill}\n' 15 | '\\begin{center}\n' 16 | '\\begin{tikzpicture}[scale=0.047]', file=latex_file 17 | ) 18 | for n in range(dim): 19 | for k in range(n + 1): 20 | if k | n == n: 21 | print(f'\\fill({2 * k - n},{-(2 * n)}) ' 22 | f'rectangle({2 * k - n + 2},{-(2 * n) + 2});', 23 | file=latex_file 24 | ) 25 | print('\\end{tikzpicture}\n' 26 | '\\end{center}\n' 27 | '\\vspace*{\\fill}\n' 28 | '\n' 29 | '\\end{document}\n', file=latex_file 30 | ) 31 | -------------------------------------------------------------------------------- /03.exercies/30.Sierpinski triangle/sierpinski_triangle_solution.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/30.Sierpinski triangle/sierpinski_triangle_solution.pdf -------------------------------------------------------------------------------- /03.exercies/31.Random walk/random_walk.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/31.Random walk/random_walk.pdf -------------------------------------------------------------------------------- /03.exercies/31.Random walk/random_walk.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from itertools import product 5 | from operator import add 6 | from random import choice 7 | 8 | import matplotlib.pyplot as plt 9 | 10 | 11 | def generate_random_walk(length=50_000): 12 | possible_moves = [p for p in product(range(-4, 5), repeat=2) 13 | if p != (0, 0) 14 | ] 15 | walk = [(0, 0)] 16 | for _ in range(length): 17 | move = choice(possible_moves) 18 | walk.append(tuple(map(add, walk[-1], move))) 19 | return walk 20 | 21 | 22 | random_walk = generate_random_walk() 23 | plt.figure(dpi=220, figsize=(5, 3)) 24 | plt.scatter(*tuple(zip(*random_walk)), c=tuple(range(len(random_walk))), 25 | cmap=plt.cm.Blues, edgecolor='none', s=1 26 | ) 27 | plt.scatter(*random_walk[0], c='green', edgecolors='none', s=10) 28 | plt.scatter(*random_walk[-1], c='red', edgecolors='none', s=10) 29 | plt.axis('off') 30 | plt.show() 31 | -------------------------------------------------------------------------------- /03.exercies/33.Multibases/multibases.py: -------------------------------------------------------------------------------- 1 | ## Written by Eric Martin for COMP9021 2 | 3 | 4 | def max_number_for(multibase): 5 | max_number = 0 6 | b = 1 7 | for i in range(1, len(multibase) + 1): 8 | max_number += b * (multibase[-i] - 1) 9 | b *= multibase[-i] 10 | return max_number 11 | 12 | def conversion_to_base_10(n, *, multibase): 13 | digits = [int(e) for e in str(n)] 14 | if len(digits) > len(multibase)\ 15 | or any(digits[-i] >= multibase[-i] for i in range(1, len(digits) + 1)): 16 | return 17 | b = multibase[-1] 18 | base_10_representation = digits[-1] 19 | for i in range(2, len(digits) + 1): 20 | base_10_representation += b * digits[-i] 21 | b *= multibase[-i] 22 | return base_10_representation 23 | 24 | def conversion_to_multibase(n, *, multibase): 25 | bases = list(reversed(multibase)) 26 | powers = [multibase.pop()] if len(multibase) > 1 else [] 27 | while len(multibase) > 1: 28 | powers.append(powers[-1] * multibase.pop()) 29 | multibase_representation = 0 30 | try: 31 | for _ in range(len(powers)): 32 | power = powers.pop() 33 | d = n // power 34 | if d >= bases.pop(): 35 | raise IndexError 36 | multibase_representation = multibase_representation * 10 + d 37 | n %= power 38 | if n >= bases.pop(): 39 | raise IndexError 40 | multibase_representation = multibase_representation * 10 + n 41 | except IndexError: 42 | return 43 | return multibase_representation 44 | -------------------------------------------------------------------------------- /03.exercies/34.Longest sequence of consecutive letters/longest_sequence.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | import sys 5 | 6 | 7 | word = input('Please input a string of lowercase letters: ') 8 | if not all(c.islower() for c in word): 9 | print('Incorrect input.') 10 | sys.exit() 11 | word = [ord(c) for c in word] 12 | longest_length = 0 13 | start = None 14 | current_start = 0 15 | while current_start < len(word) - longest_length: 16 | current_length = 1 17 | last_in_sequence = word[current_start] 18 | for i in range(current_start + 1, len(word)): 19 | if word[i] - last_in_sequence == 1: 20 | current_length += 1 21 | last_in_sequence = word[i] 22 | if current_length > longest_length: 23 | longest_length = current_length 24 | start = current_start 25 | current_start += 1 26 | print('The solution is:', ''.join(chr(word[start] + i) 27 | for i in range(longest_length) 28 | ) 29 | ) 30 | -------------------------------------------------------------------------------- /03.exercies/35.Special sequences of prime numbers/consecutive_primes.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from math import sqrt 5 | 6 | 7 | def is_prime(n): 8 | # Only used to test odd numbers. 9 | return all(n % d for d in range(3, round(sqrt(n)) + 1, 2)) 10 | 11 | 12 | print('The solutions are:\n') 13 | # The list of all even i's such that a + i is one of 14 | # a, b, c, d, e, f. 15 | good_leaps = tuple(sum(range(0, k, 2)) for k in range(2, 13, 2)) 16 | for a in range(10_001, 100_000 - good_leaps[-1], 2): 17 | # i should be in good_leaps iff a + i is prime 18 | # for i = 0, 2, 4, ..., 30. 19 | if all(((i in good_leaps) == is_prime(a + i)) 20 | for i in range(0, good_leaps[-1] + 1, 2) 21 | ): 22 | print(' '.join((str(a + i) for i in good_leaps))) 23 | -------------------------------------------------------------------------------- /03.exercies/36.Miller Rabin primality test/miller_rabin_primality_test.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from math import sqrt 5 | 6 | 7 | def witnesses_is_not_prime(a, p): 8 | if not p % a: 9 | return True 10 | bits = bin(p - 1)[2 :] 11 | one_or_p_minus_one = {1, p - 1} 12 | power = a 13 | for b in bits[1 :]: 14 | previous_power = power 15 | power = power ** 2 % p 16 | if power == 1 and previous_power not in one_or_p_minus_one: 17 | return True 18 | if b == '1': 19 | power = power * a % p 20 | return power != 1 21 | 22 | def miller_rabin_primality_test(witnesses, p): 23 | return not any(witnesses_is_not_prime(a, p) for a in witnesses) 24 | 25 | def smallest_miller_rabin_primality_test_failure(witnesses, upper_bound): 26 | sieve = sieve_of_primes_up_to(upper_bound) 27 | for i in range(max(witnesses) + 1, len(sieve)): 28 | if not sieve[i] and miller_rabin_primality_test(witnesses, 2 * i + 1): 29 | return 2 * i + 1 30 | 31 | def sieve_of_primes_up_to(n): 32 | # We let primes_sieve encode the sequence 33 | # (2, 3, 5, 7, 9, 11, ..., n') with n' equal to n if n is odd and 34 | # n - 1 is n is even. The index of n' is n_index 35 | n_index = (n - 1) // 2 36 | sieve = [True] * (n_index + 1) 37 | for k in range(1, (round(sqrt(n)) + 1) // 2): 38 | if sieve[k]: 39 | # If k is the index of p then 2 * k * (k + 1) is the index 40 | # of p ** 2. Also, we increment the value by 2p, which 41 | # corresponds to increasing the index by 2 * k + 1. 42 | for i in range(2 * k * (k + 1), n_index + 1, 2 * k + 1): 43 | sieve[i] = False 44 | return sieve 45 | -------------------------------------------------------------------------------- /03.exercies/37.Game of nim/game_of_nim.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | from itertools import cycle 3 | from operator import xor 4 | from random import choice, randrange, seed 5 | import sys 6 | 7 | # POSSIBLY DEFINE FUNCTIONS HERE 8 | 9 | try: 10 | piles = [int(n) for n in input('Describe the piles: ').split()] 11 | if any(n < 0 for n in piles): 12 | raise ValueError 13 | except ValueError: 14 | print('Incorrect description, giving up!') 15 | # INSERT YOUR CODE HERE 16 | -------------------------------------------------------------------------------- /03.exercies/37.Game of nim/readme.md: -------------------------------------------------------------------------------- 1 | ## Game of nim 2 | See description in associated Jupyter notebook sheet game_of_nim.ipynb. 3 | 4 | Insert your code in game_of_nim.py (you might find some or all of the imported modules useful, though you do not have to use them). -------------------------------------------------------------------------------- /03.exercies/38.Predictive parser/predictive_parser.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from functools import partial 5 | from operator import add, mul, sub, truediv 6 | from math import isnan 7 | 8 | 9 | additive_operators = {'+': add, '-': sub} 10 | multiplicative_operators = {'*': mul, '/': truediv} 11 | 12 | def evaluate(expression): 13 | if any(not (c.isdigit() or c.isspace() or c in '()+-*/') 14 | for c in expression 15 | ): 16 | return 17 | tokens = [c for c in expression if not c.isspace()] 18 | tokens.reverse() 19 | value = evaluate_expression_or_term(additive_operators, tokens) 20 | if tokens or value is None: 21 | return 22 | if isnan(value): 23 | raise ZeroDivisionError 24 | return value 25 | 26 | def evaluate_expression_or_term(operators, tokens): 27 | evaluation_function = partial(evaluate_expression_or_term, 28 | multiplicative_operators 29 | ) if '+' in operators\ 30 | else evaluate_factor 31 | value = evaluation_function(tokens) 32 | if value is None: 33 | return 34 | while tokens and tokens[-1] in operators: 35 | operator = tokens.pop() 36 | other_value = evaluation_function(tokens) 37 | if other_value is None: 38 | return 39 | try: 40 | value = operators[operator](value, other_value) 41 | except ZeroDivisionError: 42 | value = float('nan') 43 | return value 44 | 45 | def evaluate_factor(tokens): 46 | if not tokens: 47 | return 48 | token = tokens.pop() 49 | if token == '(': 50 | value = evaluate_expression_or_term(additive_operators, tokens) 51 | if value is None or not tokens or tokens.pop() != ')': 52 | return 53 | return value 54 | if token.isdigit(): 55 | return evaluate_number(int(token), tokens) 56 | 57 | def evaluate_number(digit, tokens): 58 | number = digit 59 | while tokens and tokens[-1].isdigit(): 60 | number = number * 10 + int(tokens.pop()) 61 | return number 62 | -------------------------------------------------------------------------------- /03.exercies/39.Postfix expressions/postfix_expression.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from operator import add, sub, mul, floordiv 5 | 6 | def evaluate(expression): 7 | operators = {'+': add, '-': sub, '*': mul, '/': floordiv} 8 | stack = [] 9 | processing_number = False 10 | for c in expression: 11 | if c.isspace(): 12 | processing_number = False 13 | elif c.isdigit(): 14 | if not processing_number: 15 | stack.append(int(c)) 16 | processing_number = True 17 | elif stack[-1]: 18 | stack[-1] = stack[-1] * 10 + int(c) 19 | else: 20 | return 21 | elif c in operators: 22 | try: 23 | operand_2 = stack.pop() 24 | stack[-1] = operators[c](stack[-1], operand_2) 25 | except IndexError: 26 | return 27 | except ZeroDivisionError: 28 | if not stack[-1]: 29 | stack[-1] = float('nan') 30 | elif stack[-1] > 0: 31 | stack[-1] = float('inf') 32 | else: 33 | stack[-1] = float('-inf') 34 | processing_number = False 35 | else: 36 | return 37 | if len(stack) != 1: 38 | return 39 | return stack[-1] 40 | -------------------------------------------------------------------------------- /03.exercies/40.Shortest distance in grid/shortest_distance.py: -------------------------------------------------------------------------------- 1 | # Written by Eric Martin for COMP9021 2 | 3 | 4 | from itertools import chain 5 | from math import hypot 6 | 7 | 8 | grid = [] 9 | with open('grid.txt') as file: 10 | for line in file: 11 | grid.append([int(x) for x in line.split()]) 12 | print('Here is the grid:\n') 13 | for line in grid: 14 | print('', ''.join({0: '\N{White Large Square}', 15 | 1: '\N{Black Large Square}' 16 | }[e] for e in line 17 | ) 18 | ) 19 | print() 20 | height = len(grid) 21 | width = len(grid[0]) 22 | solutions = set() 23 | max_distance = 0 24 | for i1 in range(height): 25 | for j1 in range(width): 26 | if not grid[i1][j1]: 27 | continue 28 | for (i2, j2) in chain(((i1, j) for j in range(j1 + 1, width)), 29 | ((i, j) for i in range(i1 + 1, height) 30 | for j in range(width) 31 | ) 32 | ): 33 | if not grid[i2][j2]: 34 | continue 35 | distance = hypot(i2 - i1, j2 - j1) 36 | if distance == max_distance: 37 | solutions.add(((j1 + 1, i1 + 1), (j2 + 1, i2 + 1))) 38 | elif distance > max_distance: 39 | max_distance = distance 40 | solutions = {((j1 + 1, i1 + 1), (j2 + 1, i2 + 1))} 41 | print('The maximum distance between 2 points in the grid is:', 42 | round(max_distance, 2) 43 | ) 44 | print("That distance is between the following pairs of points:") 45 | print('\n'.join(f'({j1}, {i1}) -- ({j2}, {i2})' 46 | for ((j1, i1), (j2, i2)) in sorted(solutions) 47 | ) 48 | ) 49 | -------------------------------------------------------------------------------- /03.exercies/43.Magic squares/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/43.Magic squares/Illustrations.zip -------------------------------------------------------------------------------- /03.exercies/45.Kaprekar's constant/6174.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/45.Kaprekar's constant/6174.pdf -------------------------------------------------------------------------------- /03.exercies/50.Catalan numbers/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/50.Catalan numbers/Illustrations.zip -------------------------------------------------------------------------------- /03.exercies/53.CO2 emissions/API_EN.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/53.CO2 emissions/API_EN.gz -------------------------------------------------------------------------------- /03.exercies/53.CO2 emissions/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/53.CO2 emissions/Illustrations.zip -------------------------------------------------------------------------------- /03.exercies/54.Word ladders/Illustrations.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/54.Word ladders/Illustrations.zip -------------------------------------------------------------------------------- /03.exercies/55.Word search puzzle/word_grid_1.txt: -------------------------------------------------------------------------------- 1 | NDAOELDLOGBMNE 2 | ITDCMEAINRUTSL 3 | CLUUEICGGGOLII 4 | KMUIMUIDIRIALT 5 | EURTUNGSTENBVH 6 | LILSLTTULRUOEI 7 | CMATETIURDRCRU 8 | IDSCAMAGNESIUM 9 | MAMPDMUINATITI 10 | PCNPLATINUMDLL 11 | HZEMANGANESEIG 12 | MGITINRUNORITC 13 | RIANNAMERCURYN 14 | UOTCCREPPOCEER 15 | -------------------------------------------------------------------------------- /03.exercies/55.Word search puzzle/word_grid_2.txt: -------------------------------------------------------------------------------- 1 | 2 | W M B R W P P O P E R R I W 3 | 4 | E L M N N M L B I A P C I K 5 | 6 | B E O R R O Y G R E P W E O 7 | 8 | K N G E R R M O A E P A R G 9 | 10 | I I R E M Y E E O R P R Y R 11 | 12 | W O K L M I R A L G A A O A 13 | 14 | I B M M S O L L E L P P A S 15 | 16 | E A O W O R A N G E R O E P 17 | 18 | W A T E R M E L O N L R R B 19 | 20 | P A N M A L B R R A W P P E 21 | 22 | B A N A N A E A A G B N R R 23 | 24 | A P B Y R R E B K C A L B R 25 | 26 | B A N W B L U E B E R R Y Y 27 | 28 | A O I L U A T P T E A N N E 29 | 30 | -------------------------------------------------------------------------------- /03.exercies/56.Election methods/election_1.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/56.Election methods/election_1.xlsx -------------------------------------------------------------------------------- /03.exercies/56.Election methods/election_2.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/56.Election methods/election_2.xlsx -------------------------------------------------------------------------------- /03.exercies/56.Election methods/election_3.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/56.Election methods/election_3.xlsx -------------------------------------------------------------------------------- /03.exercies/56.Election methods/election_4.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/56.Election methods/election_4.xlsx -------------------------------------------------------------------------------- /03.exercies/56.Election methods/election_5.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/56.Election methods/election_5.xlsx -------------------------------------------------------------------------------- /03.exercies/60.Calkin-Wilf tree/calkin_wilf_tree.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marey/UNSW_COMP9021/3428067a9ca60195cda500ca99c0aaf57d225b59/03.exercies/60.Calkin-Wilf tree/calkin_wilf_tree.pdf -------------------------------------------------------------------------------- /04.Labs/03/exercise_3_1_template.py: -------------------------------------------------------------------------------- 1 | # Assume that the arguments m and n are integers at least equal to 0. 2 | 3 | def f1(m, n): 4 | return '' 5 | # REPLACE THE RETURN STATEMENT ABOVE WITH YOUR CODE 6 | -------------------------------------------------------------------------------- /04.Labs/03/exercise_3_2_template.py: -------------------------------------------------------------------------------- 1 | # Assume that the argument n is an integer at least equal to 0. 2 | # 3 | # Even digits are white, odd digits are black. 4 | # 5 | # The output is printed out, not returned. 6 | 7 | def f2(n): 8 | return '' 9 | # REPLACE THE RETURN STATEMENT ABOVE WITH YOUR CODE 10 | -------------------------------------------------------------------------------- /04.Labs/03/exercise_3_3_template.py: -------------------------------------------------------------------------------- 1 | # Assume that the argument n is an integer at least equal to 0. 2 | # 3 | # Bases range from the smallest possible, at least equal to 2, to 10. 4 | # 5 | # The output is printed out, not returned. 6 | 7 | def f3(n): 8 | pass 9 | # REPLACE THE PASS STATEMENT ABOVE WITH YOUR CODE 10 | -------------------------------------------------------------------------------- /04.Labs/03/exercise_3_4_template.py: -------------------------------------------------------------------------------- 1 | # Assume that the argument n is an integer at least equal to 0 2 | # and the argument base is an integer between 2 and 9 included. 3 | 4 | def f4(n, base): 5 | return {} 6 | # REPLACE THE RETURN STATEMENT ABOVE WITH YOUR CODE 7 | -------------------------------------------------------------------------------- /04.Labs/03/exercise_3_5_template.py: -------------------------------------------------------------------------------- 1 | # Assume that the argument integral_part is an integer at least equal to 0 2 | # and the argument fractional_part is an integer strictly greater than 0. 3 | # 4 | # The output is printed out, not returned. 5 | 6 | def f5(integral_part, fractional_part): 7 | pass 8 | # REPLACE THE PASS STATEMENT ABOVE WITH YOUR CODE 9 | -------------------------------------------------------------------------------- /04.Labs/03/exercise_3_6_template.py: -------------------------------------------------------------------------------- 1 | # Assume that the argument L is a list of lists of integers 2 | # that are all of the same length, say a strictly positive 3 | # integer n, and that fields is a list that represents a 4 | # permutation of {1, ..., n}. 5 | # 6 | # L has to be sorted considering in a list L' of length n 7 | # - first the element of L' whose position is given by the 8 | # first member of fields, 9 | # - if n >= 2, then the element of L' whose position is given by the 10 | # second member of fields, 11 | # - ... 12 | # - finally, the element of L' whose position is given by the 13 | # last member of fields. 14 | 15 | def f6(L, fields): 16 | return [] 17 | # REPLACE THE RETURN STATEMENT ABOVE WITH YOUR CODE 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UNSW COMP9021的课件整理 2 | 3 | - 会不定期整理上传最新的课程资料 4 | - 会不定上传整理的代码 5 | - 涉及的考试真题,可私信我索取,微信:marey_marey111 --------------------------------------------------------------------------------