Do day 8 and add gcm and prime factors to lib.

This commit is contained in:
felixm 2023-12-08 00:32:03 -05:00
parent f29447c18b
commit 203f921c9f
2 changed files with 137 additions and 0 deletions

105
d8.py Normal file
View File

@ -0,0 +1,105 @@
import lib
EXAMPLE = """
LLR
AAA = (BBB, BBB)
BBB = (AAA, ZZZ)
ZZZ = (ZZZ, ZZZ)
"""
EXAMPLE2 = """
LR
11A = (11B, XXX)
11B = (XXX, 11Z)
11Z = (11B, XXX)
22A = (22B, XXX)
22B = (22C, 22C)
22C = (22Z, 22Z)
22Z = (22B, 22B)
XXX = (XXX, XXX)
"""
def solve(lines: list[str]):
res = 0
elems = {}
for (i, line) in enumerate(lines):
if i == 0:
first = list(line)
else:
left, pair = line.split("=")
left = left.strip()
pair = pair.replace("(", "").replace(")", "").strip().split(", ")
elems[left] = pair
i = 0
start = "AAA"
while start != "ZZZ":
dir = first[i % len(first)]
if dir == "L":
start = elems[start][0]
elif dir == "R":
start = elems[start][1]
else:
raise Exception("Unex")
i += 1
return i
def solve2(lines: list[str]):
res = 0
elems = {}
starts = []
ends = {}
for (i, line) in enumerate(lines):
if i == 0:
first = list(line)
else:
left, pair = line.split("=")
left = left.strip()
if left.endswith("A"):
starts.append(left)
if left.endswith("Z"):
ends[left] = 0
pair = pair.replace("(", "").replace(")", "").strip().split(", ")
elems[left] = pair
i = 0
while True:
new_starts = []
for start in starts:
dir = first[i % len(first)]
if dir == "L":
new_starts.append(elems[start][0])
elif dir == "R":
new_starts.append(elems[start][1])
else:
raise Exception("Unex")
i += 1
for start in new_starts:
if start in ends and ends[start] == 0:
ends[start] = i
starts = new_starts
for e in ends.values():
if e == 0:
break
else:
break
# 25:00
return lib.lcm(ends.values())
def main():
lines = lib.str_to_lines_no_empty(EXAMPLE)
print("Example 1:", solve(lines))
lines = lib.str_to_lines_no_empty(open("i8.txt").read())
print("Solution 1:", solve(lines))
lines = lib.str_to_lines_no_empty(EXAMPLE2)
print("Example 2:", solve2(lines))
lines = lib.str_to_lines_no_empty(open("i8.txt").read())
print("Solution 2:", solve2(lines))
if __name__ == "__main__":
main()

32
lib.py
View File

@ -1,5 +1,37 @@
import re
def prime_factors(n):
"""
Returns a list of prime factors for n.
:param n: number for which prime factors should be returned
"""
factors = []
rest = n
divisor = 2
while rest % divisor == 0:
factors.append(divisor)
rest //= divisor
divisor = 3
while divisor * divisor <= rest:
while rest % divisor == 0:
factors.append(divisor)
rest //= divisor
divisor += 2
if rest != 1:
factors.append(rest)
return factors
def lcm(numbers: list[int]) -> int:
fs = []
for n in numbers:
fs += prime_factors(n)
s = 1
fs = list(set(fs))
for f in fs:
s *= f
return s
def str_to_single_int(line: str) -> int:
line = line.replace(" ", "")
r = re.compile(r"\d+")