Beispiel #1
0
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, " #")
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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))
Beispiel #7
0
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
Beispiel #8
0
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))
Beispiel #9
0
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
Beispiel #10
0
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
Beispiel #11
0
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
Beispiel #12
0
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
Beispiel #13
0
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)
Beispiel #14
0
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
Beispiel #15
0
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
Beispiel #16
0
def checksum(s):
    return tuple(1 - operator.xor(*c) for c in u.chunks(s, 2))
Beispiel #17
0
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