diff --git a/aoc_5.py b/aoc_5.py index 5e38441..3a7511b 100644 --- a/aoc_5.py +++ b/aoc_5.py @@ -1,55 +1,41 @@ import aocd -#import numpy as np def parse(puzzle_input): - """Parse input""" - lines = puzzle_input.splitlines() - cards_data = [lines[n:n+5] for n in range(2,len(lines),6)] - return ([int(n) for n in lines[0].split(',')], [[[int(num) for num in row.split()] for row in card_data] for card_data in cards_data]) + return [[tuple([int(c) for c in point.split(',')]) for point in line.split(' -> ')] for line in puzzle_input.splitlines()] + +def omit_diagnal(lines): + return [line for line in lines if line[0][0]==line[1][0] or line[0][1] == line[1][1]] + +def turn_to_grid(lines): + max_point = max([coord for line in lines for point in line for coord in point]) + + grid = [[0 for i in range(max_point+1)] for i in range(max_point+1)] + for (x1,y1),(x2,y2) in lines: + if x1==x2: + highest,lowest = max(y1,y2), min(y1,y2) + for y in range(lowest,highest+1): + grid[y][x1]+=1 + elif y1==y2: + highest,lowest = max(x1,x2), min(x1,x2) + for x in range(lowest,highest+1): + grid[y1][x]+=1 + else: + for i in range(abs(x1-x2)+1): + grid[y1+i if y11) for p in line]) for line in grid]) def part1(data): - called_numbers, cards = data - for called_number in called_numbers: - for h in range(len(cards)): - cards[h], bingo = check_on_card(cards[h],called_number) - if bingo: - return compute_score(cards[h])*called_number + return count_dangerous(turn_to_grid(omit_diagnal(parse(data)))) def part2(data): - called_numbers, cards = data - cards = {h: cards[h] for h in range(len(cards))} - for called_number in called_numbers: - for h in list(cards.keys()): - cards[h], bingo = check_on_card(cards[h], called_number) - if bingo: - if len(cards) > 1: - del cards[h] - else: - return compute_score(cards[h]) * called_number - - - -def compute_score(card): - return sum([sum([n for n in row if n > 0]) for row in card]) - -def check_on_card(card, called_number): - for i in range(len(card)): - for j in range(len(card[i])): - if card[i][j] == called_number: - card[i][j] *= -1 - if called_number == 0: card[i][j] = -100 # edge case - if all([n < 0 for n in card[i]]) or all([row[j] < 0 for row in card]): # row or column checked - return card, True - else: - return card, False - return card, False # number is not on the card - - """Solve part 1""" + return count_dangerous(turn_to_grid(parse(data))) - -def solve(day=4): +def solve(day=5): """Solve the puzzle for the given input""" @@ -57,25 +43,5 @@ def solve(day=4): #data = example_data - print('part one:', part1(parse(data))) - print('part two:', part2(parse(data))) - -example_data = """7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1 - -22 13 17 11 0 - 8 2 23 4 24 -21 9 14 16 7 - 6 10 3 18 5 - 1 12 20 15 19 - - 3 15 0 2 22 - 9 18 13 17 5 -19 8 7 25 23 -20 11 10 24 4 -14 21 16 12 6 - -14 21 17 24 4 -10 16 15 9 19 -18 8 23 26 20 -22 11 13 6 5 - 2 0 12 3 7""" + print('part one:', part1(data)) + print('part two:', part2(data)) diff --git a/test_aoc_5.py b/test_aoc_5.py index e9b36ac..8719ec7 100644 --- a/test_aoc_5.py +++ b/test_aoc_5.py @@ -1,44 +1,79 @@ -import aocd +import aoc_5 as target -def parse(puzzle_input): - """Parse input""" - lines = puzzle_input.splitlines() - return None +def test_parse(): + assert target.parse(example_data) == example_lines -def part1(data): - return 0 -def part2(data): - return 0 +def test_turn_to_grid(): + assert target.turn_to_grid(target.omit_diagnal(example_lines)) == example_grid_1 + assert target.turn_to_grid(example_lines) == example_grid_2 -def solve(day=5): - """Solve the puzzle for the given input""" +def test_count_dangerous(): + assert target.count_dangerous(example_grid_1) == 5 + assert target.count_dangerous(example_grid_2) == 12 - data = aocd.get_data(day=day) - #data = example_data +def test_part1(): + assert target.part1(example_data) == 5 - print('part one:', part1(parse(data))) - print('part two:', part2(parse(data))) +def test_part2(): + assert target.part2(example_data) == 12 -example_data = """7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1 +example_data = """0,9 -> 5,9 +8,0 -> 0,8 +9,4 -> 3,4 +2,2 -> 2,1 +7,0 -> 7,4 +6,4 -> 2,0 +0,9 -> 2,9 +3,4 -> 1,4 +0,0 -> 8,8 +5,5 -> 8,2""" -22 13 17 11 0 - 8 2 23 4 24 -21 9 14 16 7 - 6 10 3 18 5 - 1 12 20 15 19 +example_lines = [ + [(0, 9), (5, 9)], + [(8, 0), (0, 8)], + [(9, 4), (3, 4)], + [(2, 2), (2, 1)], + [(7, 0), (7, 4)], + [(6, 4), (2, 0)], + [(0, 9), (2, 9)], + [(3, 4), (1, 4)], + [(0, 0), (8, 8)], + [(5, 5), (8, 2)], +] - 3 15 0 2 22 - 9 18 13 17 5 -19 8 7 25 23 -20 11 10 24 4 -14 21 16 12 6 +example_grid_1_string = """.......1.. +..1....1.. +..1....1.. +.......1.. +.112111211 +.......... +.......... +.......... +.......... +222111....""" -14 21 17 24 4 -10 16 15 9 19 -18 8 23 26 20 -22 11 13 6 5 - 2 0 12 3 7""" +example_grid_2_string = """1.1....11. +.111...2.. +..2.1.111. +...1.2.2.. +.112313211 +...1.2.... +..1...1... +.1.....1.. +1.......1. +222111....""" + + +def turn_to_int(c): + if c == '.': + return 0 + else: + return int(c) + + +example_grid_1 = [[turn_to_int(c) for c in line] for line in example_grid_1_string.splitlines()] +example_grid_2 = [[turn_to_int(c) for c in line] for line in example_grid_2_string.splitlines()]