Пример #1
0
def main():
    with Path('input', '19').open() as f:
        scanners = [
            Scanner([Vector(map(int, p.split(','))) for p in chunk[1:]])
            for chunk in readchunks(f)
        ]
    scanners[0].loc = zero
    oriented = {scanners[0]}
    while True:
        toorient = [s for s in scanners if s not in oriented]
        if not toorient:
            break
        oriented_ = set()
        for s in toorient:
            for t in oriented:
                if s.reorient(t):
                    oriented_.add(s)
                    break
        oriented |= oriented_

    def distances():
        for i, s in enumerate(scanners):
            for t in scanners[i + 1:]:
                yield (s.loc - t.loc).manhattan()

    print(max(distances()))
Пример #2
0
def main():
    rules = {}
    with Path('input', '19').open() as f:
        rulelines, messages = readchunks(f)
        for r in rulelines + ['8: 42 | 42 8', '11: 42 31 | 42 11 31']:
            i, text = r.split(': ')
            rules[int(i)] = Or.parse(rules, text)
        print(sum(1 for m in messages if rules[0].accept(m)))
Пример #3
0
def main():
    with Path('input', '13').open() as f:
        dots, folds = readchunks(f)
    paper = Paper(tuple(map(int, d.split(','))) for d in dots)
    for fold in folds[:1]:
        axis, n = fold.split('=')
        paper.fold(0 if 'x' == axis[-1] else 1, int(n))
    print(len(paper))
Пример #4
0
def main():
    with Path('input', '20').open() as f:
        (algo,), lines = readchunks(f)
    algo = ['#' == c for c in algo]
    image = Image({Vector([x, y]): '#' == c for y, l in enumerate(lines) for x, c in enumerate(l)})
    for _ in range(50):
        image.apply(algo)
    print(image.lit())
Пример #5
0
def main():
    with Path('input', '14').open() as f:
        (template, ), rules = readchunks(f)
    template = Template(template)
    rules = {x: y for x, _, y in (r.split() for r in rules)}
    for _ in range(10):
        template = Template(list(template.insert(rules)))
    print(template.answer())
Пример #6
0
def main():
    valid = 0
    with Path('input', '4').open() as f:
        for chunk in readchunks(f):
            p = {}
            for l in chunk:
                p.update(e.split(':') for e in l.split(' '))
            valid += fields <= p.keys()
    print(valid)
Пример #7
0
def main():
    with Path('input', '4').open() as f:
        i = readchunks(f)
        numbers, = ([int(n) for n in l.split(',')] for l in next(i))
        boards = [Board(lines) for lines in i]
    for n in numbers:
        for b in boards:
            if b.fire(n):
                print(sum(b.unmarked()) * n)
                return
Пример #8
0
def main():
    tiles = []
    with Path('input', '20').open() as f:
        for chunk in readchunks(f):
            tiles.append(Tile.parse(chunk))
    normedgetotiles = defaultdict(list)
    for t in tiles:
        for e in t.normedges:
            normedgetotiles[e].append(t)
    outertiles = defaultdict(int)
    for e, etiles in normedgetotiles.items():
        if 1 == len(etiles):
            outertiles[etiles[0]] += 1
    print(reduce(operator.mul, (t.n for t, k in outertiles.items() if k == 2)))
Пример #9
0
def main():
    with Path('input', '4').open() as f:
        i = readchunks(f)
        numbers, = ([int(n) for n in l.split(',')] for l in next(i))
        boards = [Board(lines) for lines in i]
    for n in numbers:
        boards_ = []
        for b in boards:
            if not b.fire(n):
                boards_.append(b)
        if not boards_:
            print(sum(b.unmarked()) * n)
            break
        boards = boards_
Пример #10
0
def main():
    with Path('input', '19').open() as f:
        scanners = [
            Scanner([Vector(map(int, p.split(','))) for p in chunk[1:]])
            for chunk in readchunks(f)
        ]
    oriented = {scanners[0]}
    while True:
        toorient = [s for s in scanners if s not in oriented]
        if not toorient:
            break
        oriented_ = set()
        for s in toorient:
            for t in oriented:
                if s.reorient(t):
                    oriented_.add(s)
                    break
        oriented |= oriented_
    print(len({b for s in scanners for b in s.beacons}))
