コード例 #1
0
        visited.append(pointer)

        [(op, args)] = instruction[pointer].items()
        step = int(args)

        if pointer == i:
            op = 'nop' if op == 'jmp' else 'jmp'

        if op == 'acc':
            accumulator += step
            pointer += 1
        elif op == 'jmp':
            pointer += step
        elif op == 'nop':
            pointer += 1
    return visited, pointer, accumulator


boot_code = load_day(8)
parse_data(boot_code)
# part a
visited, _, accumulator = terminate()
print(accumulator)
# part b
for i in visited:
    [(op, args)] = instruction[i].items()
    if op in ('nop', 'jmp'):
        _, j, accumulator = terminate(i)
        if j >= len(instruction):
            print(accumulator)
            break
コード例 #2
0
# Source: https://github.com/sijmn/aoc2020/blob/master/python/day14.py
from data import load_day

data = load_day(14)
mem = {}
for line in data:
    l, r = line.split(' = ')
    if l == 'mask':
        and_mask = int(r.replace('X', '1'), base=2)
        or_mask = int(r.replace('X', '0'), base=2)
    else:
        value = int(r)
        value &= and_mask  # each bit of output is 1 if x AND y is 1, otherwise it's 0
        value |= or_mask  # each bit of output is 0 if x AND y is 0, otheriwse it's 1
        mem[int(l[4:-1])] = value

print(sum(mem.values()))
コード例 #3
0
ファイル: day_03.py プロジェクト: alanaalfeche/advent-of-code
from data import load_day


def count_trees(lines, rise, run):
    line_size = len(lines[0])
    x, tree_count = 0, 0
    for line in lines[::rise]:
        tree_count += line[x] == '#'
        x = (x + run) % line_size
    return tree_count


lines = load_day(3)
# part a
print(count_trees(lines, 1, 3))  # 276
# part b
print(count_trees(lines, 1, 1) * \
      count_trees(lines, 1, 3) * \
      count_trees(lines, 1, 5) * \
      count_trees(lines, 1, 7) * \
      count_trees(lines, 2, 1))
コード例 #4
0
        _letter = letter[0]
        res.append(Password(int(_min), int(_max), _letter, password))
    return res


def password_range_policy_validator(content):
    count = 0
    for ele in content:
        freq = ele.password.count(ele.letter)
        if ele.min <= freq <= ele.max: count += 1
    print(count)


def password_position_policy_validator(content):
    count = 0
    for ele in content:
        try:
            # ^ XOR operator sets bit to 1 if one of two bits is 1
            if (ele.password[ele.min-1] == ele.letter) ^ \
               (ele.password[ele.max-1] == ele.letter):
                count += 1
        except IndexError:
            continue
    print(count)


lines = load_day(2)
content = parse(lines)
password_range_policy_validator(content)
password_position_policy_validator(content)
コード例 #5
0
ファイル: day_13.py プロジェクト: alanaalfeche/advent-of-code
def calculate_min_wait_time(ts, buses):
    wait_times = [bus - ts % bus for bus in buses]
    bus_index = wait_times.index(min(wait_times))
    return buses[bus_index] * min(wait_times)


def calculate_subsequent_departures(buses):
    ''' We need to find a number such that it's divisible by the first bus, then second bus + index, and so on.
    Take 7, 13, x, x, 59... for an example. At 77, 77 % 7 = 0, and 78 % 13 = 0.
    So, the n is where n % 7 = 0, (n + 1) % 13 = 0, and (n + 4) % 59 = 0.

    Note that all bus IDs are prime numbers so we can just iterate with the LCM until it meets our codition.
    The maximum solution is the product of all numbers. 
    '''
    time, step = 0, 1

    for delta, bus in buses.items():
        while (
                time + delta
        ) % bus:  # if not divisible, enter while loop; if divisible, we found the LCM, exit while loop
            time += step  # add step until time + delta is divisible by bus ID
        step *= bus  # lcm of previous numbers is added to step to ensure that the next number will be divisible by previous AND current
    return time


data = load_day(13)
ts = int(data[0])
buses = {i: int(bus) for i, bus in enumerate(data[1].split(',')) if bus != 'x'}

print(calculate_min_wait_time(ts, list(buses.values())))
print(calculate_subsequent_departures(buses))
コード例 #6
0
ファイル: day_16.py プロジェクト: alanaalfeche/advent-of-code
import re

from data import load_day

data = load_day(16)
partition = [i for i, ele in enumerate(data)
             if len(ele) == 0]  # entities is separated by empty string

rules = data[:partition[0]]
my_ticket = data[partition[0] + 2:partition[1]]
nearby_tickets = data[partition[1] + 2:]
# print(rules, my_ticket, nearby_tickets)

invalid = []
for ticket in nearby_tickets:
    tickets = [int(t) for t in ticket.split(',')]

    for ticket in tickets:
        result = []
        for rule in rules:
            rule = re.match(r'(.*): (.*)', rule).groups()[1].split()
            rule_1 = rule[0].split('-')
            rule_2 = rule[2].split('-')

            if int(rule_1[0]) <= ticket <= int(rule_1[1]) or \
                int(rule_2[0]) <= ticket <= int(rule_2[1]):
                result.append(True)
            else:
                result.append(False)

        if not any(result):
コード例 #7
0
ファイル: day_18.py プロジェクト: alanaalfeche/advent-of-code
def calculate(postfix_exp):
    result = []
    for token in postfix_exp:
        if token.isnumeric():
            result.append(token)
        else:
            a = int(result.pop())
            b = int(result.pop())
            c = a * b if token == '*' else a + b
            result.append(c)

    return result.pop()


data = load_day(18)
results_1, results_2 = [], []
for infix_exp in data:
    tokenized_infix_exp = tokenize(infix_exp)
    # part 1 - addition and multiplication have the same presedence
    precedence_1 = {'(': 0, '*': 1, '+': 1}
    postfix_exp_1 = convert_to_postfix(tokenized_infix_exp,
                                       precedence=precedence_1)
    results_1.append(calculate(postfix_exp_1))
    # part 2 - addition is evaluated before multiplication
    precedence_2 = {'(': 0, '*': 1, '+': 2}
    postfix_exp_2 = convert_to_postfix(tokenized_infix_exp,
                                       precedence=precedence_2)
    results_2.append(calculate(postfix_exp_2))

print(sum(results_1))
コード例 #8
0
    invalid = None

    for i in data[preamble_length:]:
        seen = set()
        for j in preamble:
            if i - j in seen:
                preamble.popleft()
                preamble.append(i)
                break
            seen.add(j)
        else:
            invalid = i
            break

    return invalid


data = [int(x) for x in load_day(9)]
# part a
invalid = find_invalid_number(data, preamble_length=5)
print(invalid)
# part b
l = r = total = 0
while total != invalid:
    while total < invalid:
        total += data[r]
        r += 1
    while total > invalid:
        total -= data[l]
        l += 1
print(min(data[l:r]) + max(data[l:r]))
コード例 #9
0
        for col in range(col_size):
            adjacents = get_adjacents(grid, row, col, row_size, col_size)

            if grid[row][col] == "L" and "#" not in adjacents:
                new_row += "#"
            elif grid[row][col] == "#" and adjacents.count("#") >= 4:
                new_row += "L"
            else:
                new_row += grid[row][col]

        new_grid.append(new_row)
    return new_grid


seating = load_day(11)
default_grid = []
for i in seating:
    row = []
    for char in i:
        row.append(char)
    default_grid.append(row)
row_size = len(default_grid)
col_size = len(default_grid[0])

# part a
process = True
while process:
    occupied_grid = get_occupied_seats(default_grid, row_size, col_size)

    if occupied_grid == default_grid:
コード例 #10
0
ファイル: day_15.py プロジェクト: alanaalfeche/advent-of-code
from data import load_day


def memory_game(seen, last, limit):
    for i in range(len(seen), limit):
        # tmp = last
        # last = i - seen.get(last, i)
        # seen[tmp] = i
        seen[last], last = i, i - seen.get(last, i)
    return last


data = load_day(15)
data = [int(ele) for ele in data[0].split(',')]
last = data[-1]
seen = {num: turn + 1 for turn, num in enumerate(data)}
# part one
print(memory_game(seen.copy(), last, 2020))
# part two -- takes 12 seconds
print(memory_game(seen.copy(), last, 30000000))
コード例 #11
0
ファイル: day_10.py プロジェクト: alanaalfeche/advent-of-code
    for i in range(len(data) - 1):
        diff = data[i + 1] - data[i]
        if diff <= 3:
            rating[diff] += 1

    return rating[1] * (
        rating[3] + 1
    )  # built-in adapter is always 3 higher than the highest adapter


