def b(): w = 25 h = 6 out = [None] * (w * h) layers = list(u.chunks(img, w * h)) for i in range(w * h): for layer in layers: if layer[i] != 2: out[i] = layer[i] break m = {(x, y): row[x] for y, row in enumerate(list(u.chunks(out, w))) for x in range(w)} u.print_matrix(m, " #")
def b(): cpos = 0 skip = 0 l = list(range(256)) vals = [ord(d) for d in data] + [17, 31, 73, 47, 23] #vals = [3, 4, 1, 5, 17, 31, 73, 47, 23] for round in range(64): print('.', end='') for length in vals: left = cpos right = cpos + length - 1 while left < right: lt = left % len(l) rt = right % len(l) tmp = l[lt] l[lt] = l[rt] l[rt] = tmp left += 1 right -= 1 cpos += length cpos += skip skip += 1 out = [] for chunk in u.chunks(l, 16): val = functools.reduce(operator.xor, chunk) out.append(f'{val:02x}') return ''.join(out)
def b(): cs = u.chunks(data, 2) s, rs = zip(*cs) sps = set(itertools.accumulate(dirs[c] for c in s)) srps = set(itertools.accumulate(dirs[c] for c in rs)) return len(sps | srps)
def a(): groups = data.split("\n\n") criteria, ticket, nearby = [l.split("\n") for l in groups] rules = {} for c in criteria: k, vs = c.split(":") rs = u.lmap(tuple, u.chunks(u.ints(vs.replace("-", " to ")), 2)) rules[k] = rs def valid(val): for ruleset in rules.values(): for a, b in ruleset: if a <= val <= b: return True return False s = 0 for ticket in nearby[1:]: t = u.ints(ticket) for v in t: if not valid(v): s += v return s
def a(): out = defaultdict(int) for x, y, tile in u.chunks(intcode.run(data, []), 3): out[(x, y)] = tile # print_tiles(out) blocks = len([v for v in out.values() if v == 2]) return blocks
def b(): def min_perim(l, w, h): return min(2 * sum(s) for s in sides(l, w, h)) return sum( math.prod((l, w, h)) + min_perim(l, w, h) for l, w, h in u.chunks(u.ints(data), 3))
def b(): nums = [u.ints(line) for line in lines] cs = zip(*nums) s = 0 for tri in u.chunks(itertools.chain.from_iterable(cs), 3): s += possible(tri) return s
def a(): def area(l, w, h): return sum(2 * math.prod(s) for s in sides(l, w, h)) def slack(l, w, h): return min(math.prod(s) for s in sides(l, w, h)) return sum( area(l, w, h) + slack(l, w, h) for l, w, h in u.chunks(u.ints(data), 3))
def a(): w = 25 h = 6 best_zero = None res = None for layer in u.chunks(img, w * h): counts = Counter(layer) if best_zero is None or counts[0] < best_zero: res = counts[1] * counts[2] best_zero = counts[0] return res
def a(): _, p0, _, p1 = ints s0 = s1 = 0 die = zip(itertools.count(1), itertools.cycle(range(1, 101))) rolls = ((max(a), sum(b)) for a, b in (zip(*c) for c in u.chunks(die, 3))) for rollcount, total in rolls: np0 = (p0 + total) % 10 or 10 ns0 = s0 + np0 if ns0 >= 1000: break s1, s0 = ns0, s1 p1, p0 = np0, p1 return s1 * rollcount
def b(): groups = data.split("\n\n") criteria, my_ticket, nearby = [g.split("\n") for g in groups] my_ticket = u.ints(my_ticket[1]) rules = {} for c in criteria: k, vs = c.split(":") rs = u.lmap(tuple, u.chunks(u.ints(vs.replace("-", " ")), 2)) rules[k] = rs def valid_for_field(v, field): return any(a <= v <= b for a, b in rules[field]) def valid(val): return any(valid_for_field(val, field) for field in rules) valid_nearby = [] for ticket in nearby[1:]: t = u.ints(ticket) if all(valid(v) for v in t): valid_nearby.append(t) possible = [] for _ in range(len(my_ticket)): possible.append(set(rules.keys())) for ticket in valid_nearby: for i, v in enumerate(ticket): pl = list(possible[i]) for field in pl: if not valid_for_field(v, field): possible[i].remove(field) mapping = {} allocated = set() for i, p in sorted(enumerate(possible), key=lambda x: x[1]): field = (p - allocated).pop() mapping[i] = field allocated.add(field) s = functools.reduce( operator.mul, (my_ticket[i] for i in mapping if mapping[i].startswith("departure")), 1, ) return s
def run(program, init): panels = defaultdict(int) pos = (0, 0) d = N panels[pos] = init buf = [panels[pos]] out = intcode.run(program, buf) for color, turn_right in u.chunks(out, 2): panels[pos] = color d = right[d] if turn_right else left[d] pos = (pos[0] + d[0], pos[1] + d[1]) buf.append(panels[pos]) return panels
def a(): keys = { complex(x, y): c for y, row in enumerate(u.chunks(range(1, 10), 3)) for x, c in enumerate(row) } def clamp(c): r = max(0, min(c.real, 2)) i = max(0, min(c.imag, 2)) return complex(r, i) code = [] pos = complex(1, 1) for line in lines: for d in line: pos += dirs[d] pos = clamp(pos) code.append(str(keys[pos])) return "".join(code)
def b(): prog = [int(c) for c in data.split(",")] prog[0] = 2 ball = None for i in range(len(prog) - 2): if prog[i] == 0 and prog[i + 1] == 3 and prog[i + 2] == 0: ball = i + 1 break for r in range(ball - 17, ball + 18): prog[r] = 1 score = 0 inps = [0] * 6500 out = defaultdict(int) for x, y, tile in u.chunks(intcode.run(prog, inps), 3): if (x, y) == (-1, 0): score = tile # print_tiles(out, score) else: out[(x, y)] = tile return score
def position_scanners(): scanners = [set(u.chunks(u.ints(scanner)[1:], 3)) for scanner in data.split('\n\n')] fingerprints = u.lmap(fingerprint, scanners) positions = {0: (0,0,0)} relative_sensors = {0: scanners[0]} solvable = deque([0]) while len(solvable) > 0: i = solvable.popleft() rscanner1 = relative_sensors[i] for j, scanner2 in enumerate(scanners): if j == i or j in positions or len(fingerprints[i] & fingerprints[j]) < threshold: continue aligned, position, rscanner2 = align_scanners(rscanner1, scanner2) if aligned: solvable.append(j) positions[j] = position relative_sensors[j] = rscanner2 sensors = {pt for v in relative_sensors.values() for pt in v} return positions, sensors
def checksum(s): return tuple(1 - operator.xor(*c) for c in u.chunks(s, 2))
def b(): draws = intlines[0] boards = [board[1:] for board in u.chunks(intlines[1:], 6)] results = [winner(board, draws) for board in boards] _, unmarked, draw = max(results, key=lambda p: p[0]) return sum(unmarked) * draw