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