diff --git a/DIRECTORY.md b/DIRECTORY.md index fd45eacaad9b..136d25c80fcd 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -206,8 +206,10 @@ * [Heaps Algorithm](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/heaps_algorithm.py) * [Heaps Algorithm Iterative](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/heaps_algorithm_iterative.py) * [Inversions](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/inversions.py) + * [Kth Order Statistic](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/kth_order_statistic.py) * [Max Subarray Sum](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/max_subarray_sum.py) * [Mergesort](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/mergesort.py) + * [Peak](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/peak.py) * [Power](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/power.py) * [Strassen Matrix Multiplication](https://github.com/TheAlgorithms/Python/blob/master/divide_and_conquer/strassen_matrix_multiplication.py) @@ -390,6 +392,7 @@ * [Chudnovsky Algorithm](https://github.com/TheAlgorithms/Python/blob/master/maths/chudnovsky_algorithm.py) * [Collatz Sequence](https://github.com/TheAlgorithms/Python/blob/master/maths/collatz_sequence.py) * [Combinations](https://github.com/TheAlgorithms/Python/blob/master/maths/combinations.py) + * [Decimal Isolate](https://github.com/TheAlgorithms/Python/blob/master/maths/decimal_isolate.py) * [Entropy](https://github.com/TheAlgorithms/Python/blob/master/maths/entropy.py) * [Eulers Totient](https://github.com/TheAlgorithms/Python/blob/master/maths/eulers_totient.py) * [Explicit Euler](https://github.com/TheAlgorithms/Python/blob/master/maths/explicit_euler.py) @@ -493,6 +496,7 @@ * [Autocomplete Using Trie](https://github.com/TheAlgorithms/Python/blob/master/other/autocomplete_using_trie.py) * [Binary Exponentiation](https://github.com/TheAlgorithms/Python/blob/master/other/binary_exponentiation.py) * [Binary Exponentiation 2](https://github.com/TheAlgorithms/Python/blob/master/other/binary_exponentiation_2.py) + * [Davis–Putnam–Logemann–Loveland](https://github.com/TheAlgorithms/Python/blob/master/other/davis–putnam–logemann–loveland.py) * [Detecting English Programmatically](https://github.com/TheAlgorithms/Python/blob/master/other/detecting_english_programmatically.py) * [Dijkstra Bankers Algorithm](https://github.com/TheAlgorithms/Python/blob/master/other/dijkstra_bankers_algorithm.py) * [Doomsday](https://github.com/TheAlgorithms/Python/blob/master/other/doomsday.py) @@ -582,6 +586,7 @@ * Problem 014 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_014/sol1.py) * [Sol2](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_014/sol2.py) + * [Sol3](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_014/sol3.py) * Problem 015 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_015/sol1.py) * Problem 016 @@ -660,6 +665,8 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_048/sol1.py) * Problem 049 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_049/sol1.py) + * Problem 050 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_050/sol1.py) * Problem 051 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_051/sol1.py) * Problem 052 @@ -681,6 +688,8 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_062/sol1.py) * Problem 063 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_063/sol1.py) + * Problem 064 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_064/sol1.py) * Problem 065 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_065/sol1.py) * Problem 067 @@ -694,6 +703,7 @@ * [Sol2](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_072/sol2.py) * Problem 074 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_074/sol1.py) + * [Sol2](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_074/sol2.py) * Problem 075 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_075/sol1.py) * Problem 076 @@ -718,6 +728,8 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_119/sol1.py) * Problem 120 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_120/sol1.py) + * Problem 123 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_123/sol1.py) * Problem 125 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_125/sol1.py) * Problem 173 @@ -726,12 +738,16 @@ * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_174/sol1.py) * Problem 191 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_191/sol1.py) + * Problem 203 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_203/sol1.py) * Problem 206 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_206/sol1.py) * Problem 207 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_207/sol1.py) * Problem 234 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_234/sol1.py) + * Problem 301 + * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_301/sol1.py) * Problem 551 * [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_551/sol1.py) @@ -740,6 +756,7 @@ * [Half Adder](https://github.com/TheAlgorithms/Python/blob/master/quantum/half_adder.py) * [Not Gate](https://github.com/TheAlgorithms/Python/blob/master/quantum/not_gate.py) * [Quantum Entanglement](https://github.com/TheAlgorithms/Python/blob/master/quantum/quantum_entanglement.py) + * [Ripple Adder Classic](https://github.com/TheAlgorithms/Python/blob/master/quantum/ripple_adder_classic.py) * [Single Qubit Measure](https://github.com/TheAlgorithms/Python/blob/master/quantum/single_qubit_measure.py) ## Scheduling diff --git a/project_euler/problem_014/sol3.py b/project_euler/problem_014/sol3.py new file mode 100755 index 000000000000..2ae43cae30eb --- /dev/null +++ b/project_euler/problem_014/sol3.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +from typing import Tuple + +""" +Collatz conjecture: start with any positive integer n. Next term obtained from +the previous term as follows: +If the previous term is even, the next term is one half the previous term. +If the previous term is odd, the next term is 3 times the previous term plus 1. +The conjecture states the sequence will always reach 1 regardless of starting +n. +Problem Statement: +The following iterative sequence is defined for the set of positive integers: + n → n/2 (n is even) + n → 3n + 1 (n is odd) +Using the rule above and starting with 13, we generate the following sequence: + 13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1 +It can be seen that this sequence (starting at 13 and finishing at 1) contains +10 terms. Although it has not been proved yet (Collatz Problem), it is thought +that all starting numbers finish at 1. +Which starting number, under one million, produces the longest chain? +""" + +# we are going to avoid repeat computations by creating a knowledge base +# where we store the length of all collatz chains we calculated so far + +knowledge = {1: 1} + + +# a single step in a collatz chain +def collatz(n: int) -> int: + """ + Calculates a single step in a collatz chain. + + >>> collatz(13) + 40 + >>> collatz(40) + 20 + >>> collatz(5) + 16 + """ + if n % 2 == 0: + return n // 2 + else: + return 3 * n + 1 + + +def calculate_chain(n: int) -> None: + """ + Calculates a collatz chain of a certain number. This calculation is halted + whenever we find a key with a known collatz chain in our knowledge base. + This function has no return value and doctests can't measure side effects, + so we can't do doctests on this function. + """ + entries = [] + while n not in knowledge: + entries.append(n) + n = collatz(n) + chain_size = knowledge[n] + for i in entries[::-1]: + chain_size += 1 + knowledge[i] = chain_size + + +def solution(m: int = 1000000, extra_info: bool = False) -> Tuple[int, int]: + """ + Returns the number under n that generates the longest Collatz sequence. + + >>> solution(1000000, True) + (837799, 525) + >>> solution(200, True) + (171, 125) + >>> solution(5000, True) + (3711, 238) + >>> solution(15000, True) + (13255, 276) + """ + max_chain = (1, 1) + for i in range(1, m + 1): + calculate_chain(i) + # we can use knowledge[i] because calculate_chain + # by definition already adds the key we specified to the + # knowledge base + if max_chain[1] < knowledge[i]: + max_chain = (i, knowledge[i]) + + if extra_info: + return max_chain + else: + return max_chain[0] + + +if __name__ == "__main__": + print( + """ + calculate the number with the longest collatz chain + in the range between 1 and the following number: + """ + ) + input_number = int(input().strip()) + number, chain_length = solution(input_number, True) + print( + f""" + the maximum collatz chain of all numbers between 1 and {input_number} is + {chain_length}, starting with the number {number} + """ + )