Skip to content

Commit

Permalink
Day 19: Aplenty
Browse files Browse the repository at this point in the history
  • Loading branch information
ephemient committed Dec 19, 2023
1 parent edcb42c commit 63fd2f1
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ Development occurs in language-specific directories:
|[Day16.hs](hs/src/Day16.hs)|[Day16.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day16.kt)|[day16.py](py/aoc2023/day16.py)|[day16.rs](rs/src/day16.rs)|
|[Day17.hs](hs/src/Day17.hs)|[Day17.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day17.kt)|[day17.py](py/aoc2023/day17.py)|[day17.rs](rs/src/day17.rs)|
|[Day18.hs](hs/src/Day18.hs)|[Day18.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day18.kt)|[day18.py](py/aoc2023/day18.py)|[day18.rs](rs/src/day18.rs)|
|[Day19.hs](hs/src/Day19.hs)|[Day19.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day19.kt)|||
|[Day19.hs](hs/src/Day19.hs)|[Day19.kt](kt/aoc2023-lib/src/commonMain/kotlin/com/github/ephemient/aoc2023/Day19.kt)|[day19.py](py/aoc2023/day19.py)||
122 changes: 122 additions & 0 deletions py/aoc2023/day19.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
"""
Day 19: Aplenty
"""

from math import prod

SAMPLE_INPUT = """
px{a<2006:qkq,m>2090:A,rfg}
pv{a>1716:R,A}
lnx{m>1548:A,A}
rfg{s<537:gd,x>2440:R,A}
qs{s>3448:A,lnx}
qkq{x<1416:A,crn}
crn{x>2662:A,R}
in{s<1351:px,qqz}
qqz{s>2770:qs,m<1801:hdj,R}
gd{a>3333:R,R}
hdj{m>838:A,pv}
{x=787,m=2655,a=1222,s=2876}
{x=1679,m=44,a=2067,s=496}
{x=2036,m=264,a=79,s=2244}
{x=2461,m=1339,a=466,s=291}
{x=2127,m=1623,a=2188,s=1013}
"""


def _parse_rules(data):
for line in data.splitlines():
if "{" not in line or not line.endswith("}"):
continue
yield line[: line.index("{")], [
(
rule[rule.index(":") + 1 :],
(rule[0], rule[1], int(rule[2 : rule.index(":")])),
)
if ":" in rule
else (rule, None)
for rule in line[line.index("{") + 1 : -1].split(",")
]


def _parse_points(data):
for line in data.splitlines():
if not line.startswith("{") or not line.endswith("}"):
continue
yield {kv[0]: int(kv[2:]) for kv in line[1:-1].split(",") if kv[1] == "="}


def part1(data):
"""
>>> part1(SAMPLE_INPUT)
19114
"""
rules, points = data.split("\n\n", maxsplit=1)
rules = dict(_parse_rules(rules))
points = list(_parse_points(points))

acc = 0
for point in points:
name = "in"
while name in rules:
for name, comparison in rules[name]:
if not comparison:
break
key, compare, value = comparison
if (
compare == "<"
and point[key] < value
or compare == ">"
and point[key] > value
):
break
else:
raise RuntimeError("unreachable")
if name == "A":
acc += sum(point.values())
return acc


def part2(data):
"""
>>> part2(SAMPLE_INPUT)
167409079868000
"""
rules, _ = data.split("\n\n", maxsplit=1)
rules = dict(_parse_rules(rules))

def go(name, bounds):
if any(first > last for first, last in bounds.values()):
return 0
if name == "A":
return prod(last - first + 1 for first, last in bounds.values())
if name not in rules:
return 0
acc = 0
# pylint: disable=R1704
for name, comparison in rules[name]:
if not comparison:
acc += go(name, bounds)
break
key, compare, value = comparison
lo, hi = bounds[key]
match compare:
case "<":
intersection = lo, min(hi, value - 1)
difference = value, hi
case ">":
intersection = max(lo, value + 1), hi
difference = lo, min(hi, value)
case _:
raise KeyError(compare)
if difference[0] > difference[1]:
break
acc += go(name, bounds | {key: intersection})
bounds[key] = difference
return acc

return go("in", {k: (1, 4000) for k in "xmas"})


parts = (part1, part2)
1 change: 1 addition & 0 deletions py/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ day15 = "aoc2023.day15:parts"
day16 = "aoc2023.day16:parts"
day17 = "aoc2023.day17:parts"
day18 = "aoc2023.day18:parts"
day19 = "aoc2023.day19:parts"

[tool.black]
target_version = ["py312"]
Expand Down

0 comments on commit 63fd2f1

Please sign in to comment.