def get_total_paths(data):
    paths = defaultdict(int)
    paths[0] = 1

    for adapter in sorted(data):
        for diff in range(1, 4):
            next = adapter + diff
            if next in data:
                paths[next] += paths[adapter]

    x = max(paths, key=int)
    return paths[x]


data = load_day(10)
data = [int(x) for x in data]
# part a
print(multiply_jolt_differences(data))
# part b
print(get_total_paths(data))
コード例 #12
0
bags = defaultdict(dict)
def parse_data(luggage_rules):
    for rule in luggage_rules:
        outside_bag = re.match(r'(.*) bags contain', rule).groups()[0]
        for count, inside_bag in re.findall(r'(\d+) (\w+ \w+) bags?', rule):
            bags[outside_bag][inside_bag] = int(count)
    return bags

answer = set()
def search(color):
    for bag in bags:
        if color in bags[bag]:
            answer.add(bag)
            search(bag)
    return len(answer)

def count(color):
    total = 1
    for bag in bags[color]:
        multiplier = bags[color][bag]
        total += multiplier * count(bag)
    return total

luggage_rules = load_day(7)
parse_data(luggage_rules)
bag = 'shiny gold'
# part a
print(search(bag))
# part b
print(count(bag)-1)
コード例 #13
0
ファイル: day_05.py プロジェクト: alanaalfeche/advent-of-code
    return min(_min, _max) if df == min_char else max(_min, _max)


def get_seat_ids(boarding_passes):
    seat_ids = []
    for bp in boarding_passes:
        rows = bp[:6]
        deciding_factor = bp[6]
        cols = bp[7:]

        row = seat_id_calculator(rows, 0, 127, 'F', 'B', deciding_factor)
        col = seat_id_calculator(cols, 0, 7, 'L', 'R', deciding_factor)

        unique_seat_id = row * 8 + col
        seat_ids.append(unique_seat_id)
    return seat_ids


def find_my_seat(seat_ids):
    return [
        seat for seat in range(min(seat_ids), max(seat_ids))
        if seat not in seat_ids
    ][0]


boarding_passes = load_day(5)
seat_ids = get_seat_ids(boarding_passes)
# part a
print(max(seat_ids))
# part b
print(find_my_seat(seat_ids))
コード例 #14
0
    return list(map(int, lines))

def multiply_two_sum(target, nums):
    difference = {}
    for num in nums:
        if num in difference:
            print(num * difference[num])
        else:
            difference[target-num] = num

def multiply_three_sum(target, nums):
    nums.sort()
    for i in range(len(nums)):
        l, r = i + 1, len(nums)-1
        while l < r:
            _sum = nums[i] + nums[l] + nums[r]
            if _sum == target:
                print(nums[i] * nums[l] * nums[r])
                break

            if _sum > target:
                r -= 1
            elif _sum < target:
                l += 1

lines = load_day(1)
content = parse(lines)

param={'target': 2020, 'nums': content}
multiply_two_sum(**param)
multiply_three_sum(**param)
コード例 #15
0
        one_passport.append(line)

    return passports_with_all_required_fields


def count_valid_passports(fields, passports):
    no_of_valid_passport = 0
    for passport in passports:
        fields = passport.split(' ')
        parsed_fields = dict(field.split(':') for field in fields)
        no_of_valid_passport += all(
            v(parsed_fields[k]) for k, v in required_passport_fields.items())
    return no_of_valid_passport


passports = load_day(4)
required_passport_fields = {
    'byr':
    lambda x: 1920 <= int(x) <= 2002,
    'iyr':
    lambda x: 2010 <= int(x) <= 2020,
    'eyr':
    lambda x: 2020 <= int(x) <= 2030,
    'hgt':
    lambda x: (x.endswith('cm') and 150 <= int(x[:-2]) <= 193) or
    (x.endswith('in') and 59 <= int(x[:-2]) <= 76),
    'hcl':
    lambda x: re.match('^#[0-9a-f]{6}$', x),
    'ecl':
    lambda x: x in ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth'],
    'pid':