Skip to content

Instantly share code, notes, and snippets.

@code-shoily
Created December 13, 2023 05:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save code-shoily/fa308effdffc02974640f70e5f62b827 to your computer and use it in GitHub Desktop.
Save code-shoily/fa308effdffc02974640f70e5f62b827 to your computer and use it in GitHub Desktop.
Advent of Code 2023 - Day 12
from functools import lru_cache
type Group = tuple[int, ...]
type Result = tuple[int, int]
type SpringConfiguration = tuple[str, Group]
OPERATIONAL = "."
DAMAGED = "#"
@lru_cache(maxsize=None)
def arrangements(
springs: str, groups: Group, current=0, current_count=0, processed=0
) -> int:
if current == len(springs):
return 1 if len(groups) == processed else 0
if springs[current] == DAMAGED:
return arrangements(springs, groups, current + 1, current_count + 1, processed)
if springs[current] == OPERATIONAL or processed == len(groups):
if processed < len(groups) and current_count == groups[processed]:
return arrangements(springs, groups, current + 1, 0, processed + 1)
return (
arrangements(springs, groups, current + 1, 0, processed)
if not current_count
else 0
)
damaged = arrangements(springs, groups, current + 1, current_count + 1, processed)
match current_count:
case count if count == groups[processed]:
return damaged + arrangements(
springs, groups, current + 1, 0, processed + 1
)
case 0:
return damaged + arrangements(springs, groups, current + 1, 0, processed)
case _:
return damaged
def parse_input(year, day) -> list[SpringConfiguration]:
def get_spring(i):
[spring, count_str] = i.split(" ")
return (spring, tuple([int(i) for i in count_str.split(",")]))
with open(f"../input_files/{year}_{day}.txt") as f:
return list(map(get_spring, f.readlines()))
def run(input_data: list[SpringConfiguration]) -> Result:
part_1 = sum(arrangements(spring + ".", groups) for spring, groups in input_data)
part_2 = sum(
arrangements("?".join([spring] * 5) + ".", groups * 5)
for spring, groups in input_data
)
return (part_1, part_2)
if __name__ == "__main__":
input_data = parse_input(2023, 12)
print(run(input_data))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment