From 4c482710711ac6a9edda32f77f47c05ea222d178 Mon Sep 17 00:00:00 2001 From: Andy Lu Date: Mon, 4 Dec 2023 11:13:18 -0500 Subject: [PATCH] Add day 4 solution --- python/2023/README.org | 23 +++++++++++ python/2023/src/andy_aoc_2023/day4.py | 56 +++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 python/2023/src/andy_aoc_2023/day4.py diff --git a/python/2023/README.org b/python/2023/README.org index 24e116d..7114af7 100644 --- a/python/2023/README.org +++ b/python/2023/README.org @@ -21,3 +21,26 @@ *** Answers 2600 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 diff --git a/python/2023/src/andy_aoc_2023/day4.py b/python/2023/src/andy_aoc_2023/day4.py new file mode 100644 index 0000000..2c56945 --- /dev/null +++ b/python/2023/src/andy_aoc_2023/day4.py @@ -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)