Add day 4 solution
This commit is contained in:
parent
1e22b8a79d
commit
4c48271071
2 changed files with 79 additions and 0 deletions
|
@ -21,3 +21,26 @@
|
||||||
*** Answers
|
*** Answers
|
||||||
2600
|
2600
|
||||||
86036
|
86036
|
||||||
|
|
||||||
|
** Day 4
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
source ~/virtualenvs/aoc-2023/bin/activate
|
||||||
|
cd ~/git/advent-of-code/python/2023
|
||||||
|
python src/andy_aoc_2023/day4.py src/andy_aoc_2023/day4_big
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
Warning: Part 2 is a little slow
|
||||||
|
|
||||||
|
#+begin_src shell
|
||||||
|
~/bin/avg-time 5 python src/andy_aoc_2023/day4.py src/andy_aoc_2023/day4_big
|
||||||
|
real 8.994000
|
||||||
|
user 8.982000
|
||||||
|
sys 0.008000
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
where =avg-time= is [[https://stackoverflow.com/a/54920339][this bit of =awk=]]
|
||||||
|
|
||||||
|
*** Answers
|
||||||
|
19135
|
||||||
|
5704953
|
||||||
|
|
56
python/2023/src/andy_aoc_2023/day4.py
Normal file
56
python/2023/src/andy_aoc_2023/day4.py
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
from collections import defaultdict
|
||||||
|
from pprint import pprint
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def parse_raw_input(lines):
|
||||||
|
output ={}
|
||||||
|
for line in lines:
|
||||||
|
card_num, numbers = line.strip().split(": ")
|
||||||
|
card_id = card_num.split(" ")[-1]
|
||||||
|
winning_nums, our_nums = numbers.split(" | ")
|
||||||
|
output[card_id] = {
|
||||||
|
"win": re.split(r"\s+", winning_nums),
|
||||||
|
"our": re.split(r"\s+", our_nums),
|
||||||
|
}
|
||||||
|
return output
|
||||||
|
|
||||||
|
def part_1(input_lines):
|
||||||
|
total = 0
|
||||||
|
for id, cards in input_lines.items():
|
||||||
|
win = set(cards["win"])
|
||||||
|
our = set(cards["our"])
|
||||||
|
|
||||||
|
matches = win.intersection(our)
|
||||||
|
count = val if (val := len(matches)) > 0 else 0
|
||||||
|
points = (2 ** (count - 1) // 1)
|
||||||
|
total += points
|
||||||
|
print(f"Card {id} has {count} {matches} matches, {points} points, total {total}")
|
||||||
|
|
||||||
|
|
||||||
|
def part_2(input_lines):
|
||||||
|
instances = defaultdict(lambda : 0)
|
||||||
|
for id, cards in input_lines.items():
|
||||||
|
instances[id] += 1
|
||||||
|
for _ in range(instances[id]):
|
||||||
|
win = set(cards["win"])
|
||||||
|
our = set(cards["our"])
|
||||||
|
|
||||||
|
matches = win.intersection(our)
|
||||||
|
count = val if (val := len(matches)) > 0 else 0
|
||||||
|
|
||||||
|
for x in range(count):
|
||||||
|
copy_num = int(id) + 1 + x
|
||||||
|
instances[str(copy_num)] += 1
|
||||||
|
|
||||||
|
print(f"Total {sum( x for x in instances.values() )}")
|
||||||
|
|
||||||
|
|
||||||
|
input_file = sys.argv[1]
|
||||||
|
|
||||||
|
with open(input_file) as infile:
|
||||||
|
input_lines = parse_raw_input(infile.readlines())
|
||||||
|
|
||||||
|
part_1(input_lines)
|
||||||
|
part_2(input_lines)
|
Loading…
Reference in a new issue