2015 day 4, 5, 6, 7.
This commit is contained in:
		| @@ -4,12 +4,17 @@ import numpy as np | ||||
|  | ||||
| lines = sys.stdin.read().splitlines() | ||||
|  | ||||
| l, w, h = np.array([[int(c) for c in line.split("x")] for line in lines]).T | ||||
| length, width, height = np.array( | ||||
|     [[int(c) for c in line.split("x")] for line in lines] | ||||
| ).T | ||||
|  | ||||
| lw, wh, hl = (l * w, w * h, h * l) | ||||
| lw, wh, hl = (length * width, width * height, height * length) | ||||
|  | ||||
| answer_1 = np.sum(2 * (lw + wh + hl) + np.min(np.stack([lw, wh, hl]), axis=0)) | ||||
| print(f"answer 1 is {answer_1}") | ||||
|  | ||||
| answer_2 = np.sum(l * w * h + 2 * np.min(np.stack([l + w, l + h, h + w]), axis=0)) | ||||
| answer_2 = np.sum( | ||||
|     length * width * height | ||||
|     + 2 * np.min(np.stack([length + width, length + height, height + width]), axis=0) | ||||
| ) | ||||
| print(f"answer 2 is {answer_2}") | ||||
|   | ||||
							
								
								
									
										16
									
								
								src/holt59/aoc/2015/day4.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/holt59/aoc/2015/day4.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| import hashlib | ||||
| import itertools | ||||
| import sys | ||||
|  | ||||
| line = sys.stdin.read().strip() | ||||
|  | ||||
| it = iter(itertools.count(1)) | ||||
| answer_1 = next( | ||||
|     i for i in it if hashlib.md5(f"{line}{i}".encode()).hexdigest().startswith("00000") | ||||
| ) | ||||
| print(f"answer 1 is {answer_1}") | ||||
|  | ||||
| answer_2 = next( | ||||
|     i for i in it if hashlib.md5(f"{line}{i}".encode()).hexdigest().startswith("000000") | ||||
| ) | ||||
| print(f"answer 2 is {answer_2}") | ||||
							
								
								
									
										36
									
								
								src/holt59/aoc/2015/day5.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/holt59/aoc/2015/day5.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| import sys | ||||
|  | ||||
| VOWELS = "aeiou" | ||||
| FORBIDDEN = {"ab", "cd", "pq", "xy"} | ||||
|  | ||||
|  | ||||
| def is_nice_1(s: str) -> bool: | ||||
|     if sum(c in VOWELS for c in s) < 3: | ||||
|         return False | ||||
|  | ||||
|     if not any(a == b for a, b in zip(s[:-1:], s[1::])): | ||||
|         return False | ||||
|  | ||||
|     if any(s.find(f) >= 0 for f in FORBIDDEN): | ||||
|         return False | ||||
|  | ||||
|     return True | ||||
|  | ||||
|  | ||||
| def is_nice_2(s: str) -> bool: | ||||
|     if not any(s.find(s[i : i + 2], i + 2) >= 0 for i in range(len(s))): | ||||
|         return False | ||||
|  | ||||
|     if not any(a == b for a, b in zip(s[:-1:], s[2::])): | ||||
|         return False | ||||
|  | ||||
|     return True | ||||
|  | ||||
|  | ||||
| lines = sys.stdin.read().splitlines() | ||||
|  | ||||
| answer_1 = sum(map(is_nice_1, lines)) | ||||
| print(f"answer 1 is {answer_1}") | ||||
|  | ||||
| answer_2 = sum(map(is_nice_2, lines)) | ||||
| print(f"answer 2 is {answer_2}") | ||||
							
								
								
									
										33
									
								
								src/holt59/aoc/2015/day6.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/holt59/aoc/2015/day6.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| import sys | ||||
| from typing import Literal, cast | ||||
|  | ||||
| import numpy as np | ||||
| import parse  # type: ignore | ||||
|  | ||||
| lines = sys.stdin.read().splitlines() | ||||
|  | ||||
| lights_1 = np.zeros((1000, 1000), dtype=bool) | ||||
| lights_2 = np.zeros((1000, 1000), dtype=int) | ||||
| for line in lines: | ||||
|     action, sx, sy, ex, ey = cast( | ||||
|         tuple[Literal["turn on", "turn off", "toggle"], int, int, int, int], | ||||
|         parse.parse("{} {:d},{:d} through {:d},{:d}", line),  # type: ignore | ||||
|     ) | ||||
|     ex, ey = ex + 1, ey + 1 | ||||
|  | ||||
|     match action: | ||||
|         case "turn on": | ||||
|             lights_1[sx:ex, sy:ey] = True | ||||
|             lights_2[sx:ex, sy:ey] += 1 | ||||
|         case "turn off": | ||||
|             lights_1[sx:ex, sy:ey] = False | ||||
|             lights_2[sx:ex, sy:ey] = np.maximum(lights_2[sx:ex, sy:ey] - 1, 0) | ||||
|         case "toggle": | ||||
|             lights_1[sx:ex, sy:ey] = ~lights_1[sx:ex, sy:ey] | ||||
|             lights_2[sx:ex, sy:ey] += 2 | ||||
|  | ||||
| answer_1 = lights_1.sum() | ||||
| print(f"answer 1 is {answer_1}") | ||||
|  | ||||
| answer_2 = lights_2.sum() | ||||
| print(f"answer 2 is {answer_2}") | ||||
							
								
								
									
										101
									
								
								src/holt59/aoc/2015/day7.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								src/holt59/aoc/2015/day7.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| import logging | ||||
