コード例 #1
0
ファイル: day04.py プロジェクト: nerdzila/belated-advent
# -*- coding: utf-8 -*-
import hashlib
from advent_tools import print_answer

ENCODING = 'utf-8'


def hash_key_and_number(key, number):
    m = hashlib.md5()
    m.update(key.encode(ENCODING))
    m.update(str(number).encode(ENCODING))
    return m.hexdigest()


def find_hash_seed(prefix, key):
    current_number = 0

    while True:
        current_number += 1
        current_hash = hash_key_and_number(puzzle_input, current_number)
        if current_hash.startswith(prefix):
            return current_number

puzzle_input = input('Puzzle key: ')


print_answer(1, find_hash_seed('00000', puzzle_input))
print_answer(2, find_hash_seed('000000', puzzle_input))
コード例 #2
0
# -*- coding: utf-8 -*-
from itertools import combinations
from functools import reduce
from operator import mul
from advent_tools import get_input_lines, print_answer

total_area, ribbon_length = (0, 0)
for line in get_input_lines():
    dimensions = list(map(int, line.strip().split('x')))
    rectangle_sides = list(combinations(dimensions, 2))
    rectangle_areas = [x * y for x, y in rectangle_sides]
    slack = min(rectangle_areas)

    total_area += sum(2 * area for area in rectangle_areas)
    total_area += slack

    perimeters = [2 * x + 2 * y for x, y in rectangle_sides]
    ribbon_length += min(perimeters)
    ribbon_length += reduce(mul, dimensions)

print_answer(1, total_area)
print_answer(2, ribbon_length)
コード例 #3
0
ファイル: day12.py プロジェクト: nerdzila/belated-advent
# -*- coding: utf-8 -*-
import re
import json
from advent_tools import get_input_string, print_answer

NUMBERS = re.compile('-?\d+')
input_string = get_input_string()

print_answer(1, sum(map(int, NUMBERS.findall(input_string))))

root = json.loads(input_string)


def explore(node, total):
    if isinstance(node, int):
        return total + node

    if isinstance(node, dict):
        if 'red' in node.values():
            return total

        acum = 0
        for n in node.values():
            acum += explore(n, 0)

        return total + acum

    if isinstance(node, list):
        acum = 0
        for n in node:
            acum += explore(n, 0)
コード例 #4
0
ファイル: day08.py プロジェクト: nerdzila/belated-advent
# -*- coding: utf-8 -*-
import re
from advent_tools import get_input_lines, print_answer

decode_pattern = re.compile(r'(\\\\)|(\\\")|(\\x[0-9a-f]{2})')
encoding_subs = [
    (re.compile(r'\\'), r'\\\\'),
    (re.compile(r'\"'), r'\\"')
]

total_code_chars = 0
total_memory_size = 0
total_encoded_size = 0

for line in get_input_lines():
    meaty_part = line[1:-1]
    mem_length = len(decode_pattern.sub('?', meaty_part))
    total_code_chars += len(line)
    total_memory_size += mem_length

    encoded_line = line
    for pattern, sub in encoding_subs:
        encoded_line = pattern.sub(sub, encoded_line)

    encoded_line = '"{}"'.format(encoded_line)
    total_encoded_size += len(encoded_line)


print_answer(1, total_code_chars - total_memory_size)
print_answer(2, total_encoded_size - total_code_chars)
コード例 #5
0
ファイル: day07.py プロジェクト: nerdzila/belated-advent
results = {}


def solve(key):
    input_ = inputs[key]

    args = []
    for source in input_.sources:
        if isinstance(source, int):
            args.append(source)
        else:
            if source not in results:
                solve(source)
            args.append(results[source])

    if input_.operator is None:
        results[key] = args[0]
    else:
        results[key] = input_.operator(*args)

solve('a')
first_answer = c_uint16(results['a']).value
print_answer(1, first_answer)

inputs['b'] = Input(sources=[first_answer], operator=None)
results = {}
solve('a')
second_answer = c_uint16(results['a']).value

print_answer(2, second_answer)
コード例 #6
0
ファイル: day04.py プロジェクト: nerdzila/belated-advent
# -*- coding: utf-8 -*-
import hashlib
from advent_tools import print_answer

ENCODING = 'utf-8'


def hash_key_and_number(key, number):
    m = hashlib.md5()
    m.update(key.encode(ENCODING))
    m.update(str(number).encode(ENCODING))
    return m.hexdigest()


def find_hash_seed(prefix, key):
    current_number = 0

    while True:
        current_number += 1
        current_hash = hash_key_and_number(puzzle_input, current_number)
        if current_hash.startswith(prefix):
            return current_number


puzzle_input = input('Puzzle key: ')

print_answer(1, find_hash_seed('00000', puzzle_input))
print_answer(2, find_hash_seed('000000', puzzle_input))
コード例 #7
0
ファイル: day10.py プロジェクト: nerdzila/belated-advent
# -*- coding: utf-8 -*-
from advent_tools import print_answer

puzzle_input = input('Puzzle input: ')


def transform(line):
    line += '*'
    last_cut = 0
    sequences = []
    for offset, left, right in zip(range(1, len(line)), line[:-1], line[1:]):
        if left != right:
            sequences.append(line[last_cut:offset])
            last_cut = offset

    result = ''
    for seq in sequences:
        result += str(len(seq))
        result += seq[0]
    return result

for _ in range(40):
    puzzle_input = transform(puzzle_input)

print_answer(1, len(puzzle_input))

for _ in range(10):
    puzzle_input = transform(puzzle_input)

print_answer(2, len(puzzle_input))
コード例 #8
0
ファイル: day01.py プロジェクト: nerdzila/belated-advent
from advent_tools import get_input_string, print_answer


def direction(instruction):
    if instruction == '(':
        return 1

    if instruction == ')':
        return -1

    raise ValueError('Instruction has to be either "(" or ")"')


input_string = get_input_string()

first_answer = input_string.count('(') - input_string.count(')')

print_answer(1, first_answer)

current_floor = 0

for idx, instruction in enumerate(input_string):
    current_floor += direction(instruction)

    if current_floor < 0:
        print_answer(2, idx + 1)
        break

if current_floor >= 0:
    print('Second answer: Negative floor was never reached')
コード例 #9
0
distances = dict()
places = set()
for line in get_input_lines():
    left, _, right, _, distance = line.split()
    distance = int(distance)

    places.add(left)
    places.add(right)
    distances[frozenset((left, right))] = distance

shortest_length = inf
shortest_route = None
biggest_length = 0
longest_route = None

for route in permutations(places):
    route_length = 0
    trips = zip(route[:-1], route[1:])
    route_length = sum(distances[frozenset(t)] for t in trips)
    if route_length < shortest_length:
        shortest_length = route_length
        shortest_route = route

    if route_length > biggest_length:
        biggest_length = route_length
        longest_route = route

print_answer(1, shortest_length)

print_answer(2, biggest_length)
コード例 #10
0
ファイル: day05.py プロジェクト: nerdzila/belated-advent
        previous_pair = self.second_to_last + self.last
        if len(previous_pair) == 2:
            self.seen_pairs.add(previous_pair)

        self.second_to_last = self.last
        self.last = char

    def is_nice(self):
        return self.has_almost_contiguous_pair and self.repeats_non_overlapping_pairs


def evaluate_words(evaluator, lines):
    nice_ones = 0
    for line in lines.split("\n"):
        ne = evaluator()

        for char in line:
            ne.read(char)

        if ne.is_nice():
            nice_ones += 1

    return nice_ones


input_string = get_input_string()


print_answer(1, evaluate_words(FirstNicenessEvaluator, input_string))
print_answer(2, evaluate_words(SecondNicenessEvaluator, input_string))
コード例 #11
0
ファイル: day05.py プロジェクト: nerdzila/belated-advent
        previous_pair = self.second_to_last + self.last
        if len(previous_pair) == 2:
            self.seen_pairs.add(previous_pair)

        self.second_to_last = self.last
        self.last = char

    def is_nice(self):
        return (self.has_almost_contiguous_pair
                and self.repeats_non_overlapping_pairs)


def evaluate_words(evaluator, lines):
    nice_ones = 0
    for line in lines.split('\n'):
        ne = evaluator()

        for char in line:
            ne.read(char)

        if ne.is_nice():
            nice_ones += 1

    return nice_ones


input_string = get_input_string()

print_answer(1, evaluate_words(FirstNicenessEvaluator, input_string))
print_answer(2, evaluate_words(SecondNicenessEvaluator, input_string))
コード例 #12
0
ファイル: day13.py プロジェクト: nerdzila/belated-advent
            change += happiness_score[r][l]

        if change > biggest_change:
            biggest_change = change

    return biggest_change


happiness_score = defaultdict(dict)

for line in get_input_lines():
    tokens = line.rstrip('.').split()
    left, _, effect, amount = tokens[:4]
    right = tokens[-1]

    score = int(amount) if effect == 'gain' else -int(amount)

    happiness_score[left][right] = score

guests = list(happiness_score.keys())

print_answer(1, compute_change(guests, happiness_score))

for key in list(happiness_score.keys()):
    happiness_score[key]['nerdzila'] = 0
    happiness_score['nerdzila'][key] = 0

guests.append('nerdzila')

print_answer(2, compute_change(guests, happiness_score))
コード例 #13
0
ファイル: day02.py プロジェクト: nerdzila/belated-advent
# -*- coding: utf-8 -*-
from itertools import combinations
from functools import reduce
from operator import mul
from advent_tools import get_input_lines, print_answer


total_area, ribbon_length = (0, 0)
for line in get_input_lines():
    dimensions = list(map(int, line.strip().split("x")))
    rectangle_sides = list(combinations(dimensions, 2))
    rectangle_areas = [x * y for x, y in rectangle_sides]
    slack = min(rectangle_areas)

    total_area += sum(2 * area for area in rectangle_areas)
    total_area += slack

    perimeters = [2 * x + 2 * y for x, y in rectangle_sides]
    ribbon_length += min(perimeters)
    ribbon_length += reduce(mul, dimensions)

print_answer(1, total_area)
print_answer(2, ribbon_length)
コード例 #14
0
ファイル: day03.py プロジェクト: nerdzila/belated-advent

def move(current_pos, direction):
    shift = shifts[direction]
    return (current_pos[0] + shift[0], current_pos[1] + shift[1])

instructions = get_input_string()

position = (0, 0)
visited = {position}

for direction in instructions:
    position = move(position, direction)
    visited.add(position)

print_answer(1, len(visited))

santa = (0, 0)
robo_santa = (0, 0)

visited = {(0, 0)}

for idx, direction in enumerate(instructions):
    if idx % 2 == 0:
        santa = move(santa, direction)
        visited.add(santa)
    else:
        robo_santa = move(robo_santa, direction)
        visited.add(robo_santa)

print_answer(2, len(visited))
コード例 #15
0

def increment_password(string):
    stop_increments = False
    inverted_result = ''

    for char in string[::-1]:
        if stop_increments:
            inverted_result += char
        else:
            next_codepoint = ord(char) + 1
            if next_codepoint > CODEPOINT_LIMIT:
                inverted_result += chr(CODEPOINT_START)
            else:
                inverted_result += chr(next_codepoint)
                stop_increments = True
    return inverted_result[::-1]


password = input('Password: ')
while not is_valid_password(password):
    password = increment_password(password)

print_answer(1, password)

password = increment_password(password)
while not is_valid_password(password):
    password = increment_password(password)

print_answer(2, password)
コード例 #16
0
# -*- coding: utf-8 -*-
import re
import json
from advent_tools import get_input_string, print_answer

NUMBERS = re.compile('-?\d+')
input_string = get_input_string()

print_answer(1, sum(map(int, NUMBERS.findall(input_string))))

root = json.loads(input_string)


def explore(node, total):
    if isinstance(node, int):
        return total + node

    if isinstance(node, dict):
        if 'red' in node.values():
            return total

        acum = 0
        for n in node.values():
            acum += explore(n, 0)

        return total + acum

    if isinstance(node, list):
        acum = 0
        for n in node:
            acum += explore(n, 0)
コード例 #17
0
ファイル: day10.py プロジェクト: nerdzila/belated-advent
from advent_tools import print_answer

puzzle_input = input('Puzzle input: ')


def transform(line):
    line += '*'
    last_cut = 0
    sequences = []
    for offset, left, right in zip(range(1, len(line)), line[:-1], line[1:]):
        if left != right:
            sequences.append(line[last_cut:offset])
            last_cut = offset

    result = ''
    for seq in sequences:
        result += str(len(seq))
        result += seq[0]
    return result


for _ in range(40):
    puzzle_input = transform(puzzle_input)

print_answer(1, len(puzzle_input))

for _ in range(10):
    puzzle_input = transform(puzzle_input)

print_answer(2, len(puzzle_input))
コード例 #18
0
ファイル: day06.py プロジェクト: nerdzila/belated-advent
        return range(self.x_start, self.x_end + 1)

    def y_range(self):
        return range(self.y_start, self.y_end + 1)


class UpdatedInstruction(Instruction):
    CALLBACKS = {
        'turn on': (lambda x: x + 1),
        'turn off': (lambda x: 0 if x - 1 < 0 else x - 1),
        'toggle': (lambda x: x + 2)
    }


g1 = BinaryGrid(1000, 1000, 0)
g2 = BinaryGrid(1000, 1000, 0)


for line in get_input_lines():
    print(line)
    first = Instruction(line)
    second = UpdatedInstruction(line)

    for x in first.x_range():
        for y in second.y_range():
            g1.update(x, y, first.command)
            g2.update(x, y, second.command)

print_answer(1, sum(g1.grid))
print_answer(2, sum(g2.grid))
コード例 #19
0
# -*- coding: utf-8 -*-
import re
from advent_tools import get_input_lines, print_answer

decode_pattern = re.compile(r'(\\\\)|(\\\")|(\\x[0-9a-f]{2})')
encoding_subs = [(re.compile(r'\\'), r'\\\\'), (re.compile(r'\"'), r'\\"')]

total_code_chars = 0
total_memory_size = 0
total_encoded_size = 0

for line in get_input_lines():
    meaty_part = line[1:-1]
    mem_length = len(decode_pattern.sub('?', meaty_part))
    total_code_chars += len(line)
    total_memory_size += mem_length

    encoded_line = line
    for pattern, sub in encoding_subs:
        encoded_line = pattern.sub(sub, encoded_line)

    encoded_line = '"{}"'.format(encoded_line)
    total_encoded_size += len(encoded_line)

print_answer(1, total_code_chars - total_memory_size)
print_answer(2, total_encoded_size - total_code_chars)