2024.05
This commit is contained in:
parent
b661de71ed
commit
2f7daa9cab
6 changed files with 110 additions and 1 deletions
1
challenges/2024/05-printQueue/README.md
Normal file
1
challenges/2024/05-printQueue/README.md
Normal file
|
@ -0,0 +1 @@
|
|||
# [Day 5: Print Queue](https://adventofcode.com/2024/day/5)
|
91
challenges/2024/05-printQueue/main.py
Normal file
91
challenges/2024/05-printQueue/main.py
Normal 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))
|
14
challenges/2024/05-printQueue/tests.json
Normal file
14
challenges/2024/05-printQueue/tests.json
Normal 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"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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 |
|
@ -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}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue