10 KiB
10 KiB
Vet mooi notebook van Bas
Laten we beginnen met de imports
import re
import numpy as np
from functools import reduce
from math import factorial
Puzzel 1
Deel 1
f = open('data/puzzle_1.txt', 'r')
total = 0
for line in f:
digit_1 = re.search('(\d)', line).group()
digit_2 = re.search('(?:\d)(?!.*\d)', line).group()
total += int(digit_1+digit_2)
total
55834
Deel 2
l = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']
digits = '|'+'|'.join(l)
f = open('data/puzzle_1.txt', 'r')
total = 0
for line in f:
string_digits = re.findall('(?=(\d'+digits+'))', line)
string_digits = [digit if (digit not in l) else str(l.index(digit)+1) for digit in string_digits]
total += int(string_digits[0] + string_digits[-1])
total
53221
Puzzel 2
data = open('data/puzzle_2.txt', 'r').readlines()
Deel 1
color_dict = {
'red': 12,
'green': 13,
'blue': 14
}
total = 0
for line in data:
possible = True
for amount, color in re.findall('(\d+)\W*(red|green|blue)', line):
if (color_dict[color] < int(amount)):
possible = False
if possible:
total += int(re.findall('(\d+)', line)[0])
total
3035
Deel 2
total = 0
for line in data:
color_dict = {'red': [], 'green': [], 'blue': []}
for pair in re.findall('(\d+)\W*(red|green|blue)', line):
color_dict[pair[1]].append(int(pair[0]))
total += max(color_dict['red']) * max(color_dict['green']) * max(color_dict['blue'])
total
66027
Puzzel 3
data = open('data/puzzle_3.txt', 'r').readlines()
data_list = [re.sub('\n', '', line) for line in data]
data_list = [re.sub('[^\d\.]', 'X', line) for line in data_list]
total = 0
for line_number, line in enumerate(data_list):
matches = re.findall('\d+', line)
for number in matches:
match = re.search(number, line)
surrounding_string = ""
start, end = match.span()
if start > 0:
start -= 1
if end <= len(line):
end += 1
if line_number != 0:
surrounding_string += data_list[line_number-1][start:end]
surrounding_string += line[start:end]
if line_number != len(data_list)-1:
surrounding_string += data_list[line_number+1][start:end]
if 'X' in surrounding_string:
total += int(match.group())
line = re.sub(match.group(), len(match.group())*'.', line, 1)
match = re.search('\d+', line)
total
517021
data_list = [re.sub('\n', '', line) for line in data]
asterisks = []
numbers = []
for line_number, line in enumerate(data_list):
match = re.search('(\*)|(\d+)', line)
while match is not None:
x, y = match.span()
if match.group() == '*':
asterisks.append({'x_pos': x, 'line_number': line_number})
else:
numbers.append({'x_start':x, 'x_end': y, 'line_number': line_number, 'number': int(match.group())})
line = re.sub('(\*)|(\d+)', len(match.group())*'.', line, 1)
match = re.search('(\*)|(\d+)', line)
for asterisk in asterisks:
asterisk_numbers = []
for number in numbers:
if number['line_number'] == asterisk['line_number']:
if number['x_end'] == asterisk['x_pos']:
asterisk_numbers.append(number['number'])
continue
if number['x_start']-1 == asterisk['x_pos']:
asterisk_numbers.append(number['number'])
continue
if (number['line_number']+1 == asterisk['line_number']) or (number['line_number']-1 == asterisk['line_number']):
if asterisk['x_pos'] in [num for num in range(number['x_start']-1, number['x_end']+1)]:
asterisk_numbers.append(number['number'])
asterisk['numbers'] = asterisk_numbers
total = 0
for asterisk in asterisks:
if len(asterisk['numbers']) == 2:
total+= asterisk['numbers'][0] * asterisk['numbers'][1]
total
81296995
Puzzel 4
Deel 1
data = open('data/puzzle_4.txt', 'r').readlines()
# initiating output variable
total = 0
for line in data:
# Cleaning identifier as it is not necessary
line_number_part = line.split(':')[1]
# Removing the \n
line_number_part = re.sub('\n', '',line_number_part)
# Creating a set with winning numbers and with owned numbers
winning_numbers, owned_numbers = line_number_part.split('|')
# Getting the seperate numbers
winning_numbers = re.findall('(\d+)', winning_numbers)
owned_numbers = re.findall('(\d+)', owned_numbers)
# Converting to a set to prepare for intersect
winning_set = set(winning_numbers)
owned_set = set(owned_numbers)
# Only numbers that are both owned and winning will be left
winning_numbers_owned = winning_set.intersection(owned_set)
# Get the number of matches
matched_number_count = len(winning_numbers_owned)
# If there are no matches, we add nothing to total, so we check for zero matches
if matched_number_count > 0:
# We then add to the total 2 to the power of the total number of matches minus one, as we start at 1 instead of 2 and 2^0 is 1
total += 2**(matched_number_count-1)
print(total)
21568
Deel 2
# initiating output variable
total = 0
winning_numbers_on_card = []
card_numbers = []
copies_of_card = []
for line in data:
# Cleaning identifier
card_identifier_part, line_number_part = line.split(':')
identifier = int(re.search('\d+', card_identifier_part).group())
# adding to the list
card_numbers.append(identifier)
# Also adding a 1 to the owned cards list
copies_of_card.append(1)
# Removing the \n
line_number_part = re.sub('\n', '',line_number_part)
# Creating a set with winning numbers and with owned numbers
winning_numbers, owned_numbers = line_number_part.split('|')
# Getting the seperate numbers
winning_numbers = re.findall('(\d+)', winning_numbers)
owned_numbers = re.findall('(\d+)', owned_numbers)
# Converting to a set to prepare for intersect
winning_set = set(winning_numbers)
owned_set = set(owned_numbers)
# Only numbers that are both owned and winning will be left
winning_numbers_owned = winning_set.intersection(owned_set)
# Get the number of matches
matched_number_count = len(winning_numbers_owned)
# Add to card info list
winning_numbers_on_card.append(matched_number_count)
# Just simulating the rounds, if a card has winining numbers, loop over a range and add that loop variable to the card number
# if the card number exists, we simply add the number of copies of the current card to that card
# etc.
for i, card_id in enumerate(card_numbers):
winning_numbers = winning_numbers_on_card[i]
for number in range(1, winning_numbers+1):
if (card_id+number) in card_numbers:
id_to_add_to = card_numbers.index(card_id+number)
copies_of_card[id_to_add_to] += copies_of_card[i]
# just sum the total cards at the end
print(sum(copies_of_card))
11827296
AANSCHOUW!!!!!
Het wonder, het fantastischste ding ooit, oneliners
reduce(lambda total, multipliers: (total + 2**(multipliers-1) if (multipliers > 0) else total) ,map(lambda numbers: len(numbers)-len(set(numbers)), [re.findall('(?:(\d+)\s|\n)', line) for line in open('data/puzzle_4.txt')]), 0)
21568
sum([y for (x,y) in reduce(lambda total, cards: total + [(cards[0], 1)] + [(card, 1+sum([total_card[1] for total_card in total if total_card[0] == cards[0]])) for card in cards[1]], enumerate([j+1+i for j in range(len(re.findall(r'(?:\b(\d+)\s)(?=.*\s\1\b)', line)))] for i, line in enumerate(open('data/puzzle_4.txt'))), [])])
11827296
Puzzel 5
Deel 1
data = open('data/puzzle_5.txt','r').readlines()
seeds = [int(seed) for seed in re.findall(r'\d+', data[0])]
seed_maps = []
map_names = []
mapping = []
for line in data[1:]:
if 'map' in line:
mapping = []
map_names.append(line)
if line == '\n':
seed_maps.append(mapping)
ints = [int(value) for value in re.findall(r'\b(\d+)', line)]
if len(ints) > 0:
mapping.append(ints)
seed_maps.append(mapping)
for mapping in seed_maps:
if len(mapping) < 1:
continue
new_seeds = []
for map_row in mapping:
for seed in seeds:
if (map_row[1]+map_row[2]) > seed >= map_row[1]:
new_seeds.append(seed+map_row[0]-map_row[1])
seeds = new_seeds
print(seeds)
min(seeds)
[3871578677, 1724133724, 199602917, 2982314302, 595680226, 692431340, 2899305373, 2926286942, 4220409748, 2324727144, 2504054106, 2942258417, 1481150454, 1479468889, 2022824054, 4001340211, 3089202785]
199602917
Deel 2
data = open('data/puzzle_5.txt','r').readlines()
seeds = [{'start': int(x), 'end': int(x) + int(y)} for (x,y) in re.findall(r'(?:(\d+)\s(\d+))', data[0])]
seed_maps = []
map_names = []
mapping = []
for line in data[1:]:
if 'map' in line:
mapping = []
map_names.append(line)
if line == '\n':
if len(mapping) > 0:
seed_maps.append(mapping)
ints = [int(value) for value in re.findall(r'\b(\d+)', line)]
if len(ints) > 0:
mapping.append({'start': ints[1], 'end': ints[1]+ints[2], 'change': ints[0] - ints[1]})
seed_maps.append(mapping)
for seed_map in seed_maps:
new_seeds = []
for seed in seeds:
bounds = [(seed['start'], 0), (seed['end'], 0)]
for row in seed_map:
if (row['start'] >= seed['end']) or (row['end'] <= seed['start']):
continue
if row['start'] <= seed['start']:
bounds.append((seed['start'], row['change']))
else:
bounds.append((row['start'], row['change']))
if row['end'] < seed['end']:
bounds.append((row['end'], 0))
bounds.sort(key=lambda x: x[0])
for i in range(len(bounds)-1):
lower_bound = bounds[i]
upper_bound = bounds[i+1]
if lower_bound[0] != lower_bound[1]:
new_seeds.append({'start': lower_bound[0]+lower_bound[1], 'end': upper_bound[0]+lower_bound[1]})
seeds = new_seeds
min([seed['start'] for seed in seeds])
2254686