Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ solutions:
python3 src/aoc_2023/days/1.py --input_file inputs/1.txt --part 1
python3 src/aoc_2023/days/1.py --input_file inputs/1.txt --part 2
python3 src/aoc_2023/days/2.py --input_file inputs/2.txt
python3 src/aoc_2023/days/3.py --input_file inputs/3.txt
python3 src/aoc_2023/days/3.py --input_file inputs/3.txt
python3 src/aoc_2023/days/4.py --input_file inputs/4.txt
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@ docker run aoc-2023-app
| 01 | ⭐️ | ⭐️ |
| 02 | ⭐️ | ⭐️ |
| 03 | ⭐️ | ⭐️ |
| 04 | todo | todo |
| 04 | ⭐️ | todo |
15 changes: 15 additions & 0 deletions src/aoc_2023/days/4.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from aoc_2023.solvers.day_4_solvers import (
solve_day_4,
)
from aoc_2023.utils.input_handling import read_input, parse_args


def main():
args = parse_args()
input = read_input(args.input_file)
result_part_1 = solve_day_4(input)
print(f"Day 4. Total points for part 1 is {result_part_1}. ")


if __name__ == "__main__":
main()
62 changes: 62 additions & 0 deletions src/aoc_2023/solvers/day_4_solvers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import re


class Card:
def __init__(self, card_number, winning_numbers, numbers_i_have):
self.card_number = card_number
self.winning_numbers = winning_numbers
self.numbers_i_have = numbers_i_have
self.n_winners = None
self.points = None

def __str__(self):
return (
f"Card {self.card_number}: {self.winning_numbers} | "
f"{self.numbers_i_have} | "
f"n_winners: {self.n_winners} | points: {self.points}"
)

def find_n_winners(self):
self.n_winners = sum(
[1 for n in self.numbers_i_have if n in self.winning_numbers]
)

def compute_points(self):
if self.n_winners > 0:
self.points = 2 ** (self.n_winners - 1)
else:
self.points = 0


def parse_input_line(line):
card_number = re.findall(r"(\d+)", line.split(":")[0])[0]
all_numbers = line.split(":")[1]
[winning_numbers, numbers_i_have] = all_numbers.split("|")
winning_numbers = re.findall(r"(\d+)", winning_numbers)
numbers_i_have = re.findall(r"(\d+)", numbers_i_have)

return (card_number, winning_numbers, numbers_i_have)


def create_cards(input_txt):
cards = []
for line in input_txt:
(card_number, winning_numbers, numbers_i_have) = parse_input_line(line)
card = Card(card_number, winning_numbers, numbers_i_have)
cards.append(card)
return cards


def compute_total_score(cards):
total_score = 0
for card in cards:
card.find_n_winners()
card.compute_points()
total_score += card.points
return total_score


def solve_day_4(input) -> int:
cards = create_cards(input)
total_score = compute_total_score(cards)
return total_score
30 changes: 30 additions & 0 deletions tests/test_day_4_solvers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pytest
from aoc_2023.solvers.day_4_solvers import solve_day_4


@pytest.fixture
def day_4_test_input():
return [
"Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53",
"Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19",
"Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1",
"Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83",
"Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36",
"Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11",
]


@pytest.fixture
def day_4_expected_scores():
return [
8,
2,
2,
1,
0,
0,
]


def test_solve_day_4(day_4_test_input, day_4_expected_scores):
assert solve_day_4(day_4_test_input) == sum(day_4_expected_scores)