Beispiel #1
0
    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())
Beispiel #2
0
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)))
Beispiel #3
0
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):
Beispiel #4
0
    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])
Beispiel #5
0
            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
Beispiel #6
0
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)
Beispiel #7
0
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)
Beispiel #8
0
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))
Beispiel #9
0
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)
Beispiel #10
0
    # 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)
Beispiel #11
0
        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="")
Beispiel #12
0
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()))
Beispiel #13
0
    (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)
Beispiel #14
0
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))