Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
* Arrays
* [Permutations](data_structures/arrays/permutations.py)
* [Prefix Sum](data_structures/arrays/prefix_sum.py)
* [Product Sum Array](data_structures/arrays/product_sum.py)
* [Product Sum](data_structures/arrays/product_sum.py)
* Binary Tree
* [Avl Tree](data_structures/binary_tree/avl_tree.py)
* [Basic Binary Tree](data_structures/binary_tree/basic_binary_tree.py)
Expand Down Expand Up @@ -522,7 +522,6 @@
* [Xgboost Regressor](machine_learning/xgboost_regressor.py)

## Maths
* [3N Plus 1](maths/3n_plus_1.py)
* [Abs](maths/abs.py)
* [Add](maths/add.py)
* [Addition Without Arithmetic](maths/addition_without_arithmetic.py)
Expand Down
151 changes: 0 additions & 151 deletions maths/3n_plus_1.py

This file was deleted.

69 changes: 45 additions & 24 deletions maths/collatz_sequence.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,64 @@
from __future__ import annotations
"""
The Collatz conjecture is a famous unsolved problem in mathematics. Given a starting
positive integer, define the following sequence:
- If the current term n is even, then the next term is n/2.
- If the current term n is odd, then the next term is 3n + 1.
The conjecture claims that this sequence will always reach 1 for any starting number.

Other names for this problem include the 3n + 1 problem, the Ulam conjecture, Kakutani's
problem, the Thwaites conjecture, Hasse's algorithm, the Syracuse problem, and the
hailstone sequence.

def collatz_sequence(n: int) -> list[int]:
Reference: https://en.wikipedia.org/wiki/Collatz_conjecture
"""

from collections.abc import Generator


def collatz_sequence(n: int) -> Generator[int, None, None]:
"""
Collatz conjecture: start with any positive integer n. The next term is
obtained as follows:
If n term is even, the next term is: n / 2 .
If n is odd, the next term is: 3 * n + 1.

The conjecture states the sequence will always reach 1 for any starting value n.
Example:
>>> collatz_sequence(2.1)
Generate the Collatz sequence starting at n.
>>> list(collatz_sequence(2.1))
Traceback (most recent call last):
...
Exception: Sequence only defined for natural numbers
>>> collatz_sequence(0)
Exception: Sequence only defined for positive integers
>>> list(collatz_sequence(0))
Traceback (most recent call last):
...
Exception: Sequence only defined for natural numbers
>>> collatz_sequence(43) # doctest: +NORMALIZE_WHITESPACE
[43, 130, 65, 196, 98, 49, 148, 74, 37, 112, 56, 28, 14, 7,
22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]
Exception: Sequence only defined for positive integers
>>> list(collatz_sequence(4))
[4, 2, 1]
>>> list(collatz_sequence(11))
[11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]
>>> list(collatz_sequence(31)) # doctest: +NORMALIZE_WHITESPACE
[31, 94, 47, 142, 71, 214, 107, 322, 161, 484, 242, 121, 364, 182, 91, 274, 137,
412, 206, 103, 310, 155, 466, 233, 700, 350, 175, 526, 263, 790, 395, 1186, 593,
1780, 890, 445, 1336, 668, 334, 167, 502, 251, 754, 377, 1132, 566, 283, 850, 425,
1276, 638, 319, 958, 479, 1438, 719, 2158, 1079, 3238, 1619, 4858, 2429, 7288, 3644,
1822, 911, 2734, 1367, 4102, 2051, 6154, 3077, 9232, 4616, 2308, 1154, 577, 1732,
866, 433, 1300, 650, 325, 976, 488, 244, 122, 61, 184, 92, 46, 23, 70, 35, 106, 53,
160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1]
>>> list(collatz_sequence(43)) # doctest: +NORMALIZE_WHITESPACE
[43, 130, 65, 196, 98, 49, 148, 74, 37, 112, 56, 28, 14, 7, 22, 11, 34, 17, 52, 26,
13, 40, 20, 10, 5, 16, 8, 4, 2, 1]
"""

if not isinstance(n, int) or n < 1:
raise Exception("Sequence only defined for natural numbers")
raise Exception("Sequence only defined for positive integers")

sequence = [n]
yield n
while n != 1:
n = 3 * n + 1 if n & 1 else n // 2
sequence.append(n)
return sequence
if n % 2 == 0:
n //= 2
else:
n = 3 * n + 1
yield n


def main():
n = 43
sequence = collatz_sequence(n)
sequence = list(collatz_sequence(n))
print(sequence)
print(f"collatz sequence from {n} took {len(sequence)} steps.")
print(f"Collatz sequence from {n} took {len(sequence)} steps.")


if __name__ == "__main__":
Expand Down