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
|
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:
|
def str_to_single_int(line: str) -> int:
|
||||||
line = line.replace(" ", "")
|
line = line.replace(" ", "")
|
||||||
r = re.compile(r"\d+")
|
r = re.compile(r"\d+")
|
||||||
|
Reference in New Issue
Block a user