def process(include_diag=False): input_data = common.read_string_file() grid = defaultdict(int) for line in input_data: # debug(line) if line: points = [[int(p) for p in point.strip().split(",")] for point in line.split("->")] increment = [0, 0] for pos in (0, 1): difference = points[1][pos] - points[0][pos] if difference: increment[pos] = difference // abs(difference) debug(f"{points=} {increment=}") # all(increment) will be true for a diag but not a straight if include_diag or not all(increment): point = points[0] while True: grid[tuple(point)] += 1 debug(tuple(point)) point[0] += increment[0] point[1] += increment[1] if point == points[1]: grid[tuple(point)] += 1 debug(tuple(point)) break debug(grid) print_grid(grid) return len([v for v in grid.values() if v >= 2])
def process(): input_data = common.read_string_file() grid = Grid() for line in input_data: grid.add_row(int(c) for c in line) grid.show_grid() return grid
def get_bits(): input_data = common.read_string_file() for line in input_data: debug(line.strip()) yield ("".join(HEX_MAPPINGS[c] for c in line.strip())) debug("") return ""
def __init__(self, include_w=False): input_data = common.read_string_file() self.include_w = include_w self.points = {} for (y, line) in enumerate(input_data, 1): for (x, val) in enumerate(f".{line}."): self.points[Point(0, x, y, 0)] = val == "#" self.points[Point(0, x, y, -1)] = False self.points[Point(0, x, y, 1)] = False if self.include_w: self.points[Point(-1, x, y, -1)] = False self.points[Point(-1, x, y, 0)] = False self.points[Point(-1, x, y, 1)] = False self.points[Point(1, x, y, -1)] = False self.points[Point(1, x, y, 0)] = False self.points[Point(1, x, y, 1)] = False # Add start and end lines in all z's if self.include_w: w_range = (-1, 0, 1) else: w_range = (0, ) for w in w_range: for z in (-1, 0, 1): for x in range(len(line) + 2): self.points[Point(w, x, 0, z)] = False self.points[Point(w, x, y + 1, z)] = False self.mins = {"w": -1 if self.include_w else 0, "x": 0, "y": 0, "z": -1} self.maxs = { "w": 1 if self.include_w else 0, "x": len(line) + 1, "y": y + 1, "z": 1, }
def parse(self): self.fields = {} self.ranges = [] self.input_data = common.read_string_file() patterns = True for line in self.input_data: if patterns: m = FIELD_RE.match(line) if m: d = m.groupdict() ranges = ( range(int(d["min1"]), int(d["max1"]) + 1), range(int(d["min2"]), int(d["max2"]) + 1), ) self.fields[d["field"]] = ranges self.ranges.extend(ranges) else: break for line in self.input_data: if "your ticket:" in line: continue if not line: break self.own = [int(c.strip()) for c in line.split(",")]
def process(fuel_cost_func): input_data = common.read_string_file() crabs = [int(i) for i in next(input_data).split(",")] positions = defaultdict(int) for crab in crabs: for pos in range(min(crabs), max(crabs) + 1): positions[pos] += fuel_cost_func(abs(pos - crab)) debug(positions) return min(positions.values())
def process(): input_data = [l for l in common.read_string_file()] timestamp = int(input_data[0]) bus_times = [] for bus_time in [bt for bt in input_data[1:]]: bus_times.append( [int(bus) if bus != "x" else None for bus in bus_time.split(",")]) debug(bus_times) return (timestamp, bus_times)
def process(check): matches = 0 input_data = common.read_string_file() for (n, line) in enumerate(input_data): c = check(line) debug((n, c)) if c: matches += 1 return matches
def process(): sids = [] input_data = common.read_string_file() for l in input_data: row = find_row(l[:7]) col = find_col(l[7:]) sid = (row * 8) + col sids.append(sid) debug((row, col, sid)) return sids
def process(calculate_parenthesis_func): results = [] input_data = common.read_string_file() for line in input_data: result = process_algo( [c.strip() for c in line if c.strip()], calculate_parenthesis_func=calculate_parenthesis_func, ) results.append(result) return results
def process(directions): hits = [] input_data = common.read_string_file() for (x, y) in directions: i = InputData(input_data=input_data, x_amt=x, y_amt=y) dir_hits = 0 for (row, hit) in enumerate(i.is_tree_in_row()): debug((row, hit, i.x)) if hit: dir_hits += 1 hits.append(dir_hits) result = math.prod(hits) return result
def __init__(self, repeats): input_data = common.read_string_file() self.graph = nx.Graph() self.maxx = 0 self.maxy = 0 vals = {} for ymult in range(repeats): input_data = common.read_string_file() for (y, line) in enumerate(input_data): if line: for xmult in range(repeats): for (x, v) in enumerate(line): v = int(v) v += ymult if v > 9: v -= 9 v += xmult if v > 9: v -= 9 self.graph.add_node( ( x + ((self.maxx + 1) * xmult), y + ((self.maxy + 1) * ymult), ), weight=v, ) if xmult == 0: self.maxx = x if ymult == 0: self.maxy = y self.maxx = ((self.maxx + 1) * repeats) - 1 self.maxy = ((self.maxy + 1) * repeats) - 1 debug(self.maxx) debug(self.maxy) for x in range(self.maxx + 1): for y in range(self.maxy + 1): for (xd, yd) in ((-1, 0), (1, 0), (0, -1), (0, 1)): if (x + xd >= 0) and (y + yd >= 0): self.graph.add_edge((x, y), (x + xd, y + yd))
def process_p1(): mappings = { "forward": ("horizontal", 1), "down": ("depth", 1), "up": ("depth", -1) } position = {"horizontal": 0, "depth": 0} input_data = common.read_string_file() for instruction in input_data: (direction, amount) = instruction.split(" ") (key, multiplier) = mappings[direction] position[key] += int(amount) * multiplier debug(position) return position["horizontal"] * position["depth"]
def process(): input_data = common.read_string_file() tiles = {} for line in input_data: if "Tile" in line: tid = int(line[5:-1]) array = [] elif line: array.append([c for c in line]) else: tiles[tid] = numpy.array(array) if array: tiles[tid] = numpy.array(array) return tiles
def parse_lines(): passports = [] def add_passport_dict(items): passports.append(dict([item.split(":") for item in items])) items = [] for line in common.read_string_file(): if line: items.extend([l.strip() for l in line.split(" ")]) else: add_passport_dict(items) items = [] if items: add_passport_dict(items) return passports
def process_p2(): mappings = {"down": 1, "up": -1} horizontal = 0 depth = 0 aim = 0 input_data = common.read_string_file() for instruction in input_data: (direction, amount) = instruction.split(" ") if direction in mappings: aim += int(amount) * mappings[direction] else: # direction must be forward horizontal += int(amount) depth += aim * int(amount) debug(locals()) return horizontal * depth
def process(): input_data = common.read_string_file() line = next(input_data) pairs = Counter() for i in range(len(line) - 1): pairs[f"{line[i]}{line[i+1]}"] += 1 mappings = {} for l in input_data: if l: mapping = l.strip().split(" -> ") mappings[mapping[0]] = ( f"{mapping[0][0]}{mapping[1]}", f"{mapping[1]}{mapping[0][1]}", ) debug(pairs) debug(mappings) return (pairs, mappings)
def process(target_day): input_data = common.read_string_file() fishes = defaultdict(int) for fish in [int(i) for i in next(input_data).split(",")]: fishes[fish] += 1 day = 0 debug(fishes) while True: day += 1 new = fishes[0] for n in range(1, 9): fishes[n - 1] = fishes[n] fishes[6] += new fishes[8] = new if day <= FIRST_DEBUG_DAYS: debug(f"{day: 2}: {fishes} {new=}") if day == target_day: debug(list(fishes.values())) return sum(list(fishes.values()))
def process(): groups = [[ defaultdict(int), ]] n = 0 input_data = common.read_string_file() for l in input_data: if l: n += 1 for c in l: groups[-1][0][c] += 1 else: groups[-1].append(n) n = 0 groups.append([ defaultdict(int), ]) groups[-1].append(n) return groups
def process_p1(): input_data = common.read_string_file() bits = [] for line in input_data: debug(line) for (n, bit) in enumerate(line): if n == len(bits): bits.append(Counter()) bits[n][bit] += 1 debug(bits) gamma = [] epsilon = [] for bc in bits: (most, least) = bc.most_common(2) gamma.append(most[0]) epsilon.append(least[0]) debug( f"{gamma=} ({''.join(gamma), 2}) {epsilon=} ({''.join(epsilon), 2})" ) return int("".join(gamma), 2) * int("".join(epsilon), 2)
def process(mapping={}): rules = {} input_data = common.read_string_file() for line in input_data: if not line: break line = mapping.get(line, line) (r, pattern) = line.split(":") p = [[]] for c in pattern.split(" "): if c.strip(): if c == "|": p.append([]) elif c[0] in "123456789": p[-1].append(int(c)) else: p = c.strip('"') rules[int(r)] = p if type(p) is str else tuple(p) messages = [line for line in input_data] return (rules, messages)
def process(): input_data = common.read_string_file() mismatches = [] unused = [] for line in input_data: opens = [] for c in line: if c in OPEN: opens.append(c) if c in CLOSE: o = opens[-1] if opens else None if OPEN_TO_CLOSE.get(o, None) != c: mismatches.append(c) debug(f"{line}- Mismatch on line") break opens.pop() else: debug(f"{line} - No mismatch on line") unused.append(opens) return (mismatches, unused)
def process(): bags_top_down = {} bags_bottom_up = defaultdict(list) input_data = common.read_string_file() for line in input_data: (front, content_string) = line.split("contain") bag = front.split("bag")[0].strip() if "no other bags" in content_string: bags_top_down[bag] = None else: d = {} for content in content_string.split(","): (num, description) = content.strip().split(" ", 1) desc = description.strip().rsplit(" ", 1)[0].strip() d[desc] = int(num.strip()) bags_bottom_up[desc].append(bag) bags_top_down[bag] = d debug(bags_top_down, pretty=True) debug(bags_bottom_up, pretty=True) return (bags_top_down, bags_bottom_up)
def process(find_last=False): def print_boards(): if settings.settings.debug: for row in range(boards[0].board.shape[0]): debug(" ".join([ " ".join([f"{i: 3}" for i in board.board[row, :].tolist()]) for board in boards ])) input_data = common.read_string_file() inputs = [int(i) for i in next(input_data).split(",")] debug(inputs) boards = [] vals = [] for line in input_data: if not line: if vals: boards.append(Board(vals)) vals = [] else: vals.append([l for l in line.split(" ") if l]) remaining_boards = len(boards) print_boards() for input_val in inputs: debug(f"{input_val=}") for board in boards: if not board.winning: board.set_val(input_val) if board.check_for_win(): if not find_last: print_boards() return board.score(input_val) else: remaining_boards -= 1 if not remaining_boards: print_boards() return board.score(input_val) print_boards()
def process_p2(): vals = {} for (key, count_index, tiebreak) in (("oxygen", 0, "1"), ("co2", 1, "0")): input_data = [l for l in common.read_string_file()] debug(key) for i in range(len(input_data[0])): c = Counter() for l in input_data: c[l[i]] += 1 mc = c.most_common(2) debug(mc) if (len(mc) > 1) and (mc[0][1] == mc[1][1]): keepbit = tiebreak else: keepbit = mc[count_index][0] input_data = [l for l in input_data if l[i] == keepbit] debug(f"{i=} {c=} {input_data=} {keepbit=}") if len(input_data) == 1: vals[key] = int("".join(input_data[0]), 2) break debug(vals) return vals["oxygen"] * vals["co2"]
def process(): input_data = common.read_string_file() for vals in input_data: if vals[0] != "#": # debug(vals) ipt = [] n = 0 while n < len(vals): if vals[n] in ("[", "]", ","): ipt.append(vals[n]) n += 1 else: num = [] for i in range(n, len(vals)): if vals[i] in "0123456789": num.append(vals[i]) else: break if num: ipt.append(int("".join(num))) n = i yield ipt
def __init__(self): d = {} self.folds = [] input_data = common.read_string_file() maxx = 0 maxy = 0 for line in input_data: if not line.strip(): break (x, y) = [int(l) for l in line.strip().split(",")] d[(x, y)] = 1 if x >= maxx: maxx = x + 1 if y >= maxy: maxy = y + 1 self.array = np.full((maxy, maxx), False, dtype=bool) for (x, y) in d.keys(): self.array[y][x] = True for line in input_data: if line: vals = line[11:].split("=") self.folds.append((vals[0], int(vals[1])))
def process(): rets = [] for s in next(common.read_string_file()).split(", "): rets.extend([int(c.strip()) for c in s[2:].split("..")]) return rets
def process(): input_data = common.read_string_file() return Grid(input_data)
def process(console_cls=Console): input_data = common.read_string_file() console = console_cls([l for l in input_data]) return console