def __getitem__(self, p): return self.grid.get(p, self.unmapped) def __str__(self): ps = self.points() xs = {x for (x, _) in ps} ys = {y for (_, y) in ps} ret = "" for y in range(min(ys) - 1, max(ys) + 2): for x in range(min(xs) - 1, max(xs) + 2): if self[(x, y)]: ret += "██" else: ret += " ." ret += "\n" return ret if __name__ == "__main__": grid = Grid(read()) # 1 for _ in range(2): grid.tick() print(grid.len()) # 2 for _ in range(48): grid.tick() print(grid.len())
from collections import defaultdict from prelude import read def explore(graph, pos="start", seen=set(), revisit=False): for step in graph[pos]: if step == "end": yield 1 elif revisit or step not in seen: new_seen = set(seen) if step != "end" and step.islower(): new_seen.add(step) yield from explore(graph, step, new_seen, revisit=revisit and step not in seen) if __name__ == "__main__": data = read(lambda c: c.split("-")) graph = defaultdict(set) for (a, b) in data: # No returning to start, no leaving end. if b != "start" and a != "end": graph[a].add(b) if a != "start" and b != "end": graph[b].add(a) print(sum(explore(graph))) print(sum(explore(graph, revisit=True)))
from prelude import read def average(matrix, i): return sum(elt[i] == '1' for elt in matrix) >= len(matrix) / 2 if __name__ == '__main__': data = read() n = len(data[0]) # 1 commons = [average(data, i) for i in range(n)] commons = eval('0b' + ''.join(str(int(i)) for i in commons)) uncommons = [not average(data, i) for i in range(n)] uncommons = eval('0b' + ''.join(str(int(i)) for i in uncommons)) print(commons * uncommons) # 2 candidates = data[:] for i in range(n): if len(candidates) == 1: break test = str(int(average(candidates, i))) candidates = [elt for elt in candidates if elt[i] == test] generator = eval('0b' + candidates[0]) candidates = data[:] for i in range(n):
elif cmd[0] == 'down': pos[1] += int(cmd[1]) elif cmd[0] == 'up': pos[1] -= int(cmd[1]) return pos def update2(pos, cmd): x = int(cmd[1]) if cmd[0] == 'forward': pos[0] += x pos[1] += pos[2] * x elif cmd[0] == 'down': pos[2] += x elif cmd[0] == 'up': pos[2] -= x return pos if __name__ == '__main__': data = read(lambda x: x.split(' ')) pos = [0, 0] for elt in data: pos = update(pos, elt) print(pos[0] * pos[1]) pos = [0, 0, 0] for elt in data: pos = update2(pos, elt) print(pos[0] * pos[1])
g[p2] = g[p] + cost(p2) come_from[p2] = p heappush(open, ((h(p2) + g[p2], p2))) # Crash if no path was found. assert (end in come_from) # Reconstruct path path = [end] while come_from[path[-1]] != start: path.append(come_from[path[-1]]) return sum(cost(p) for p in path) if __name__ == "__main__": data = read(lambda x: [int(c) for c in x]) w, h = len(data[0]), len(data) def cost(p): x, y = p if x < 0 or y < 0 or x >= w or y >= h: return 999999999 else: return data[y][x] print(astar((0, 0), (w - 1, h - 1), cost)) def cost2(p): x, y = p if x < 0 or y < 0 or x >= w * 5 or y >= h * 5: return 999999999
from prelude import read def parse_wire(line): for elt in line.split(","): if elt[0] == "U": yield [0, -int(elt[1:])] if elt[0] == "R": yield [int(elt[1:]), 0] if elt[0] == "D": yield [0, int(elt[1:])] if elt[0] == "L": yield [-int(elt[1:]), 0] if __name__ == "__main__": data = read(lambda a: list(parse_wire(a))) print(data)
from prelude import read if __name__ == "__main__": nums = read(int) n = 0 for i in range(1, len(nums)): if nums[i] > nums[i - 1]: n += 1 print(n) nums2 = [nums[i] + nums[i - 1] + nums[i - 2] for i in range(2, len(nums))] n = 0 for i in range(1, len(nums2)): if nums2[i] > nums2[i - 1]: n += 1 print(n)
def flood(map, p) -> set: result = set() open = {p} while open: seed = open.pop() result.add(seed) for n in neighbors(map, seed): cell = get(map, n) if n not in result and cell is not None and cell < 9: open.add(n) return result if __name__ == "__main__": map = read(lambda y: [int(x) for x in y]) # 1 acc = 0 for y in range(len(map)): for x in range(len(map[0])): cell = get(map, (x, y)) if all(cell < get(map, n) for n in neighbors(map, (x, y))): acc += cell + 1 print(acc) # 2 basins: List[set] = [] for y in range(len(map)): for x in range(len(map[0])): cell = get(map, (x, y))
def hits(dx, dy, rect): x1, x2, y1, y2 = rect for (x, y) in plot(dx, dy, rect): if x >= x1 and x <= x2 and y >= y1 and y <= y2: return True if x > x2 or y < y1: return False def xsum(dx): return (dx * dx + dx) / 2 if __name__ == "__main__": rect = ints(read()[0]) x1, x2, y1, y2 = rect # Find all dx values that stop on top of the box. dxes = [dx for dx in range(9999) if xsum(dx) >= x1 and xsum(dx) <= x2] max_y = 0 for dx in dxes: for dy in (dy for dy in range(999) if hits(dx, dy, rect)): apex = max(y for (x, y) in plot(dx, dy, rect)) max_y = max(max_y, apex) print(max_y) print( len([(dx, dy) for dx in range(5000) for dy in range(y1, 5000)
# XXX: Only works for orthogonal or diagonal lines (x1, y1), (x2, y2) = line dx = x2 - x1 dy = y2 - y1 length = max(abs(dx), abs(dy)) dx, dy = dx / length, dy / length x, y = x1, y1 for _ in range(length + 1): yield (x, y) x += dx y += dy if __name__ == "__main__": data = read(lambda line: [[int(x) for x in y.split(",")] for y in line.split("->")]) # 1 lines = [line for line in data if orthogonal(line)] hist = defaultdict(int) for line in lines: for point in points(line): hist[point] += 1 print(len([point for point in hist if hist[point] > 1])) # 2 lines = data[:] hist = defaultdict(int)
new_expr = step_reduce(expr) if new_expr == expr: return expr else: expr = new_expr def abs(expr): if isinstance(expr, int): return expr else: return 3 * abs(expr[0]) + 2 * abs(expr[1]) if __name__ == "__main__": data = read(eval) # 1 sum = reduce(add, data) print(abs(sum)) # 2 print(max(abs(add(i, j)) for i in data for j in data if i != j)) def p(expr): """Fancy visualizer function.""" def q(expr, depth): if isinstance(expr, int): if expr >= 10 and depth <= 4: eprint("\x1b[1;35m%s\x1b[0m" % expr, end="")
from collections import defaultdict from prelude import read, cat def update(table, pairs): new_pairs = defaultdict(int) for (p, n) in list(pairs.items()): c = table[p] new_pairs[cat(p[0], c)] += n new_pairs[cat(c, p[1])] += n return new_pairs if __name__ == "__main__": lines = read() init = lines[0] table = dict(x.split(" -> ") for x in lines[2:]) pairs = defaultdict(int) for x in (cat(p) for p in zip(init, init[1:])): pairs[x] += 1 # 1, 2 for n in [10, 40]: state = pairs.copy() for _ in range(n): state = update(table, state) hist = defaultdict(int, {init[-1]: 1}) for ((c, _), n) in state.items(): hist[c] += n print(max(hist.values()) - min(hist.values()))
(a, ) = acf - cf bd = bcdf - cf (b, ) = bd - adg (d, ) = bd - {b} bcef = comp(adg) (e, ) = bcef - {b} - cf cde = comp(abfg) (f, ) = cf - cde (c, ) = cf - {f} (g, ) = comp({a, b, c, d, e, f}) return {a: "a", b: "b", c: "c", d: "d", e: "e", f: "f", g: "g"} if __name__ == "__main__": data = read(lambda y: [x.split(" ") for x in y.split(" | ")]) # One is two, seven is three, four is four, eight is seven. print( sum( len(segments) in [2, 3, 4, 7] for (_, num) in data for segments in num)) sum = 0 for (wires, digits) in data: sol = solve(wires) num = int("".join(DIGITS["".join(sorted(sol[c] for c in digit))] for digit in digits)) sum += num print(sum)
from functools import cache from prelude import read, ints @cache def zero_fish_spawns_in(days): if days < 0: return 0 else: return ( 1 + zero_fish_spawns_in(days - 7) + zero_fish_spawns_in(days - 9) ) if __name__ == "__main__": data = read(ints)[0] print(sum(1 + zero_fish_spawns_in(79 - x) for x in data)) print(sum(1 + zero_fish_spawns_in(255 - x) for x in data))