Do day 8 and add gcm and prime factors to lib.
This commit is contained in:
parent
f29447c18b
commit
203f921c9f
105
d8.py
Normal file
105
d8.py
Normal 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
32
lib.py
@ -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+")
|
||||
|
Reference in New Issue
Block a user