67 lines
1.9 KiB
Python
67 lines
1.9 KiB
Python
from dataclasses import dataclass
|
|
from typing import NamedTuple, NewType
|
|
import re
|
|
|
|
|
|
def im_replace(line: str, mask: str) -> str:
|
|
idx = 0
|
|
new_line = ""
|
|
for c in line:
|
|
if c != "?":
|
|
new_line += c
|
|
else:
|
|
new_line += mask[idx]
|
|
idx += 1
|
|
return new_line
|
|
|
|
|
|
class SpringLine(NamedTuple):
|
|
line: str
|
|
groups: tuple[int, ...]
|
|
|
|
def arrangments(self) -> list[str]:
|
|
count_im = self.line.count("?")
|
|
print(count_im)
|
|
possibles = []
|
|
for i in range(pow(2, count_im)):
|
|
rep_str = f"{i:b}".rjust(count_im, "0").replace("0", ".").replace("1", "#")
|
|
print(rep_str, end=" / ")
|
|
tentative = im_replace(self.line, rep_str)
|
|
possible = SpringLine(tentative, self.groups)
|
|
print(possible, end=": ")
|
|
if possible.is_valid():
|
|
possibles.append(im_replace(self.line, rep_str))
|
|
print("valid")
|
|
else:
|
|
print("invalid")
|
|
return possibles
|
|
|
|
def is_valid(self) -> bool:
|
|
# TODO: correct this (re.match with generated pattern based en groups)
|
|
line_copy = self.line
|
|
|
|
for group in self.groups:
|
|
idx = line_copy.find("#" * group)
|
|
if idx == -1:
|
|
return False
|
|
line_copy = line_copy[idx + group :]
|
|
return True
|
|
|
|
|
|
Spring = NewType("Spring", list[SpringLine])
|
|
|
|
|
|
def parse(input_file: str) -> Spring:
|
|
spring_lines = []
|
|
with open(input_file, "r", encoding="utf-8") as inputfd:
|
|
while line := inputfd.readline():
|
|
if match := re.match("([?#.]+)\s([0-9,]+)", line):
|
|
# print(match.group(0))
|
|
spring_lines.append(
|
|
SpringLine(
|
|
match.group(1),
|
|
tuple(map(lambda c: int(c), match.group(2).split(","))),
|
|
)
|
|
)
|
|
return Spring(spring_lines)
|