Skip to content

Commit

Permalink
add 2020 day 16
Browse files Browse the repository at this point in the history
  • Loading branch information
NimVek committed Nov 11, 2023
1 parent 9914d5a commit c33771b
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![AoC 2017](https://img.shields.io/badge/2017-★_24-bcb01b)](https://adventofcode.com/2017)
[![AoC 2018](https://img.shields.io/badge/2018-★_9-fb7938)](https://adventofcode.com/2018)
[![AoC 2019](https://img.shields.io/badge/2019-★_6-f26e3c)](https://adventofcode.com/2019)
[![AoC 2020](https://img.shields.io/badge/2020-★_2-e66241)](https://adventofcode.com/2020)
[![AoC 2020](https://img.shields.io/badge/2020-★_4-ec683f)](https://adventofcode.com/2020)
[![AoC 2021](https://img.shields.io/badge/2021-★_50-44cc11)](https://adventofcode.com/2021)
[![AoC 2022](https://img.shields.io/badge/2022-★_50-44cc11)](https://adventofcode.com/2022)
[![AoC 2023](https://img.shields.io/badge/2023-★_0-9f9f9f)](https://adventofcode.com/2023)
Expand Down
3 changes: 3 additions & 0 deletions y2020/d16/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__year__ = 2020
__day__ = 16
__title__ = "Ticket Translation"
12 changes: 12 additions & 0 deletions y2020/d16/cases/example.71..txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class: 1-3 or 5-7
row: 6-11 or 33-44
seat: 13-40 or 45-50

your ticket:
7,1,14

nearby tickets:
7,3,47
40,4,50
55,2,20
38,6,12
85 changes: 85 additions & 0 deletions y2020/d16/solution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import collections
import functools

from dataclasses import dataclass
from math import prod

from aoc.lib.sets import IntervalSet
from aoc.lib.solution import SolutionBase

import logging


__all__ = ["Solution"]
__log__ = logging.getLogger(__name__)

Ticket = tuple[int, ...]


@dataclass
class Input:
rules: dict[str, IntervalSet]
own: Ticket
nearby: list[Ticket]


class Solution(SolutionBase):
@staticmethod
def prepare(data):
return Input(
rules={
field: IntervalSet(
*(
map(int, interval.split("-"))
for interval in value.strip().split(" or ")
)
)
for field, value in (rule.split(":") for rule in data[0])
},
own=tuple(map(int, data[1][1].split(","))),
nearby=list(tuple(map(int, ticket.split(","))) for ticket in data[2][1:]),
)

@staticmethod
def part_01(data):
valid = functools.reduce(lambda a, b: a | b, data.rules.values())
return sum(sum(x for x in ticket if x not in valid) for ticket in data.nearby)

@staticmethod
def part_02(data):
valid = functools.reduce(lambda a, b: a | b, data.rules.values())
tickets = (ticket for ticket in data.nearby if all(x in valid for x in ticket))

investigate = collections.defaultdict(lambda: set(range(len(data.own) + 1)))
for ticket in tickets:
for name, values in data.rules.items():
investigate[name] &= {
idx for idx, value in enumerate(ticket) if value in values
}

translate = {}
while investigate:
translate.update(
{
code: opcodes.pop()
for code, opcodes in investigate.items()
if len(opcodes) == 1
}
)
investigate = {
code: opcodes - set(translate.values())
for code, opcodes in investigate.items()
if len(opcodes) > 1
}

return prod(
data.own[idx]
for name, idx in translate.items()
if name.startswith("departure")
)


if __name__ == "__main__":
import aoc.lib.main

aoc.lib.main.main(Solution)

0 comments on commit c33771b

Please sign in to comment.