# Vet mooi notebook van Bas Laten we beginnen met de imports ```python import re import numpy as np from functools import reduce from math import factorial ``` ## Puzzel 1 ### Deel 1 ```python 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 ```python 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 ```python data = open('data/puzzle_2.txt', 'r').readlines() ``` ### Deel 1 ```python 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 ```python 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 ```python data = open('data/puzzle_3.txt', 'r').readlines() ``` ```python 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 ```python 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 ```python data = open('data/puzzle_4.txt', 'r').readlines() ``` ```python # 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 ```python # 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 ```python 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 ```python 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