2015 day 12, 13 & 14.
This commit is contained in:
		| @@ -42,7 +42,6 @@ def find_next_password(p: str) -> str: | ||||
|  | ||||
| line = sys.stdin.read().strip() | ||||
|  | ||||
|  | ||||
| answer_1 = find_next_password(line) | ||||
| print(f"answer 1 is {answer_1}") | ||||
|  | ||||
|   | ||||
							
								
								
									
										27
									
								
								src/holt59/aoc/2015/day12.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/holt59/aoc/2015/day12.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| import json | ||||
| import sys | ||||
| from typing import TypeAlias | ||||
|  | ||||
| JsonObject: TypeAlias = dict[str, "JsonObject"] | list["JsonObject"] | int | str | ||||
|  | ||||
|  | ||||
| def json_sum(value: JsonObject, ignore: str | None = None) -> int: | ||||
|     if isinstance(value, str): | ||||
|         return 0 | ||||
|     elif isinstance(value, int): | ||||
|         return value | ||||
|     elif isinstance(value, list): | ||||
|         return sum(json_sum(v, ignore=ignore) for v in value) | ||||
|     elif ignore not in value.values(): | ||||
|         return sum(json_sum(v, ignore=ignore) for v in value.values()) | ||||
|     else: | ||||
|         return 0 | ||||
|  | ||||
|  | ||||
| data: JsonObject = json.load(sys.stdin) | ||||
|  | ||||
| answer_1 = json_sum(data) | ||||
| print(f"answer 1 is {answer_1}") | ||||
|  | ||||
| answer_2 = json_sum(data, "red") | ||||
| print(f"answer 2 is {answer_2}") | ||||
							
								
								
									
										41
									
								
								src/holt59/aoc/2015/day13.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/holt59/aoc/2015/day13.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| import itertools | ||||
| import sys | ||||
| from collections import defaultdict | ||||
| from typing import Literal, cast | ||||
|  | ||||
| import parse  # type: ignore | ||||
|  | ||||
|  | ||||
| def max_change_in_happiness(happiness: dict[str, dict[str, int]]) -> int: | ||||
|     guests = list(happiness) | ||||
|     return max( | ||||
|         sum( | ||||
|             happiness[o][d] + happiness[d][o] | ||||
|             for o, d in zip((guests[0],) + order, order + (guests[0],)) | ||||
|         ) | ||||
|         for order in map(tuple, itertools.permutations(guests[1:])) | ||||
|     ) | ||||
|  | ||||
|  | ||||
| lines = sys.stdin.read().splitlines() | ||||
|  | ||||
| happiness: dict[str, dict[str, int]] = defaultdict(dict) | ||||
| for line in lines: | ||||
|     u1, gain_or_loose, hap, u2 = cast( | ||||
|         tuple[str, Literal["gain", "lose"], int, str], | ||||
|         parse.parse(  # type: ignore | ||||
|             "{} would {} {:d} happiness units by sitting next to {}.", line | ||||
|         ), | ||||
|     ) | ||||
|     happiness[u1][u2] = hap if gain_or_loose == "gain" else -hap | ||||
|  | ||||
|  | ||||
| answer_1 = max_change_in_happiness(happiness) | ||||
| print(f"answer 1 is {answer_1}") | ||||
|  | ||||
| for guest in list(happiness): | ||||
|     happiness["me"][guest] = 0 | ||||
|     happiness[guest]["me"] = 0 | ||||
|  | ||||
| answer_2 = max_change_in_happiness(happiness) | ||||
| print(f"answer 2 is {answer_2}") | ||||
							
								
								
									
										62
									
								
								src/holt59/aoc/2015/day14.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								src/holt59/aoc/2015/day14.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| import sys | ||||
| from dataclasses import dataclass | ||||
| from typing import Literal, cast | ||||
|  | ||||
| import parse  # type: ignore | ||||
|  | ||||
|  | ||||
| @dataclass(frozen=True) | ||||
| class Reindeer: | ||||
|     name: str | ||||
|     speed: int | ||||
|     fly_time: int | ||||
|     rest_time: int | ||||
|  | ||||
|  | ||||
| lines = sys.stdin.read().splitlines() | ||||
|  | ||||
| reindeers: list[Reindeer] = [] | ||||
| for line in lines: | ||||
|     reindeer, speed, speed_time, rest_time = cast( | ||||
|         tuple[str, int, int, int], | ||||
|         parse.parse(  # type: ignore | ||||
|             "{} can fly {:d} km/s for {:d} seconds, " | ||||
|             "but then must rest for {:d} seconds.", | ||||
|             line, | ||||
|         ), | ||||
|     ) | ||||
|     reindeers.append( | ||||
|         Reindeer(name=reindeer, speed=speed, fly_time=speed_time, rest_time=rest_time) | ||||
|     ) | ||||
|  | ||||
| target = 1000 if len(reindeers) <= 2 else 2503 | ||||
|  | ||||
| states: dict[Reindeer, tuple[Literal["resting", "flying"], int]] = { | ||||
|     reindeer: ("resting", 0) for reindeer in reindeers | ||||
| } | ||||
| distances: dict[Reindeer, int] = {reindeer: 0 for reindeer in reindeers} | ||||
| points: dict[Reindeer, int] = {reindeer: 0 for reindeer in reindeers} | ||||
|  | ||||
| for time in range(target): | ||||
|     for reindeer in reindeers: | ||||
|         if states[reindeer][0] == "flying": | ||||
|             distances[reindeer] += reindeer.speed | ||||
|  | ||||
|     top_distance = max(distances.values()) | ||||
|     for reindeer in reindeers: | ||||
|         if distances[reindeer] == top_distance: | ||||
|             points[reindeer] += 1 | ||||
|  | ||||
|     for reindeer in reindeers: | ||||
|         if states[reindeer][1] == time: | ||||
|             if states[reindeer][0] == "resting": | ||||
|                 states[reindeer] = ("flying", time + reindeer.fly_time) | ||||
|             else: | ||||
|                 states[reindeer] = ("resting", time + reindeer.rest_time) | ||||
|  | ||||
|  | ||||
| answer_1 = max(distances.values()) | ||||
| print(f"answer 1 is {answer_1}") | ||||
|  | ||||
| answer_2 = max(points.values()) - 1 | ||||
| print(f"answer 2 is {answer_2}") | ||||
		Reference in New Issue
	
	Block a user