Esempio n. 1
0
    def naive_step_inner(curr):
        @cache
        def alter_pair(pair):
            return pair[0] + rules[pair] + pair[1]

        pairs = tuple(lmap("".join, sliding_window(2, curr)))
        return do_merge(tuple(lmap(alter_pair, pairs)))
Esempio n. 2
0
def process_two(data):
    oxy_lines = data[:]
    colnum = 0
    while len(oxy_lines) > 1:
        cols = parse_lines_into_cols(oxy_lines)
        most_common, mc_count = lmap(str,
                                     Counter(cols[colnum]).most_common()[0])
        least_common, lc_count = lmap(str,
                                      Counter(cols[colnum]).most_common()[-1])
        if mc_count == lc_count:
            most_common = "1"
        oxy_lines = lfilter(lambda x: x[colnum] == most_common, oxy_lines)
        colnum = colnum + 1

    oxy_rating = int(oxy_lines[0], 2)

    co_lines = data[:]
    colnum = 0
    while len(co_lines) > 1:
        cols = parse_lines_into_cols(co_lines)
        most_common, mc_count = lmap(str,
                                     Counter(cols[colnum]).most_common()[0])
        least_common, lc_count = lmap(str,
                                      Counter(cols[colnum]).most_common()[-1])
        if mc_count == lc_count:
            least_common = "0"
        co_lines = lfilter(lambda x: x[colnum] == least_common, co_lines)
        colnum = colnum + 1

    co_rating = int(co_lines[0], 2)

    return oxy_rating * co_rating
Esempio n. 3
0
def parse_input(data: str):
    sections = data.split("\n\n")
    numbers = sections[0].split(",")
    boards = sections[1:]
    lboards = lmap(splitstriplines, boards)
    dboards = lmap(lambda b: lmap(str.split, b), lboards)
    return (numbers, dboards)
def rearrange_data(data):
    # We want to have an ordered bunch of rows, corresponding to each puzzle,
    # and each row should have the puzzle id and the list of people's times in
    # the same order as the intiial entries.
    # We can think about sorting it differently another time.
    entries = [data["members"][k] for k in data["members"]]
    ordered = sorted(entries, key=lambda x: -x["local_score"])
    names = lmap(lambda n: NAMES.get(n, n), lpluck("name", ordered))
    days = lmap(methodcaller("keys"), lpluck("completion_day_level", ordered))
    latest_day = max(map(int, lconcat(days)))
    puzzle_rows = []

    def get_timestamp(day, part, entry):
        times = entry["completion_day_level"]
        timestamp = (times.get(str(day), {}).get(str(part),
                                                 {}).get("get_star_ts", 0))
        return timestamp

    for i in range(1, 1 + latest_day):
        p1_info = []
        p2_info = []
        for entry in ordered:
            part_one_ts = get_timestamp(i, 1, entry)
            p1_info.append(part_one_ts)
            part_two_ts = get_timestamp(i, 2, entry)
            p2_info.append(part_two_ts)
        puzzle_rows.append(p1_info)
        puzzle_rows.append(p2_info)

    def check(idx_item):
        return sum([x[idx_item[0]] for x in puzzle_rows]) > 0

    filtered = lfilter(check, enumerate(names))
    filtered_cols = lpluck(0, filtered)
    filtered_names = lpluck(1, filtered)

    def filter_row(row):
        cols = lfilter(lambda i_r: i_r[0] in filtered_cols, enumerate(row))
        return lpluck(1, cols)

    filtered_rows = lmap(filter_row, puzzle_rows)

    def mark_winner(row):
        winner = min(filter(lambda x: x != 0, row))
        return [(item, item == winner) for item in row]

    with_winners = lmap(mark_winner, filtered_rows)

    return (filtered_names, with_winners)
