コード例 #1
0
def get_data():
    lines = readlines(rpath('day15.txt', 'aoc2021'))
    graph = {}
    for y, line in enumerate(lines):
        for x, r in enumerate(line):
            graph[x, y] = int(r)
    return graph, len(line)
コード例 #2
0
def get_data():
  data = readlines(rpath('day13.txt', 'aoc2021'))
  pic = [line.split(',') for line in data if ',' in line]
  pic = [(int(x), int(y)) for x, y in pic]
  folds = [line.replace('fold along ', '').split('=')
    for line in data if line.startswith('fold')]
  folds = [(x, int(y)) for x, y in folds]
  return pic, folds
コード例 #3
0
def get_data():
  data = readlines(rpath('day20.txt', 'aoc2021'), sep='\n\n')
  enhancement, image = data
  image = image.strip().split('\n')
  imgsz = len(image)
  image = {
    (x, y): c
    for y, line in enumerate(image)
    for x, c in enumerate(line)}
  return image, enhancement, imgsz
コード例 #4
0
def get_data():
  data = readlines(rpath('day19.txt', 'aoc2021'), sep='\n\n')
  scanners = []
  for sc in data:
    lines = sc.split('\n')
    name, vecs = lines[0], lines[1:]
    name = name.replace('--- scanner ', 'Scn').replace(' ---', '')
    vecs = [Vector(*[int(q) for q in l.split(',')]) for l in vecs]
    scanners.append(Scanner(name, vecs))
  relations = get_relations(scanners)
  return scanners, relations
コード例 #5
0
def get_data():
    data = readlines(rpath('day12.txt', 'aoc2021'))
    graph = {'upper': set()}
    for line in data:
        src, dst = line.split('-')
        if src.isupper():
            graph['upper'].add(src)
        if dst.isupper():
            graph['upper'].add(dst)

        if src in graph:
            graph[src].append(dst)
        else:
            graph[src] = [dst]
        if dst in graph:
            graph[dst].append(src)
        else:
            graph[dst] = [src]
    return graph
コード例 #6
0
def get_data():
  return readlines(rpath('day07.txt', 'aoc2021'), conv=int, sep=',')
コード例 #7
0
    return p


def part1(data):
    rel = parse(data)
    objs = set(sum(data, []))

    total = 0
    for obj in objs:
        total += len(path_to_com(rel, obj))

    return total


def part2(data):
    rel = parse(data)
    pyou, psan = ['YOU'], ['SAN']
    pyou = path_to_com(rel, 'YOU')
    psan = path_to_com(rel, 'SAN')

    for i, o in enumerate(pyou):
        if o in psan:
            return i + psan.index(o) - 2


if __name__ == '__main__':
    data = readlines(rpath('day06.txt', 'aoc2019'),
                     conv=lambda m: m.split(')'))
    print(part1(data))
    print(part2(data))
コード例 #8
0

def get_loop_size(sub, target):
    i = 1
    val = 1
    while True:
        val = transform(sub, val)
        if val == target:
            return i
        i += 1


def get_encryption_key(public, loop_sz):
    return transform(public, 1, n=loop_sz)


def part1(cpub, dpub):
    card_loopsz = get_loop_size(7, cpub)
    door_loopsz = get_loop_size(7, dpub)
    card_key = get_encryption_key(cpub, door_loopsz)
    door_key = get_encryption_key(dpub, card_loopsz)

    assert card_key == door_key

    return card_key


if __name__ == '__main__':
    card_pub, door_pub = readlines(rpath('day25.txt', 'aoc2020'), conv=int)
    print(part1(card_pub, door_pub))
コード例 #9
0
def part2(data):
    signals = []
    for perm in permutations((5, 6, 7, 8, 9)):
        cpus = [
            Intcode(debug=False, wfi_mode=True, inputs=[p])
            for _, p in enumerate(perm)
        ]
        for cpu in cpus:
            cpu.load_program(data)

        out = 0
        i = 0
        while True:
            cpu = cpus[i % 5]
            cpu.feed_inputs(out)
            cpu.run()
            out = cpu.outputs[-1]
            if all([cpu.halt for cpu in cpus]):
                break
            i += 1
        signals.append(cpu.outputs[-1])
    return max(signals)


if __name__ == '__main__':
    data = readlines(rpath('day07.txt', 'aoc2019'), sep=',', conv=int)

    print(part1(data))
    print(part2(data))
コード例 #10
0
def get_data():
    data = readlines(rpath('day11.txt', 'aoc2021'))
    data = {(x, y): int(c)
            for y, line in enumerate(data) for x, c in enumerate(line)}
    return data
コード例 #11
0
    ls = Node.make_nodes(data)

    for i in range(100):
        cups = ls.take3()
        ls.put(cups, ls.dst(cups))

    ls.active = ls.get(1)
    return ''.join([str(n.val) for n in ls.nodes()[1:]])


def part2(data):
    data += list(range(max(data) + 1, 1_000_001))
    assert len(data) == 1_000_000
    ls = Node.make_nodes(data)

    for i in range(10_000_000):
        cups = ls.take3()
        ls.put(cups, ls.dst(cups))

    one1 = ls.get(1).next
    one2 = one1.next
    return one1.val * one2.val


if __name__ == '__main__':
    data = readlines(rpath('day23.txt', 'aoc2020'),
                     conv=lambda m: [int(x) for x in m])[0]

    print(part1(data))
    print(part2(data))
コード例 #12
0
def get_data():
    data = readlines(rpath('day17.txt', 'aoc2021'))[0]
    data = re.findall(r'(x|y)=(-?\d+\.\.-?\d+)', data)
    x, y = [(int(x), int(y)) for x, y in [d[1].split('..') for d in data]]
    return x, y
コード例 #13
0
def part1(data):
    all_ings_list = sum([d[0] for d in data], [])
    all_ings = set(all_ings_list)
    unsafe_ings = set.union(*get_mapping(data).values())
    safe_ings = all_ings - unsafe_ings
    return sum([all_ings_list.count(i) for i in safe_ings])


def part2(data):
    mapping = get_mapping(data)

    identified = {}
    while len(identified) != len(mapping.keys()):
        for agen, ings in mapping.items():
            if len(ings) == 1:
                ing = ings.pop()
                identified[agen] = ing
                for a, i in mapping.items():
                    mapping[a] -= {ing}
                break

    return ','.join(
        [x[1] for x in sorted(identified.items(), key=lambda m: m[0])])


if __name__ == '__main__':
    data = readlines(rpath('day21.txt', 'aoc2020'), conv=parse)

    print(part1(data))
    print(part2(data))
コード例 #14
0
        if first == string[0]:
            return match(ruleset, rule[1:], string[1:])
    elif isinstance(first, list):
        matches = []
        for subrule in first:
            matches.append(match(ruleset, subrule + rule[1:], string))
        return any(matches)


def part1(ruleset, strings):
    matches = [match(ruleset, [0], string) for string in strings]
    return len([m for m in matches if m is True])


def part2(ruleset, strings):
    ruleset[8] = [[42], [42, 8]]
    ruleset[11] = [[42, 31], [42, 11, 31]]
    matches = [match(ruleset, [0], string) for string in strings]
    return len([m for m in matches if m is True])


if __name__ == '__main__':
    data = readlines(rpath('day19.txt', 'aoc2020'), sep='\n\n')

    rules, strings = data[0], data[1]
    strings = strings.split('\n')
    ruleset = parse_rules(rules)

    print(part1(ruleset, strings))
    print(part2(ruleset, strings))
コード例 #15
0
    if mono:
      valid.append(i)

  return valid

def part1(data):
  return len(valid1(data))

def part2(data):
  valid = valid1(data)
  new = []
  for n in valid:
    strn = str(n)
    match = re.search(rx, strn)
    if match:
      strpd = strn.replace(match.group(0), '')
      m2 = re.search(rx, strpd)
      if not m2 and len(strpd) in (2,3) and len(set(strpd)) != len(strpd):
        new.append(n)

    else:
      new.append(n)
  return len(new)


if __name__ == '__main__':
  data = readlines(rpath('day04.txt', 'aoc2019'),
                   conv=lambda m: [int(x) for x in m.split('-')])[0]
  print(part1(data))
  print(part2(data))
コード例 #16
0
    # Now if a given field is valid in only one column across all tickets,
    # then that must be it, we save that information and remove the column
    # marked as valid from remaining fields
    field_cols = {}
    while len(field_cols) != field_cnt:
        field, val = [(f, v) for f, v in rng_cols.items()
                      if v.count('1') == 1][0]
        field_cols[field] = val.index('1')
        rng_cols = {
            rname: f'{int(c, 2) & ~int(val, 2):020b}'
            for rname, c in rng_cols.items()
        }

    my_fields = {
        k: v
        for k, v in field_cols.items() if k.startswith('departure')
    }
    res = [mytick[i] for i in my_fields.values()]
    return reduce(mul, res)


if __name__ == '__main__':
    data = [
        d.split('\n')
        for d in readlines(rpath('day16.txt', 'aoc2020'), sep='\n\n')
    ]
    ranges, mytick, tickets, allrng = parse(data)

    print(part1(ranges, tickets, allrng))
    print(part2(ranges, tickets, allrng, mytick))
コード例 #17
0
            l0 = numbers.get(0, [])
            l0.append(i)
            numbers[0] = l0
            last = 0

        else:
            new = ls[-1] - ls[-2]
            newl = numbers.get(new, [])
            newl.append(i)
            numbers[new] = newl
            last = new

        i += 1
    return last


def part1(data):
    return task(data, 2020)


def part2(data):
    # It gets done in about half a minute
    return task(data, 30_000_000)


if __name__ == '__main__':
    data = readlines(rpath('day15.txt', 'aoc2020'),
                     conv=lambda l: [int(x) for x in l.split(',')])[0]
    print(part1(data))
    print(part2(data))
コード例 #18
0
def get_data():
    return readlines(rpath('day18.txt', 'aoc2021'),
                     conv=lambda line: parse(eval(line)))
コード例 #19
0
                new_active.append((x, y, z, w))
        else:
            if neighcnt == 3:
                new_active.append((x, y, z, w))
    return new_active


def part1(data):
    active = [(x, y, 0) for y, line in enumerate(data)
              for x, val in enumerate(line) if val == '#']

    a = active
    for i in range(6):
        a = iterate3d(a)
    return len(a)


def part2(data):
    active = [(x, y, 0, 0) for y, line in enumerate(data)
              for x, val in enumerate(line) if val == '#']
    a = active
    for i in range(6):
        a = iterate4d(a)
    return len(a)


if __name__ == "__main__":
    data = readlines(rpath('day17.txt', 'aoc2020'))
    print(part1(data))
    print(part2(data))
コード例 #20
0
def part1(map_):
    dst = [pos for pos, status in map_.items()
           if status == Droid.STATUS_OXY][0]
    path = find_path(map_, [(0, 0)], dst)
    return len(path) - 1


def part2(map_):
    oxy = [pos for pos, status in map_.items()
           if status == Droid.STATUS_OXY][0]
    adjmap = {**map_}

    minutes = 0
    while any([state == Droid.STATUS_OK for _, state in adjmap.items()]):
        for oxy in [
                pos for pos, status in adjmap.items()
                if status == Droid.STATUS_OXY
        ]:
            for adj in get_adjacent(map_, *oxy):
                adjmap[adj] = Droid.STATUS_OXY
        minutes += 1

    return minutes


if __name__ == '__main__':
    data = readlines(rpath('day15.txt', 'aoc2019'), conv=int, sep=',')
    map_ = get_map(data)
    print(part1(map_))
    print(part2(map_))
コード例 #21
0
    num = ls[i]
    for n, k in permutations(range(plen + 1), 2):
        if n != k and ls[i - n] + ls[i - k] == num:
            return True
    return False


def part1(data):
    for i, n in enumerate(data):
        if i < 25:
            continue

        if not sum_of_previous(data, i, plen=25):
            return n


def part2(ls, n):
    for plen in range(2, len(ls)):
        for i in range(len(ls) - plen):
            chunk = ls[i:i + plen]
            if sum(chunk) == n:
                return min(chunk) + max(chunk)
    return None


if __name__ == '__main__':
    data = readlines(rpath('day09.txt', 'aoc2020'), conv=int)
    part1_res = part1(data)
    print(part1_res)
    print(part2(data, part1_res))
コード例 #22
0
def part1(p1p, p2p):
  pmin = min(set(p1p) & set(p2p), key=lambda p: dist(p))
  return dist(pmin)

def part2(p1p, p2p):
  isect = set(p1p) & set(p2p) - set([(0,0)])
  p1d, p2d = {}, {}

  for i, p in enumerate(p1p):
    if p in isect:
      p1d[p] = i

  for i, p in enumerate(p2p):
    if p in isect:
      p2d[p] = i

  pd = {p: d+p2d[p] for p, d in p1d.items()}

  return min(pd.values())


if __name__ == '__main__':
  data = readlines(rpath('day03.txt', 'aoc2019'), conv=lambda l: l.split(','))
  p1, p2 = data
  p1p = get_points(p1)
  p2p = get_points(p2)

  print(part1(p1p, p2p))
  print(part2(p1p, p2p))
コード例 #23
0
def get_layers(data, w, h):
    return [data[i:i + w * h] for i in range(0, len(data), w * h)]


def part1(layers):
    min0layer = min(layers, key=lambda m: m.count('0'))
    return min0layer.count('1') * min0layer.count('2')


def part2(layers, w, h):
    img = layers[0]
    for layer in layers[1:]:
        new_img = ''
        for i, l in zip(img, layer):
            new_img += l if i == '2' else i
        img = new_img

    img = [img[i:i + w] for i in range(0, len(img), w)]
    for line in img:
        print(line.replace('0', ' ').replace('1', '#'))


if __name__ == '__main__':
    data = readlines(rpath('day08.txt', 'aoc2019'))[0]
    w, h = 25, 6
    layers = get_layers(data, w, h)

    print(part1(layers))
    part2(layers, w, h)
コード例 #24
0
                firstdata = datad[t2]
                firstlbl = t2
                break

    img = get_img(lines)
    img = join_img(img)

    imgc = img
    for i in range(4):
        hashcnt, monstercnt = find_monsters(imgc)
        if monstercnt:
            return hashcnt
        imgc = rotated(imgc)

    imgc = f(imgc)
    for i in range(4):
        hashcnt, monstercnt = find_monsters(imgc)
        if monstercnt:
            return hashcnt
        imgc = rotated(imgc)


if __name__ == '__main__':
    data = readlines(rpath('day20.txt', 'aoc2020'), sep='\n\n', conv=parse)
    datad = dict(data)
    conns = all_conns(data)
    corners = get_corners(conns)

    print(part1(corners))
    print(part2(data, datad, conns, corners))
コード例 #25
0
def part2(asteroids):
    best = best_monitoring(asteroids)[1]
    dets = [
        Detection(best, other, slope(best, other), distance(best, other))
        for other in asteroids
    ]
    dets.sort(key=lambda m: -m.dist)
    slopes = set([det.slope for det in dets])

    for i, slp in enumerate(cycle(slopesort(slopes))):
        others = [det for det in dets if det.slope == slp]
        if others:
            try:
                closest = others.pop()
                dets.remove(closest)
            except IndexError:
                pass

        if i == 199:
            x, y = closest.dst
            return 100 * x + y


if __name__ == '__main__':
    data = readlines(rpath('day10.txt', 'aoc2019'))
    asteroids = [(x, y) for y, line in enumerate(data)
                 for x, char in enumerate(line) if char == '#']
    print(part1(asteroids))
    print(part2(asteroids))
コード例 #26
0
def get_data():
    data = readlines(rpath('day04.txt', 'aoc2021'), sep='\n\n')
    nums, boards = data[0], data[1:]
    nums = [int(n) for n in nums.split(',')]
    boards = [[int(n) for n in re.split(r'\s+', b)] for b in boards]
    return nums, boards
コード例 #27
0
def get_data():
    return readlines(rpath('day09.txt', 'aoc2021'))
コード例 #28
0
from util.helpers import readlines, rpath, tpath


def fuel_req(mass):
    return mass // 3 - 2


def additional(mass):
    add = 0
    mass = fuel_req(mass)
    while mass > 0:
        add += mass
        mass = fuel_req(mass)
    return add


def part1(data):
    return sum([fuel_req(mass) for mass in data])


def part2(data):
    return sum([fuel_req(m) + additional(fuel_req(m)) for m in data])


if __name__ == '__main__':
    data = readlines(rpath('day01.txt', 'aoc2019'), conv=int)

    print(part1(data))
    print(part2(data))