| import operator | ||||
| import os | ||||
| import sys | ||||
| from typing import Callable, Literal, TypeAlias, cast | ||||
|  | ||||
| VERBOSE = os.getenv("AOC_VERBOSE") == "True" | ||||
| logging.basicConfig(level=logging.INFO if VERBOSE else logging.WARNING) | ||||
|  | ||||
| OPERATORS = { | ||||
|     "AND": operator.and_, | ||||
|     "OR": operator.or_, | ||||
|     "LSHIFT": operator.lshift, | ||||
|     "RSHIFT": operator.rshift, | ||||
| } | ||||
|  | ||||
| ValueGetter = Callable[[dict[str, int]], int] | ||||
| Signals = dict[ | ||||
|     str, | ||||
|     tuple[ | ||||
|         tuple[str, str], | ||||
|         tuple[ValueGetter, ValueGetter], | ||||
|         Callable[[int, int], int], | ||||
|     ], | ||||
| ] | ||||
|  | ||||
|  | ||||
| def zero_op(_a: int, _b: int) -> int: | ||||
|     return 0 | ||||
|  | ||||
|  | ||||
| def value_of(key: str) -> tuple[str, Callable[[dict[str, int]], int]]: | ||||
|     try: | ||||
|         return "", lambda _p, _v=int(key): _v | ||||
|     except ValueError: | ||||
|         return key, lambda values: values[key] | ||||
|  | ||||
|  | ||||
| lines = sys.stdin.read().splitlines() | ||||
|  | ||||
| signals: Signals = {} | ||||
| values: dict[str, int] = {"": 0} | ||||
|  | ||||
| for line in lines: | ||||
|     command, signal = line.split(" -> ") | ||||
|  | ||||
|     if command.startswith("NOT"): | ||||
|         name = command.split(" ")[1] | ||||
|         signals[signal] = ( | ||||
|             (name, ""), | ||||
|             (lambda values, _n=name: values[_n], lambda _v: 0), | ||||
|             lambda a, _b: ~a, | ||||
|         ) | ||||
|  | ||||
|     elif not any(command.find(name) >= 0 for name in OPERATORS): | ||||
|         try: | ||||
|             values[signal] = int(command) | ||||
|         except ValueError: | ||||
|             signals[signal] = ( | ||||
|                 (command, ""), | ||||
|                 (lambda values, _c=command: values[_c], lambda _v: 0), | ||||
|                 lambda a, _b: a, | ||||
|             ) | ||||
|  | ||||
|     else: | ||||
|         op: Callable[[int, int], int] = zero_op | ||||
|         lhs_s, rhs_s = "", "" | ||||
|  | ||||
|         for name in OPERATORS: | ||||
|             if command.find(name) >= 0: | ||||
|                 op = OPERATORS[name] | ||||
|                 lhs_s, rhs_s = command.split(f" {name} ") | ||||
|                 break | ||||
|  | ||||
|         lhs_s, lhs_fn = value_of(lhs_s) | ||||
|         rhs_s, rhs_fn = value_of(rhs_s) | ||||
|  | ||||
|         signals[signal] = ((lhs_s, rhs_s), (lhs_fn, rhs_fn), op) | ||||
|  | ||||
|  | ||||
| def process( | ||||
|     signals: Signals, | ||||
|     values: dict[str, int], | ||||
| ) -> dict[str, int]: | ||||
|     while signals: | ||||
|         signal = next(s for s in signals if all(p in values for p in signals[s][0])) | ||||
|         _, deps, command = signals[signal] | ||||
|         values[signal] = command(deps[0](values), deps[1](values)) % 65536 | ||||
|         del signals[signal] | ||||
|  | ||||
|     return values | ||||
|  | ||||
|  | ||||
| values_1 = process(signals.copy(), values.copy()) | ||||
| logging.info("\n" + "\n".join(f"{k}: {values_1[k]}" for k in sorted(values_1))) | ||||
| answer_1 = values_1["a"] | ||||
| print(f"answer 1 is {answer_1}") | ||||
|  | ||||
| values_2 = process(signals.copy(), values | {"b": values_1["a"]}) | ||||
| answer_2 = values_2["a"] | ||||
| print(f"answer 2 is {answer_2}") | ||||
		Reference in New Issue
	
	Block a user