diff --git a/2017/day12.py b/2017/day12.py deleted file mode 100644 index 83d9493..0000000 --- a/2017/day12.py +++ /dev/null @@ -1,42 +0,0 @@ -from collections import defaultdict - -with open("input/day12.txt") as f: - input = f.read() - -neighbors = defaultdict(set) - -for line in input.splitlines(): - a, bs = line.split(" <-> ") - for b in bs.split(", "): - neighbors[a].add(b) - neighbors[b].add(a) - - -def connected(start, neighbors): - queue = [start] - seen = set() - while queue: - node = queue.pop(0) - if node in seen: - continue - - seen.add(node) - queue.extend(neighbors[node]) - return seen - - -def groups(neighbors) -> int: - seeds = set(neighbors.keys()) - count = 0 - - while seeds: - start = seeds.pop() - seen = connected(start, neighbors) - seeds.difference_update(seen) - count += 1 - - return count - - -print(len(connected("0", neighbors))) -print(groups(neighbors)) diff --git a/2017/day13.py b/2017/day13.py deleted file mode 100644 index 4a88f1d..0000000 --- a/2017/day13.py +++ /dev/null @@ -1,99 +0,0 @@ -from math import lcm -from dataclasses import dataclass - -with open("input/day13.txt") as f: - input = f.read() - -scanners: dict[int, int] = {} - -for line in input.splitlines(): - parts = line.split(": ") - d, r = int(parts[0]), int(parts[1]) - - assert d not in scanners, "no overlapping scanners" - scanners[d] = r - - -def part1(scanners): - severity = 0 - for d in range(max(scanners.keys()) + 1): - r = scanners.get(d) - if r is None: - continue - - assert r > 1, r - cycle = (r - 1) * 2 - pos = d % cycle - if pos == 0: - severity += d * r - return severity - - -def is_safe(scanners, delay): - for depth in range(max(scanners.keys()) + 1): - r = scanners.get(depth) - if r is None: - continue - - assert r > 1, r - cycle = (r - 1) * 2 - pos = (delay + depth) % cycle - if pos == 0: - return False - return True - - -@dataclass -class Scanner: - depth: int - cycle: int - - -@dataclass(order=True) -class Candidate: - delay: int - increment: int - - def __init__(self, delay: int, increment: int): - self.delay = delay % increment - self.increment = increment - - def __hash__(self): - return hash((self.delay % self.increment, self.increment)) - - def scale(self, scalar: int) -> set["Candidate"]: - res = set() - increment = self.increment * scalar - for i in range(scalar + 1): - res.add(Candidate(self.delay + i * self.increment, increment)) - return res - - def __str__(self): - return f"{self.delay} + k * {self.increment}" - - -def part2(scanner_map: dict[int, int]): - scanners: list[Scanner] = [] - for depth in range(max(scanner_map.keys()) + 1): - r = scanner_map.get(depth) - if r is None: - continue - cycle = (r - 1) * 2 - scanners.append(Scanner(depth, cycle)) - - candidates = {Candidate(0, 1)} - for s in scanners: - next: set[Candidate] = set() - for c in candidates: - scalar = lcm(c.increment, s.cycle) // c.increment - for n in c.scale(scalar): - if (n.delay + s.depth) % s.cycle: - next.add(n) - - candidates = next - - return min(c.delay for c in candidates) - - -print(part1(scanners)) -print(part2(scanners))