diff options
| author | 2023-12-03 15:34:46 +0100 | |
|---|---|---|
| committer | 2023-12-03 15:34:46 +0100 | |
| commit | 8d8312b9ea8cee09e861165749449961a5c66ab9 (patch) | |
| tree | fd1316a9733154176b0356ee09ee2e5e391a73e0 /day2/__init__.py | |
| parent | d1bbbd066202b7e8a6ef75ef961de20ef4331a40 (diff) | |
| download | 2023-8d8312b9ea8cee09e861165749449961a5c66ab9.tar.gz 2023-8d8312b9ea8cee09e861165749449961a5c66ab9.tar.bz2 2023-8d8312b9ea8cee09e861165749449961a5c66ab9.zip | |
Day 2
Diffstat (limited to 'day2/__init__.py')
| -rw-r--r-- | day2/__init__.py | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/day2/__init__.py b/day2/__init__.py new file mode 100644 index 0000000..0afc441 --- /dev/null +++ b/day2/__init__.py | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | # -*- coding: utf-8 -*- | ||
| 2 | from abc import ABC | ||
| 3 | from enum import Enum | ||
| 4 | from functools import reduce | ||
| 5 | from typing import Iterator | ||
| 6 | |||
| 7 | from aoc import BaseAssignment, I, T | ||
| 8 | |||
| 9 | |||
| 10 | class Color(Enum): | ||
| 11 | red = 'red' | ||
| 12 | green = 'green' | ||
| 13 | blue = 'blue' | ||
| 14 | |||
| 15 | ColorCount = tuple[int, Color] | ||
| 16 | |||
| 17 | class Assignment(BaseAssignment, ABC): | ||
| 18 | def parse_item(self, item: str) -> list[tuple[ColorCount, ...]]: | ||
| 19 | _, items = item.split(': ') | ||
| 20 | |||
| 21 | return [ | ||
| 22 | tuple( | ||
| 23 | ColorCount(( | ||
| 24 | int(_.split(' ')[0]), | ||
| 25 | Color(_.split(' ')[1]) | ||
| 26 | )) | ||
| 27 | for _ in pair.split(', ') | ||
| 28 | ) | ||
| 29 | for pair in items.split('; ') | ||
| 30 | ] | ||
| 31 | |||
| 32 | |||
| 33 | class AssignmentOne(Assignment): | ||
| 34 | example_result = 8 | ||
| 35 | |||
| 36 | inventory = { | ||
| 37 | Color.red: 12, | ||
| 38 | Color.green: 13, | ||
| 39 | Color.blue: 14, | ||
| 40 | } | ||
| 41 | |||
| 42 | def is_possible(self, game: list[tuple[ColorCount, ...]]): | ||
| 43 | for item in game: | ||
| 44 | for count, color in item: | ||
| 45 | if count > self.inventory[color]: | ||
| 46 | return False | ||
| 47 | |||
| 48 | return True | ||
| 49 | |||
| 50 | def run(self, input: Iterator[list[tuple[ColorCount, ...]]]) -> int: | ||
| 51 | possible_games = [] | ||
| 52 | |||
| 53 | for index, game in enumerate(input): | ||
| 54 | if self.is_possible(game): | ||
| 55 | possible_games.append(index + 1) | ||
| 56 | |||
| 57 | return sum(possible_games) | ||
| 58 | |||
| 59 | |||
| 60 | class AssignmentTwo(Assignment): | ||
| 61 | example_result = 2286 | ||
| 62 | |||
| 63 | def get_least_numbers(self, game: list[tuple[ColorCount, ...]]): | ||
| 64 | counts = {} | ||
| 65 | |||
| 66 | for item in game: | ||
| 67 | for count, color in item: | ||
| 68 | if color not in counts or count > counts[color]: | ||
| 69 | counts[color] = count | ||
| 70 | |||
| 71 | return counts | ||
| 72 | |||
| 73 | def run(self, input: Iterator[list[tuple[ColorCount, ...]]]) -> int: | ||
| 74 | powers = [] | ||
| 75 | |||
| 76 | for game in input: | ||
| 77 | counts = self.get_least_numbers(game) | ||
| 78 | powers.append( | ||
| 79 | reduce( | ||
| 80 | lambda total, item: total * item, | ||
| 81 | counts.values(), | ||
| 82 | 1 | ||
| 83 | ) | ||
| 84 | ) | ||
| 85 | |||
| 86 | return sum(powers) | ||
| 87 | |||
| 88 | |||
| 89 | |||
