Day12 part 1

This commit is contained in:
Christoph Stahl 2023-12-13 21:33:06 +01:00
parent 9854bf2c99
commit ef470926c0

View file

@ -1,28 +1,11 @@
from __future__ import annotations
from typing import TypeAlias
from dataclasses import dataclass
from itertools import groupby, takewhile, compress
from itertools import groupby
from collections import deque
from .aoc import Aoc2, AocParseLines
"""
?###.??????? 3,2,1
1 2 3
? 0 0 0
# 0 0 0
# 1 0 0
# 2 0 0
. 2 0 0
? 2 0 0
? 2 3 0
? 2 4 0
? 2 5 2
? 2 6 3
"""
@dataclass
class Line:
@ -39,6 +22,17 @@ class Line:
return Line("." + springs + ".", springs_group, groups)
@classmethod
def from_str2(cls, inpt: str) -> Line:
springs, groups_str = inpt.split(" ")
springs = "?".join([springs] * 5)
groups = [int(d) for d in groups_str.split(",")]
groups = groups + groups + groups + groups + groups
springs_group = deque((len(list(d)), i) for i, d in groupby(springs))
return Line("." + springs + ".", springs_group, groups)
P1: TypeAlias = list[Line]
P2: TypeAlias = list[Line]
@ -49,7 +43,7 @@ class Day12(AocParseLines[Line, Line], Aoc2[P1, P2]):
return Line.from_str(inpt)
def parseline2(self, inpt: str) -> Line:
return Line.from_str(inpt)
return Line.from_str2(inpt)
@staticmethod
def fits(line: str, startpos: int, length: int) -> bool:
@ -58,25 +52,35 @@ class Day12(AocParseLines[Line, Line], Aoc2[P1, P2]):
starter = line[startpos - 1]
segment = line[startpos : startpos + length]
stopper = line[startpos + length]
return (
starter != "#"
and stopper != "#"
and (len(segment) >= length)
and ("." not in segment)
)
return starter != "#" and stopper != "#" and ("." not in segment)
def part1(self, inpt: P1) -> int:
accum = 0
# inpt = inpt[:1]
# print(inpt)
for line in inpt:
belegungen = [[0]]
for group in line.groups:
for i, group in enumerate(line.groups):
# print(f"{belegungen=}")
next_belegungen = []
for belegung in belegungen:
last_end = belegung[-1]
# print(f"{last_start=}, {last_end=}, {group=}, {len(line.springs)=}")
# try:
# first_hash = line.springs[last_end:].index("#") + 1
# # print("First hash", first_hash)
# except ValueError:
# first_hash = len(line.springs) - 1
for startvalue in range(last_end + 1, len(line.springs)):
# print(startvalue)
if "#" in line.springs[last_end:startvalue]:
continue
fits = self.fits(line.springs, startvalue, group)
if i == len(line.groups) - 1:
if "#" in line.springs[startvalue + group :]:
continue
if fits:
# print(f"Y {i=}, {startvalue=}, {group=}")
next_belegungen.append(belegung + [startvalue + group])
@ -84,24 +88,33 @@ class Day12(AocParseLines[Line, Line], Aoc2[P1, P2]):
# print(f"N {i=}, {startvalue=}, {group=}")
belegungen = next_belegungen
# print(belegungen)
# print(line.springs[1:-1], line.groups, len(belegungen))
# if len(belegungen) == 1:
# print(
# f"{line.springs=}, {line.groups=}, {[line.springs[x] for x in belegungen[0]]}"
# )
for belegung in belegungen:
last_belegung = belegung[-1]
if "#" in line.springs[last_belegung:]:
print(line.springs, line.groups)
if len(set((tuple(x) for x in belegungen))) != len(belegungen):
print("X")
# print(line.springs, line.groups)
for belegung in belegungen:
self.check_belegung(line, belegung)
accum += len(belegungen)
# print(len(belegungen))
# print(belegungen)
# print(belegungen)
print(accum)
return accum
def check_belegung(self, line, belegung):
if "#" in [line.springs[x] for x in belegung]:
print(f"Wron # in {line=}")
print(f"Wrong # in {line=}")
if len(belegung) != 1 + len(line.groups):
print(f"Groups Wrong in {line=}")
@ -110,13 +123,29 @@ class Day12(AocParseLines[Line, Line], Aoc2[P1, P2]):
if "." in b:
print("{line=}")
last_end = 0
bstr = "."
for ends, lengths in zip(belegung[1:], line.groups):
beginning = ends - lengths
bstr += "." * (beginning - len(bstr))
bstr += "#" * lengths
if (line.springs[beginning - 1] == "#") or line.springs[ends] == "#":
print("X")
if beginning - last_end < 1:
print("XXX")
last_end = ends
# print(bstr)
def part2(self, inpt: P2) -> int:
return 0
for line in inpt:
print(line)
return self.part1(inpt)
def main() -> None:
aoc = Day12(2023, 12, example_code_nr1=1, example_code_nr2=1)
aoc.run()
aoc.run_example_2()
if __name__ == "__main__":