diff --git a/assignments/a4/a4_part2.py b/assignments/a4/a4_part2.py index 0738c89..27e8c83 100644 --- a/assignments/a4/a4_part2.py +++ b/assignments/a4/a4_part2.py @@ -83,6 +83,30 @@ def coprime_to_all(primes: set[int], n: int) -> list[int]: and may NOT modify it (even though it is not as efficient as it could be!!). - You will find the math.prod function useful. """ + increment = math.prod(primes) + nums_so_far = starting_coprime_numbers(primes) + period = len(nums_so_far) + while nums_so_far[-period] + increment < n: + # Note: Write four assert statements here expressing the four loop invariants from the + # assignment handout. These statements should be at the top of the loop body. + + # Loop Invariant 1: every number k in nums_so_far is coprime to every prime + assert all(all(math.gcd(p, k) == 1 for p in primes) for k in nums_so_far) + # Loop Invariant 2: for all natural numbers i between 0 and len(nums_so_far) - period - 1 inclusive, + # nums_so_far[i] + increment == nums_so_far[i + period]. + assert all(nums_so_far[i] + increment == nums_so_far[i + period] for i in range(len(nums_so_far) - period)) + # Loop Invariant 3: for all natural numbers i between 0 and len(nums_so_far) - 2 inclusive, + # nums_so_far[i] < nums_so_far[i + 1] (this means that nums_so_far is always sorted). + assert all(nums_so_far[i] < nums_so_far[i + 1] for i in range(len(nums_so_far) - 2 + 1)) + # Loop Invariant 4: for all natural numbers k between 0 and nums_so_far[-1] inclusive, + # if k is coprime to all primes, then k in nums_so_far. + assert all(k in nums_so_far for k in range(nums_so_far[-1] + 1) + if all(math.gcd(p, k) == 1 for p in primes)) + + next_number = nums_so_far[-period] + increment + list.append(nums_so_far, next_number) + + return nums_so_far def starting_coprime_numbers(primes: set[int]) -> list[int]: