コード例 #1
0
ファイル: d11_life.py プロジェクト: dncnwtts/adventofcode-1
            if seat == FREE and occupied == 0:
                new_map[i][j] = TAKEN
                changed = True
            elif seat == TAKEN and occupied >= max_occupied:
                new_map[i][j] = FREE
                changed = True
    return new_map, changed


def solve(seat_map, count_f, n):
    changed = True
    while changed:
        seat_map, changed = crowding_pass(seat_map, count_f, n)
    return sum(row.count(TAKEN) for row in seat_map)


@aoc_timer(1, 11, 2020)
def solve_first(seat_map):
    return solve(seat_map, count_adjacent, 4)


@aoc_timer(2, 11, 2020)
def solve_second(seat_map):
    return solve(seat_map, count_seen, 5)


if __name__ == '__main__':
    seat_map = parse_input(get_input(11, year=2020))
    solve_first(seat_map)
    solve_second(seat_map)
コード例 #2
0
def parse_input(input_str):
    return list(map(parse_policy, input_str.splitlines()))


def valid_count(policy):
    count_low, count_high, letter, password = policy
    return int(count_low) <= password.count(letter) <= int(count_high)


@aoc_timer(1, 2, 2020)
def solve_first(policies):
    return sum(map(valid_count, policies))


def valid_position(policy):
    pos1, pos2, letter, password = policy
    char1 = password[int(pos1) - 1]
    char2 = password[int(pos2) - 1]
    return [char1, char2].count(letter) == 1


@aoc_timer(2, 2, 2020)
def solve_second(policies):
    return sum(map(valid_position, policies))


if __name__ == '__main__':
    policies = parse_input(get_input(2, year=2020))
    solve_first(policies)
    solve_second(policies)
コード例 #3
0
ファイル: d17_life.py プロジェクト: dncnwtts/adventofcode-1
    zeroes = [0] * (N - 2)
    pocket = set((x, y, *zeroes)
                 for x, y in product(range(pocket_length), repeat=2)
                 if initial_state[x][y] == '#')
    for _ in range(6):
        counter = Counter(neighbour for coords in pocket
                          for neighbour in neighbour_set(coords))
        pocket = set(coords for coords, active in counter.items()
                     if (active == 2 and coords in pocket) or active == 3)
    return len(pocket)


@aoc_timer(1, 17, 2020)
def solve_first(initial_state):
    return solve(initial_state, 3)


@aoc_timer(2, 17, 2020)
def solve_second(initial_state):
    return solve(initial_state, 4)


def parse_input(input_str):
    return input_str.splitlines()


if __name__ == '__main__':
    initial_state = parse_input(get_input(17, year=2020))
    solve_first(initial_state)
    solve_second(initial_state)
コード例 #4
0
@aoc_timer(2, 16, 2020)
def solve_second(args):
    rules, my_ticket, nearby = args
    nearby = [t for t in nearby if valid_ticket(rules, t)]
    transposed = list(zip(*nearby))
    header_sets = [set() for _ in range(len(transposed))]
    for header, in_range in rules:
        for col, values in enumerate(transposed):
            if all(map(in_range, values)):
                header_sets[col].add(header)
    header_mapping = {}
    while len(header_mapping) != len(transposed):
        for col, headers in enumerate(header_sets):
            if len(headers) != 1:
                continue
            header = headers.pop()
            for h in header_sets:
                h.discard(header)
            header_mapping[col] = header
    result = 1
    for col, header in header_mapping.items():
        if header.startswith('departure'):
            result *= my_ticket[col]
    return result


if __name__ == '__main__':
    args = parse_input(get_input(16, year=2020))
    solve_first(args)
    solve_second(args)
コード例 #5
0
ファイル: d05_binary.py プロジェクト: dncnwtts/adventofcode-1
def calculate_id(bitstring):
    row = int(bitstring[:7], 2)
    col = int(bitstring[7:], 2)
    return row * 8 + col


def parse_input(input_str):
    char_table = str.maketrans('FBLR', '0101')
    bitstrings = input_str.translate(char_table).splitlines()
    return list(map(calculate_id, bitstrings))


@aoc_timer(1, 5, 2020)
def solve_first(boarding_ids):
    return max(boarding_ids)


@aoc_timer(2, 5, 2020)
def solve_second(boarding_ids):
    id_set = set(boarding_ids)
    for boarding_id in count(min(boarding_ids)):
        if boarding_id not in id_set:
            return boarding_id


if __name__ == '__main__':
    boarding_passes = parse_input(get_input(5, year=2020))
    solve_first(boarding_passes)
    solve_second(boarding_passes)
コード例 #6
0
RULES = {
    "byr": lambda x: 1920 <= int(x) <= 2002,
    "iyr": lambda x: 2010 <= int(x) <= 2020,
    "eyr": lambda x: 2020 <= int(x) <= 2030,
    "hgt": validate_hgt,
    "hcl": lambda x: re.match("^#[0-9a-f]{6}$", x), 
    "ecl": lambda x: x in {"amb", "blu", "brn", "gry", "grn", "hzl", "oth"},
    "pid": lambda x: re.match("^[0-9]{9}$", x)
}


def validate(passport):
    for key, valid in RULES.items():
        if key not in passport:
            return False
        if not valid(passport[key]):
            return False
    return True


@aoc_timer(1, 4, 2020)
def solve_second(passports):
    return len(list(filter(validate, passports)))


if __name__ == '__main__':
    passports = parse_input(get_input(4, year=2020))
    solve_first(passports)
    solve_second(passports)
コード例 #7
0
ファイル: d15_memory.py プロジェクト: dncnwtts/adventofcode-1
def parse_input(input_str):
    return list(map(int, input_str.split(',')))


def solve(numbers, N):
    mem = {n: i for i, n in enumerate(numbers[:-1], 1)}
    mem = defaultdict(bool, mem)
    last = numbers[-1]
    for turn in range(len(numbers), N):
        current = mem[last]
        current = turn - current if current else 0
        mem[last] = turn
        last = current
    return current


@aoc_timer(1, 15, 2020)
def solve_first(numbers):
    return solve(numbers, 2020)


@aoc_timer(2, 15, 2020)
def solve_second(numbers):
    return solve(numbers, 30000000)


if __name__ == '__main__':
    numbers = parse_input(get_input(15, year=2020))
    solve_first(numbers)
    solve_second(numbers)
コード例 #8
0
    for i, coded_int in enumerate(encrypted_ints[25:]):
        preamble = encrypted_ints[i:i + 25]
        for x, y in combinations(preamble, 2):
            if x + y == coded_int:
                break
        else:
            return coded_int, i


@aoc_timer(1, 9, 2020)
def solve_first(encrypted_data):
    return find_error(encrypted_data)[0]


@aoc_timer(2, 9, 2020)
def solve_second(encrypted_ints):
    target_int, limit = find_error(encrypted_ints)
    for i, _ in enumerate(encrypted_ints[:limit]):
        sum_iterator = accumulate(encrypted_ints[i:])
        for j, running_sum in enumerate(sum_iterator):
            if running_sum == target_int:
                return i + encrypted_ints[i + j]
            if running_sum > target_int:
                break


if __name__ == '__main__':
    encrypted_ints = parse_input(get_input(9, year=2020))
    solve_first(encrypted_ints)
    solve_second(encrypted_ints)
コード例 #9
0
ファイル: d03_modulo.py プロジェクト: dncnwtts/adventofcode-1
def parse_input(input_str):
    return input_str.splitlines()


def count_trees(forest, right, down):
    rows, cols = len(forest), len(forest[0])
    trees = 0
    for row in range(down, rows, down):
        column = int((row / down) * right % cols)
        if forest[row][column] == '#':
            trees += 1
    return trees


@aoc_timer(1, 3, 2020)
def solve_first(forest):
    return count_trees(forest, 3, 1)


@aoc_timer(2, 3, 2020)
def solve_second(forest):
    count = partial(count_trees, forest)
    return count(1, 1) * count(3, 1) * count(5, 1) * count(7, 1) * count(1, 2)


if __name__ == '__main__':
    forest = parse_input(get_input(3, year=2020))
    solve_first(forest)
    solve_second(forest)
コード例 #10
0
@aoc_timer(2, 21, 2020)
def solve_second(args):
    can_contain, _ = args
    allergic = {}
    while len(allergic) != len(can_contain):
        for allergen, ingredients in can_contain.items():
            diff = ingredients - set(allergic)
            if len(diff) == 1:
                allergic[diff.pop()] = allergen
    return ",".join(sorted(allergic, key=lambda ing: allergic[ing]))


def parse_line(line, can_contain=dict(), counts=Counter()):
    ingredients, allergens = line.split(' (contains ')
    ingredients = set(ingredients.split())
    counts += Counter(ingredients)
    for allergen in allergens.rstrip(')').split(', '):
        checked = can_contain.get(allergen, ingredients)
        can_contain[allergen] = checked & ingredients
    return can_contain, counts


def parse_input(input_str):
    return list(map(parse_line, input_str.splitlines())).pop()


if __name__ == '__main__':
    args = parse_input(get_input(21, year=2020))
    solve_first(args)
    solve_second(args)
コード例 #11
0
ファイル: d06_sets.py プロジェクト: dncnwtts/adventofcode-1
def parse_input(input_str):
    groups = input_str.split('\n\n')
    groups = map(str.split, groups)
    return [list(map(set, g)) for g in groups]


def count_uniques(answer_sets):
    unique_answers = set.union(*answer_sets)
    return len(unique_answers)


def count_same(answer_sets):
    same_answers = set.intersection(*answer_sets)
    return len(same_answers)


@aoc_timer(1, 6, 2020)
def solve_first(groups):
    return sum(map(count_uniques, groups))


@aoc_timer(2, 6, 2020)
def solve_second(groups):
    return sum(map(count_same, groups))


if __name__ == '__main__':
    answers = parse_input(get_input(6, year=2020))
    solve_first(answers)
    solve_second(answers)
コード例 #12
0
ファイル: d01.py プロジェクト: dncnwtts/adventofcode-1
def parse_input(input_str):
    return list(map(int, input_str.splitlines()))


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


def rocket_fuel(to_lift):
    total = delta = fuel(to_lift)
    while delta := fuel(delta) > 0:
        total += delta
    return total


@aoc_timer(1, 1, 2019)
def solve_first(masses):
    return sum(map(fuel, masses))


@aoc_timer(2, 1, 2019)
def solve_second(masses):
    return sum(map(rocket_fuel, masses))


if __name__ == '__main__':
    masses = parse_input(get_input(1, year=2019))
    solve_first(masses)
    solve_second(masses)

コード例 #13
0
from operator import sub

from adventofcode.inputs import get_input
from adventofcode.utils import aoc_timer


def parse_input(input_str):
    jolts = list(map(int, input_str.splitlines()))
    jolts.extend([0, max(jolts) + 3])
    return sorted(jolts)


@aoc_timer(1, 10, 2020)
def solve_first(jolts):
    counter = Counter(starmap(sub, zip(jolts[1:], jolts)))
    return counter[1] * counter[3]


@aoc_timer(2, 10, 2020)
def solve_second(jolts):
    cache = defaultdict(int, {0: 1})
    for j in jolts[1:]:
        cache[j] = sum(cache[i] for i in range(j - 3, j))
    return cache[jolts[-1]]


if __name__ == '__main__':
    jolts_lst = parse_input(get_input(10, year=2020))
    solve_first(jolts_lst)
    solve_second(jolts_lst)
コード例 #14
0
                addr_template += "1"
            else:
                addr_template += "{}"
        floating_length = mask.count('X')
        for f in range(2**floating_length):
            addr = addr_template.format(*bitstring(f, floating_length))
            addr = int(addr, 2)
            mem[addr] = int(val)
    return sum(mem.values())


def bitstring(x, l):
    return bin(x)[2:].zfill(l)


def parse(line):
    arg, val = line.split(' = ')
    if arg == 'mask':
        return arg, val
    else:
        return int(arg[4:-1]), val


def parse_input(input_str):
    return list(map(parse, input_str.splitlines()))


if __name__ == '__main__':
    code = parse_input(get_input(14, year=2020))
    solve_first(code)
    solve_second(code)
コード例 #15
0
        elif instr == FORWARD:
            x, y = move(x, y, arg, facing)
        else:
            x, y = move(x, y, arg, instr)
    return abs(x) + abs(y)


@aoc_timer(2, 12, 2020)
def solve_second(nav_list):
    sx, sy = 0, 0
    wx, wy = 10, 1
    for instr, arg in nav_list:
        if (instr, arg) in {(LEFT, 90), (RIGHT, 270)}:
            wx, wy = -wy, wx
        elif (instr, arg) in {(LEFT, 180), (RIGHT, 180)}:
            wx, wy = -wx, -wy
        elif (instr, arg) in {(LEFT, 270), (RIGHT, 90)}:
            wx, wy = wy, -wx
        elif instr == FORWARD:
            sx += wx * arg
            sy += wy * arg
        else:
            wx, wy = move(wx, wy, arg, instr)
    return abs(sx) + abs(sy)


if __name__ == '__main__':
    nav_list = parse_input(get_input(12, year=2020))
    solve_first(nav_list)
    solve_second(nav_list)
コード例 #16
0

def evaluate(tokens, inner_eval, brackets_regex=re.compile(r'(\([^()]+\))')):
    inside_brackets = brackets_regex.search(tokens)
    if not inside_brackets:
        return inner_eval(tokens)
    inside_brackets = inside_brackets.group(1)
    brackets_result = inner_eval(inside_brackets.strip('()'))
    new_tokens = tokens.replace(inside_brackets, str(brackets_result))
    return evaluate(new_tokens, inner_eval)


@aoc_timer(1, 18, 2020)
def solve_first(lines):
    return sum(evaluate(line, equal_precedence) for line in lines)


@aoc_timer(2, 18, 2020)
def solve_second(lines):
    return sum(evaluate(line, add_before) for line in lines)


def parse_input(input_str):
    return input_str.splitlines()


if __name__ == '__main__':
    lines = parse_input(get_input(18, year=2020))
    solve_first(lines)
    solve_second(lines)
コード例 #17
0
from itertools import combinations, dropwhile

from adventofcode.inputs import get_input
from adventofcode.utils import aoc_timer


def parse_input(input_str):
    return list(map(int, input_str.split()))


def solve(expenses, n):
    constraint = lambda x: sum(x) != 2020
    accepted_values = next(dropwhile(constraint, combinations(expenses, n)))
    return math.prod(accepted_values)


@aoc_timer(1, 1, 2020)
def solve_first(expenses):
    return solve(expenses, 2)


@aoc_timer(2, 1, 2020)
def solve_second(expenses):
    return solve(expenses, 3)


if __name__ == '__main__':
    expenses = parse_input(get_input(1, year=2020))
    solve_first(expenses)
    solve_second(expenses)
コード例 #18
0
ファイル: d14_fuel.py プロジェクト: dncnwtts/adventofcode-1
    # [0] is fuel amount, but puzzle input is always 1
    reactants = reactions["FUEL"][1]
    total_ore = 0
    for chem, n_current in reactants.items():
        total_ore += sum(ore_needed(reactions, chem, n_fuel * n_current))
    return total_ore


@aoc_timer(1, 14, 2019)
def solve_first(reactor_equations):
    return get_fuel(reactor_equations, 1)


@aoc_timer(2, 14, 2019)
def solve_second(reactor_equations):
    trillion = 1000000000000
    high, low = trillion, 0
    while high - low > 1:
        fuel = (high + low) // 2
        if get_fuel(reactor_equations, fuel) > trillion:
            high = fuel
        else:
            low = fuel
    return low


if __name__ == "__main__":
    reactor_equations = parse_input(get_input(14, year=2019))
    solve_first(reactor_equations)
    solve_second(reactor_equations)
コード例 #19
0
    for color, constraints in rules.items():
        if color in in_the_bag:
            continue
        if target in constraints:
            in_the_bag.add(color)
            search(color, rules)
    return len(in_the_bag)


@aoc_timer(1, 7, 2020)
def solve_first(rules_dct):
    return search('shiny gold', rules_dct)


@aoc_timer(2, 7, 2020)
def solve_second(rules_dct):
    final_count = 0
    bags_to_check = ['shiny gold']
    while bags_to_check:
        to_check = bags_to_check.pop()
        for color, count in rules_dct[to_check].items():
            final_count += count
            bags_to_check.extend([color] * count)
    return final_count


if __name__ == '__main__':
    rules = parse_input(get_input(7, year=2020))
    solve_first(rules)
    solve_second(rules)