mirror of
https://github.com/Noettore/AdventOfCode.git
synced 2025-10-14 19:26:39 +02:00
116 lines
3.1 KiB
Python
116 lines
3.1 KiB
Python
"""AOC Day 4"""
|
|
|
|
from os import read
|
|
import pathlib
|
|
import time
|
|
|
|
TEST_INPUT = """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"""
|
|
|
|
def read_input(input_path: str) -> str:
|
|
"""take input file path and return a str with the file's content"""
|
|
with open(input_path, 'r') as input_file:
|
|
input_data = input_file.read().strip()
|
|
return input_data
|
|
|
|
def extract(input_data: str) -> tuple:
|
|
"""take input data and return the appropriate data structure"""
|
|
matrixs = input_data.split('\n\n')
|
|
drawn_nums = list(map(int, matrixs.pop(0).split(',')))
|
|
cards = list()
|
|
for matrix in matrixs:
|
|
card = []
|
|
for line in matrix.split('\n'):
|
|
card.append(list(map(int, line.split())))
|
|
cards.append(card)
|
|
return (drawn_nums, cards)
|
|
|
|
def check_card(card: list, r: int, c: int) -> bool:
|
|
if sum(x == -1 for x in card[r]) == 5:
|
|
return True
|
|
if sum(row[c] == -1 for row in card) == 5:
|
|
return True
|
|
return False
|
|
|
|
def mark_num(card: list, num: int) -> bool:
|
|
for row_num, row in enumerate(card):
|
|
for col_num, cell in enumerate(row):
|
|
if cell == num:
|
|
card[row_num][col_num] = -1
|
|
return check_card(card, row_num, col_num)
|
|
return False
|
|
|
|
def card_score(card: list, last_num: int) -> int:
|
|
unmarked_sum = 0
|
|
for row in card:
|
|
for cell in row:
|
|
if cell != -1:
|
|
unmarked_sum += cell
|
|
return unmarked_sum*last_num
|
|
|
|
def part1and2(entries: tuple) -> tuple:
|
|
"""part2 solver take the entries and return the part2 solution"""
|
|
drawn_nums, cards = entries
|
|
n_cards = len(cards)
|
|
won_cards = 0
|
|
|
|
first_score = 0
|
|
last_score = 0
|
|
|
|
for num in drawn_nums:
|
|
for i, card in enumerate(cards):
|
|
if card is None:
|
|
continue
|
|
if mark_num(card, num):
|
|
won_cards += 1
|
|
if won_cards == 1:
|
|
first_score = card_score(card, num)
|
|
if won_cards == n_cards:
|
|
last_score = card_score(card, num)
|
|
cards[i] = None
|
|
|
|
return (first_score, last_score)
|
|
|
|
def test_input_day_04():
|
|
"""pytest testing function"""
|
|
entries = extract(TEST_INPUT)
|
|
p1, p2 = part1and2(entries)
|
|
assert p1 == 4512
|
|
assert p2 == 1924
|
|
|
|
def test_bench_day_04(benchmark):
|
|
"""pytest-benchmark function"""
|
|
benchmark(main)
|
|
|
|
def main():
|
|
"""main function"""
|
|
input_path = str(pathlib.Path(__file__).resolve().parent.parent) + "/inputs/" + str(pathlib.Path(__file__).stem)
|
|
start_time = time.time()
|
|
input_data = read_input(input_path)
|
|
entries = extract(input_data)
|
|
p1, p2 = part1and2(entries)
|
|
print("Part 1: %d" % p1)
|
|
print("Part 2: %d" % p2)
|
|
end_time = time.time()
|
|
print("Execution time: %f" % (end_time-start_time))
|
|
|
|
if __name__ == "__main__":
|
|
main()
|