Пример #11
0
def main():
    oktickets = []
    if True:
        with Path('input', '16').open() as f:
            for chunk in readchunks(f):
                if 'your ticket:' == chunk[0]:
                    myticket = [int(w) for w in chunk[1].split(',')]
                elif 'nearby tickets:' == chunk[0]:
                    for t in islice(chunk, 1, None):
                        vals = [int(w) for w in t.split(',')]
                        if all(any(f.accept(v) for f in fields) for v in vals):
                            oktickets.append(vals)
                else:
                    fields = []
                    for rule in chunk:
                        name, ranges = rule.split(': ')
                        ranges = ranges.split(' or ')
                        fields.append(
                            Field(name, [
                                range(min, max + 1) for r in ranges
                                for min, max in [map(int, r.split('-'))]
                            ]))
    indexsets = {f: set(range(len(fields))) for f in fields}
    indexes = {}
    while len(indexes) < len(fields):
        for t in oktickets:
            for index in range(len(fields)):
                for f, s in indexsets.items():
                    if not f.accept(t[index]):
                        s.discard(index)
        for f, s in indexsets.items():
            if 1 == len(s):
                i, = s
                indexes[f] = i
        for f in indexes:
            indexsets.pop(f, None)
        for s in indexsets.values():
            s.difference_update(indexes.values())
    print(
        reduce(operator.mul,
               (myticket[indexes[f]]
                for f in fields if f.name.startswith('departure'))))
Пример #12
0
 def badvals():
     with Path('input', '16').open() as f:
         for chunk in readchunks(f):
             if 'your ticket:' == chunk[0]:
                 pass
             elif 'nearby tickets:' == chunk[0]:
                 for t in islice(chunk, 1, None):
                     vals = [int(w) for w in t.split(',')]
                     for v in vals:
                         if all(v not in r for ranges in fields.values()
                                for r in ranges):
                             yield v
             else:
                 fields = {}
                 for rule in chunk:
                     name, ranges = rule.split(': ')
                     ranges = ranges.split(' or ')
                     fields[name] = [
                         range(min, max + 1) for r in ranges
                         for min, max in [map(int, r.split('-'))]
                     ]
Пример #13
0
def main():
    with Path('input', '20').open() as f:
        tiles = [Tile(chunk[1:]) for chunk in readchunks(f)]
    void = Void(tiles)
    solution = {}

    def solve(x, y):
        for i, t in enumerate(tiles):
            for o in t.orientations():
                if solution.get(
                    (x - 1, y), void).acceptright(o) and solution.get(
                        (x, y - 1), void).acceptbottom(o):
                    tiles.pop(i)
                    solution[x, y] = o
                    return

    for rank in range(gridsize):
        solve(rank, rank)
        for file in range(rank + 1, gridsize):
            solve(file, rank)
            solve(rank, file)

    def gridrows():
        for y in range(gridsize):
            for r in range(1, tilesize - 1):
                yield ''.join(solution[x, y].rows[r][c]
                              for x in range(gridsize)
                              for c in range(1, tilesize - 1))

    grid = BaseTile(list(gridrows()))
    for o in nessie.orientations():
        locations = list(grid.find(o))
        if locations:
            break
    for loc in locations:
        grid.delete(o, *loc)
    print(grid.hashes())
Пример #14
0
 def counts():
     with Path('input', '6').open() as f:
         for group in readchunks(f):
             conjunction = set(ascii_lowercase)
             conjunction.intersection_update(*group)
             yield len(conjunction)
Пример #15
0
def main():
    with Path('input', '22').open() as f:
        decks = [[int(l) for l in chunk[1:]] for chunk in readchunks(f)]
    print(sum(c * (1 + i) for i, c in enumerate(reversed(decks[consume(decks)]))))
Пример #16
0
 def counts():
     with Path('input', '6').open() as f:
         for group in readchunks(f):
             yield len(set(chain(*group)))