def process_data(data):
    names, rows = rearrange_data(data)
    longest_name = max([*map(len, names)] + [11])
    # print_names = [name.rjust(longest_name) for name in names]
    print_names = rjust_row(longest_name, names)
    headers = "        ".join(["Puzzle"] + print_names)
    hr = "".join(["-" * len(headers)])
    times = lmap(lambda _: fmt_timestamps(*_), enumerate(rows))
    # pdb.set_trace()
    print_times = [rjust_row(longest_name, row) for row in times]

    def add_puzzle(day, times):
        base_day = str(day // 2 + 1)
        puzzle = "1" if day % 2 == 0 else "2"
        return [f"{base_day}.{puzzle}".rjust(6)] + times

    print_rows = [add_puzzle(i, row) for i, row in enumerate(print_times)]

    print(headers)
    print(hr)
    for i, row in enumerate(print_rows):
        if i != 0 and i % 10 == 0:
            print(hr)
            print(headers)
            print(hr)
        print("        ".join(row))
def rjust_row(width, row):
    justify = methodcaller("rjust", width)
    brighten = lambda s: f"{Fore.CYAN}{s}{Style.RESET_ALL}"
    make_cell = lambda c: brighten(justify(c[0])) if c[1] else justify(c[0])
    if len(row[0]) == 2 and row[0][1] in (True, False):
        return lmap(make_cell, row)
    return [justify(str(col)) for col in row]
Esempio n. 7
0
def get_lows(data):
    grid = []
    gridd = {}
    for y, row in enumerate(data):
        for x, char in enumerate(row):
            grid.append(aoc.Point(x=x, y=y))
            gridd[aoc.Point(x=x, y=y)] = (char, None)
    for pt in gridd:
        above = gridd.get(aoc.Point(x=pt.x, y=pt.y - 1))
        below = gridd.get(aoc.Point(x=pt.x, y=pt.y + 1))
        left = gridd.get(aoc.Point(x=pt.x - 1, y=pt.y))
        right = gridd.get(aoc.Point(x=pt.x + 1, y=pt.y))
        adjs = lcompact([above, below, left, right])
        curr = int(gridd[pt][0])
        low = True
        for adj in adjs:
            if curr >= int(adj[0]):
                low = False
        if low:
            gridd[pt] = (gridd[pt][0], curr + 1)

    lows = lmap(lambda x: x,
                lfilter(lambda x: x[1][1] is not None, gridd.items()))

    return lows
Esempio n. 8
0
def process_one(data):
    numbers, boards = data
    called_numbers, rest = numbers[:4], numbers[4:]  # Can't win without 5 nums
    for number in rest:
        called_numbers.append(number)
        check = partial(is_winner, called_numbers)
        if winning_totals := lcompact(lmap(check, boards)):
            return winning_totals[0]
Esempio n. 9
0
def coords_to_lines(coords: set[Point]) -> list[str]:
    getx, gety = attrgetter("x"), attrgetter("y")
    xmax, ymax = max(map(getx, coords)), max(map(gety, coords))

    def get_line(idx):
        vals = (Point(x=xval, y=idx) for xval in range(xmax + 1))
        return "".join("█" if pt in coords else " " for pt in vals)

    return lmap(get_line, range(ymax + 1))
Esempio n. 10
0
def xdo_steps(curr, rules, num):
    pairs = lmap("".join, sliding_window(2, curr))
    couplets = {p: 1 for p in pairs}
    for i in range(num):
        print(i, couplets, sum(couplets.values()))
        new_couplets = {}
        for couplet in couplets:
            triplet = couplet[0] + rules[couplet] + couplet[1]
            newpairs = lmap("".join, sliding_window(2, triplet))
            for np in newpairs:
                if np in new_couplets:
                    new_couplets[np] = new_couplets[np] + 1
                else:
                    new_couplets[np] = 1
        for k in couplets:
            if k in new_couplets:
                new_couplets[k] = new_couplets[k] * couplets[k]
        couplets = new_couplets
    return couplets
def incr_neighbors(grid, center, flashed):
    neighbors = lmap(lambda x: center + Point(*x), adjacent_transforms(2))
    points = lfilter(lambda x: x in grid, neighbors)
    for pt in points:
        grid[pt] = grid[pt] + 1
    for pt in points:
        if pt not in flashed and grid[pt] > 9:
            flashed = flashed + [pt]
            grid, flashed = incr_neighbors(grid, pt, flashed)
    return grid, flashed
Esempio n. 12
0
    def better_step(curr):
        print(len(sequences))

        if curr in sequences:
            return sequences[curr]
        elif len(curr) > 7:
            quads = make_quads(curr)
            altered_quads = map(alter_quad, quads)
            stuff = ""
            for q in altered_quads:
                stuff = stuff[:-1] + q

            if curr not in sequences:
                sequences[curr] = stuff

            return stuff
        else:
            pairs = lmap("".join, sliding_window(2, curr))
            return merge(lmap(alter_pair, pairs))
Esempio n. 13
0
def process_step(curr, rules):
    pairs = lmap("".join, sliding_window(2, curr))

    def alter_pair(pair):
        if pair in rules:
            pair = pair[0] + rules[pair] + pair[1]
        return pair

    def merge(couplets):
        st = ""
        for i, couplet in enumerate(couplets):
            if not st:
                st = couplet
            else:
                st = st[: 2 * (i)] + couplet
        return st

    xx = merge(lmap(alter_pair, pairs))
    xx2 = merge(xx[0])
    return xx2, rules
Esempio n. 14
0
def process_two(data):
    grid = {}
    for y, row in enumerate(data):
        for x, char in enumerate(row):
            grid[aoc.Point(x=x, y=y)] = (char, None)
    lows = get_lows(data)

    basins = lmap(lambda x: explore(grid, x[0], [], [x[0]]), lows)
    sbasins = sorted(basins, key=len)
    threebasins = sbasins[-3:]
    return prod(map(len, threebasins))

    return data
Esempio n. 15
0
def parse_line(line):
    coords = splitstrip(line, "->")
    raw_points = [lmap(int, splitstrip(coord, ",")) for coord in coords]
    points = lmap(lambda x: aoc.Point(*x), raw_points)
    return points
Esempio n. 16
0
def process_two(data):
    lines = lcompact(lmap(make_line_diag, data))
    count = detect_overlap(lines)
    return count
Esempio n. 17
0
def process_one(data):
    lines = lcompact(lmap(make_line, data))
    count = detect_overlap(lines)
    return count
Esempio n. 18
0
def parse_lines_into_cols(data):
    ints = lmap(partial(lmap, int), data)
    crosswise = list(zip(*ints))
    return crosswise
Esempio n. 19
0
def parse_line(line):
    return lmap(aoc.Point.from_string, splitstrip(line, sep="->"))
Esempio n. 20
0
def parse_data(data):
    start, raw_rules = data.split("\n\n")
    rules = lmap(lambda x: splitstrip(x, sep="->"), splitstriplines(raw_rules))
    rules = dict(rules)

    return start, rules
Esempio n. 21
0
def parse_input(data: str):
    sections = data.split("\n\n")
    numbers, raw_boards = sections[0].split(","), sections[1:]
    boards_as_rows = lmap(splitstriplines, raw_boards)
    boards = lmap(lambda b: lmap(str.split, b), boards_as_rows)
    return (numbers, boards)
Esempio n. 22
0
def detect_overlap(lines):
    llines = lmap(list, lines)
    counted = Counter(lconcat(llines))
    overone = {k: v for k, v in counted.items() if v >= 2}
    return len(overone)
def parse_line(line):
    raw_signals, raw_value = splitstrip(line, sep=" | ")
    sortjoin = compose_left(sorted, "".join)
    signals = lmap(sortjoin, raw_signals.split())
    value = lmap(sortjoin, raw_value.split())
    return signals, value
Esempio n. 24
0
def parse_data(data: str) -> tuple[set[Point], list[dict]]:
    raw_coords, raw_instructions = map(splitstriplines, data.split("\n\n"))
    coords = set(map(Point.from_string, raw_coords))
    instructions = lmap(parse_instruction, raw_instructions)
    return (coords, instructions)
Esempio n. 25
0
from toolz import keyfilter
from tadhg_utils import (
    lcompact,
    lconcat,
    lfilter,
    lmap,
    splitstrip,
    splitstriplines,
)


INPUT, TEST = aoc.get_inputs(__file__)
TA1, TA2, A1, A2 = 26397, 288957, 399153, 2995077699

pairs = ("()", "[]", r"{}", "<>")
openers = dict(lmap(tuple, pairs))
closers = {k: v for v, k in openers.items()}
"""
openers = [pair[0] for pair in pairs]
closers = [pair[1] for pair in pairs]
get_c_for_o = dict(zip(openers, closers))
get_o_for_c = dict(zip(closers, openers))
"""


def find_errors(line) -> int:
    error_vals = {
        ")": 3,
        "]": 57,
        "}": 1197,
        ">": 25137,
Esempio n. 26
0
def process_two(data):
    incomplete = lfilter(lambda x: find_errors(x) == 0, data)
    scores = lmap(complete_line, incomplete)
    return sorted(scores)[len(scores) // 2]
def parse_lines(lines):
    return lmap(parse_line, lines)
Esempio n. 28
0
 def alter_quad(quad):
     pairs = lmap("".join, sliding_window(2, quad))
     return merge(lmap(alter_pair, pairs))