예제 #1
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
예제 #2
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
예제 #3
0
def find_all_paths2(graph, start, end):
    path = []
    paths = []
    queue = [(start, end, path)]
    while queue:
        start, end, path = queue.pop()
        path = path + [start]
        if start == end:
            paths.append(path)
        for node in set(graph[start]):
            if node in ("start", "end"):
                if node not in path:
                    queue.append((node, end, path))
            elif node.islower():
                lcnodes = lfilter(
                    lambda x: x not in ("start", "end") and x.islower(), path)
                if len(lcnodes) == len(set(lcnodes)) and path.count(node) <= 1:
                    queue.append((node, end, path))
                elif (len(lcnodes) - 1 == len(set(lcnodes))
                      and path.count(node) < 1):
                    queue.append((node, end, path))

            elif node.isupper():
                queue.append((node, end, path))
    return paths
def filter_by_func(func: Callable, lines: list[str]) -> str:
    colnum = 0
    while len(lines) > 1:
        qualified = func([ln[colnum] for ln in lines])
        lines = lfilter(lambda x: x[colnum] == qualified, lines)
        colnum = colnum + 1
    assert len(lines) == 1
    return lines[0]
예제 #5
0
def process_two(data):
    numbers, boards = data
    for number in numbers:
        boards = [change_board(number, board) for board in boards]
        if len(boards) == 1:
            if check_for_winner(boards[0], number):
                return check_for_winner(boards[0], number)
        else:
            boards = lfilter(lambda b: not check_for_winner(b, number), boards)
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
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 filter_row(row):
     cols = lfilter(lambda i_r: i_r[0] in filtered_cols, enumerate(row))
     return lpluck(1, cols)
예제 #9
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 decipher_line(line):
    signals, value = line
    all_chars = lconcat(
        map(partial(filter, lambda x: "." not in x), lconcat(NUMS.values())))
    segments = {}
    base = {NUM_SEGS.get(len(d)): d for d in value + signals}
    known = keyfilter(lambda x: x is not None, base)

    # If it's in 7 not 1 it's a.
    segments["a"] = (set(known[7]) - set(known[1])).pop()
    assert len(segments.keys()) == len(set(segments.values()))

    # If we have a three-letter--i.e. 7--then whatever six-letter is not a
    # superset of it is six
    sixes = set(filter(lambda x: len(x) in (6, ), signals))
    for t in sixes:
        if not set(t) >= set(known[7]):
            known[6] = t
            assert len(set(known[7]) - set(known[6])) == 1
            segments["c"] = (set(known[7]) - set(known[6])).pop()

    assert len(segments.keys()) == len(set(segments.values()))

    # Now we know what c is, f is whatever is in 1 that's not a or c:
    ac = list(pick(["a", "c"], segments).values())
    assert len(set(known[1]) - set(ac)) == 1
    segments["f"] = (set(known[1]) - set(ac)).pop()
    assert len(segments.keys()) == len(set(segments.values()))

    # Now we know acf, we know that any signal lacking f is 2:
    twos = lfilter(lambda x: segments["f"] not in x, signals)
    assert len(twos) == 1
    known[2] = twos[0]

    # Now whatever's in 6 that isn't in 7|2 is b:
    seven_u_two = set(known[7]).union(set(known[2]))
    assert len(set(known[6]) - seven_u_two) == 1
    segments["b"] = (set(known[6]) - seven_u_two).pop()
    assert len(segments.keys()) == len(set(segments.values()))

    # Whatever isn't these in four is d:
    four_not_bcf = set(known[4]) - set(
        pick(["b", "c", "f"], segments).values())
    assert len(four_not_bcf) == 1
    segments["d"] = four_not_bcf.pop()
    assert len(segments.keys()) == len(set(segments.values()))

    # eight minus d is zero:
    known[0] = "".join(sorted(filter(lambda x: x != segments["d"], known[8])))

    # nine is whatever six-length signal isn't 0 or 6:
    nine = [x for x in sixes if x not in known.values()]
    assert len(nine) == 1
    known[9] = nine[0]

    # whatever is in 2 but not in 9 is e:
    two_not_nine = set(known[2]) - set(known[9])
    assert len(two_not_nine) == 1
    segments["e"] = two_not_nine.pop()
    assert len(segments.keys()) == len(set(segments.values()))

    # Whatever of the five-length signals contains b is 5:
    fives = set(filter(lambda x: len(x) in (5, ), signals))
    five = [x for x in fives if segments["b"] in x]
    assert len(five) == 1
    known[5] = five[0]

    # Whatever five-length isn't 2 or 5 is 3:
    three = [x for x in fives if x not in (known[2], known[5])]
    assert len(three) == 1
    known[3] = three[0]

    # Whatever's in the signal that isn't in segments values must be g:
    leftover = set(all_chars) - set(segments.values())
    assert len(leftover) == 1
    segments["g"] = leftover.pop()

    assert len(known) == 10
    codex = {v: k for k, v in known.items()}
    digits = ""
    for num in value:
        digits = digits + str(codex[num])

    return int(digits, 10)
def process_one(data):
    values = lconcat([line[1] for line in data])
    return len(lfilter(lambda d: len(d) in NUM_SEGS, values))
예제 #12
0
def called_winner(board, called_numbers):
    numbers = lfilter(lambda n: n not in called_numbers, lconcat(board))
    return sum(map(int, numbers)) * int(called_numbers[-1])
예제 #13
0
def adjacent_transforms(dimensions: int,
                        omit_origin: bool = True) -> List[Tuple]:
    adj = product([-1, 0, 1], repeat=dimensions)
    not_origin = lambda x: not all([_ == 0 for _ in x])
    return lfilter(not_origin, adj) if omit_origin else adj