This commit is contained in:
akp 2024-12-05 12:07:35 +00:00
parent b661de71ed
commit 2f7daa9cab
No known key found for this signature in database
GPG key ID: CF8D58F3DEB20755
6 changed files with 110 additions and 1 deletions

View file

@ -0,0 +1 @@
# [Day 5: Print Queue](https://adventofcode.com/2024/day/5)

View file

@ -0,0 +1,91 @@
import sys
from collections import namedtuple, defaultdict
import math
OrderingRule = namedtuple("OrderingRule", ["page", "goes_before"])
def parse(instr: str) -> tuple[list[OrderingRule], list[list[int]]]:
rules, sets = instr.split("\n\n")
return (
[OrderingRule(*map(int, line.split("|"))) for line in rules.splitlines()],
[list(map(int, line.split(","))) for line in sets.splitlines()],
)
def generate_rule_map(rules: list[OrderingRule]) -> dict[int, list[int]]:
rule_map = defaultdict(lambda: [])
for rule in rules:
rule_map[rule.page].append(rule.goes_before)
return rule_map
def is_pageset_valid(rule_map: dict[int, list[int]], pageset: list[int]) -> bool:
for i, v in enumerate(pageset):
before = pageset[:i]
for following_number in rule_map[v]:
if following_number in before:
return False
return True
def get_middle_number(x: list[int]) -> int:
assert len(x) % 2 == 1, f"{x} has no nice middle point"
return x[int((len(x) - 1) / 2)]
def one(instr: str):
rules, pagesets = parse(instr)
rule_map = generate_rule_map(rules) # for each item, these items should be after it
acc = 0
for pageset in pagesets:
if is_pageset_valid(rule_map, pageset):
acc += get_middle_number(pageset)
return acc
def two(instr: str):
rules, pagesets = parse(instr)
rule_map = generate_rule_map(rules)
inverse_rule_map = defaultdict(
lambda: []
) # for each item, these items should be before it
for rule in rules:
inverse_rule_map[rule.goes_before].append(rule.page)
acc = 0
for pageset in filter(lambda x: not is_pageset_valid(rule_map, x), pagesets):
while not is_pageset_valid(rule_map, pageset):
for i in range(len(pageset)):
for j in range(i + 1, len(pageset)):
iv = pageset[i]
jv = pageset[j]
if jv in inverse_rule_map[iv] and i < j:
pageset[i], pageset[j] = pageset[j], pageset[i]
acc += get_middle_number(pageset)
return acc
def _debug(*args, **kwargs):
kwargs["file"] = sys.stderr
print(*args, **kwargs)
if __name__ == "__main__":
if len(sys.argv) < 2 or sys.argv[1] not in ["1", "2"]:
print("Missing day argument", file=sys.stderr)
sys.exit(1)
inp = sys.stdin.read().strip()
if sys.argv[1] == "1":
print(one(inp))
else:
print(two(inp))

View file

@ -0,0 +1,14 @@
{
"1": [
{
"is": "143",
"input": "47|53\n97|13\n97|61\n97|47\n75|29\n61|13\n75|53\n29|13\n97|29\n53|29\n61|53\n97|53\n61|29\n47|13\n75|47\n97|75\n47|61\n75|61\n47|29\n75|13\n53|13\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n75,97,47,61,53\n61,13,29\n97,13,75,29,47\n\n"
}
],
"2": [
{
"is": "123",
"input": "47|53\n97|13\n97|61\n97|47\n75|29\n61|13\n75|53\n29|13\n97|29\n53|29\n61|53\n97|53\n61|29\n47|13\n75|47\n97|75\n47|61\n75|61\n47|29\n75|13\n53|13\n\n75,47,61,53,29\n97,61,53,29,13\n75,29,13\n75,97,47,61,53\n61,13,29\n97,13,75,29,47\n\n"
}
]
}

View file

@ -17,4 +17,5 @@ A day denoted with an asterisk means it has a visualisation.
| 01 - Historian Hysteria | ★ ★ | Python | The reading comprehension was the hardest part of this. |
| 02 - Red-Nosed Reindeer | ★ ★ | Python ||
| 03 - Mull It Over | ★ ★ | Python | The first instance of Advent of Parsing this year! |
| 04* - Ceres Search | ★ ★ | Python | When it says a cross, it does not mean a plus. |
| 04* - Ceres Search | ★ ★ | Python | When it says a cross, it does not mean a plus. |
| 05 - Print Queue | ★ ★ | Python | Before you dismiss and idea as being "too simple", make sure you check that it actually wouldn't work! |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Before After
Before After

View file

@ -6,3 +6,5 @@
{"day": 3, "part": 2, "runner": "py", "min": 0.02115607261657715, "max": 0.03121805191040039, "avg": 0.022722084522247315, "n": 100}
{"day": 4, "part": 1, "runner": "py", "min": 0.17342424392700195, "max": 0.3778045177459717, "avg": 0.18848238706588746, "n": 100}
{"day": 4, "part": 2, "runner": "py", "min": 0.05280470848083496, "max": 0.06299543380737305, "avg": 0.05627016305923462, "n": 100}
{"day": 5, "part": 1, "runner": "py", "min": 0.02001357078552246, "max": 0.030559301376342773, "avg": 0.02152919292449951, "n": 100}
{"day": 5, "part": 2, "runner": "py", "min": 0.02507805824279785, "max": 0.03197765350341797, "avg": 0.027084295749664308, "n": 100}