diff --git a/d8.py b/d8.py new file mode 100644 index 0000000..dab62d9 --- /dev/null +++ b/d8.py @@ -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() diff --git a/lib.py b/lib.py index 6e4715b..2170f46 100644 --- a/lib.py +++ b/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+")