Day 12 - still unfinished

This commit is contained in:
Stefan Harmuth 2023-12-12 16:59:43 +01:00
parent 7089224009
commit d9a9209d76

117
day12.py
View File

@ -1,64 +1,6 @@
import re
from tools.aoc import AOCDay from tools.aoc import AOCDay
from tools.int_seq import triangular from tools.int_seq import triangular
from typing import Any, Iterable from typing import Any
def is_Valid(springs: str, groups: list[int]) -> bool:
foo = []
h_count = 0
for c in springs:
if c == "#":
h_count += 1
elif h_count > 0:
foo.append(h_count)
h_count = 0
if h_count > 0:
foo.append(h_count)
return foo == groups
def sums(length: int, total_sum: int) -> Iterable[tuple]:
if length == 1:
yield (total_sum,)
else:
for v in range(total_sum + 1):
for p in sums(length - 1, total_sum - v):
yield (v,) + p
def get_options(groups: list[int], fill: list[int]) -> Iterable[str]:
missing_len = sum(fill)
print("fill_len", len(fill), "miss_len", missing_len)
for opt in sums(len(fill), missing_len):
ret = ""
for i, c in enumerate(opt):
if 0 < i < len(fill) - 1 and c == 0:
break
ret += " " * c
if i < len(groups):
ret += "#" * groups[i]
else:
yield ret
def _get_arrangements(springs: str, groups: list[int]) -> int:
arrangements = 0
springs = springs.replace(".", " ")
after_fill = len(springs) - sum(groups) - len(groups) + 1
if after_fill == 0:
return 1
fill = [0] + [1] * (len(groups) - 1) + [after_fill]
p = re.compile(springs.replace("?", "."))
for s in get_options(groups, fill):
if p.match(s):
arrangements += 1
return arrangements
def get_arrangements(springs: str, groups: list[int]): def get_arrangements(springs: str, groups: list[int]):
@ -67,14 +9,16 @@ def get_arrangements(springs: str, groups: list[int]):
open_groups = get_open_groups(springs) open_groups = get_open_groups(springs)
to_determine = [] to_determine = []
for start, group_str in open_groups: for start, group_str in open_groups:
print("look in", group_str, "for", [groups[x] for x in not_found]) print("look in", group_str, "for", [groups[x[2]] for x in not_found])
assigned = [] assigned = []
for need in list(not_found): for min_x, max_x, idx_need in list(not_found):
print("check", need, groups[need]) print("check", min_x, "<", start, "<", max_x, idx_need, groups[idx_need])
if groups[need] > len(group_str): if groups[idx_need] > len(group_str):
continue continue
elif not assigned or sum(assigned) + len(assigned) + groups[need] <= len(group_str): elif (not assigned or sum(assigned) + len(assigned) + groups[idx_need] <= len(group_str)) and (
assigned.append(groups[need]) min_x <= start <= max_x
):
assigned.append(groups[idx_need])
not_found = not_found[1:] not_found = not_found[1:]
else: else:
break break
@ -126,26 +70,51 @@ def clean_springs(springs: str, groups: list[int]) -> (str, list[int]):
hashes.append((start, c_size)) hashes.append((start, c_size))
print("cleaning", springs, "with hashes", hashes, "and groups", groups) print("cleaning", springs, "with hashes", hashes, "and groups", groups)
found = [] found = {}
for i, s in enumerate(groups): for i, s in enumerate(groups):
for h in hashes: for h in hashes:
if h[0] >= sum(groups[:i]) + i and h[0] <= len(springs) - (sum(groups[i:]) + len(groups) - i) + 1: if h[0] >= sum(groups[:i]) + i and h[0] <= len(springs) - (sum(groups[i:]) + len(groups) - i) + 1:
print(h[0], ">", sum(groups[:i]) + i) # print(h[0], ">", sum(groups[:i]) + i)
print(h[0], "<", len(springs) - (sum(groups[i:]) + len(groups) - i) + 1) # print(h[0], "<", len(springs) - (sum(groups[i:]) + len(groups) - i) + 1)
if h[1] == s: if h[1] == s:
found.append(i) found[i] = (h[0], s)
if i == 0: if h[0] == 0:
springs = "#" * h[1] + "." + springs[h[0] + h[1] + 1 :] springs = "#" * h[1] + "." + springs[h[0] + h[1] + 1 :]
elif i == len(springs) - 1: elif h[0] + h[1] == len(springs):
springs = springs[: -(h[0] + h[1] + 1)] + "." + "#" * h[1] springs = springs[: -(h[1] + 1)] + "." + "#" * h[1]
else: else:
springs = springs[: h[0] - 1] + "." + "#" * h[1] + "." + springs[h[0] + h[1] + 1 :] springs = springs[: h[0] - 1] + "." + "#" * h[1] + "." + springs[h[0] + h[1] + 1 :]
print("found index", i, "value", groups[i], "at", h[0], "new springs", springs) print(
"found index",
i,
"value",
groups[i],
"at",
h[0],
"new springs",
springs,
)
break break
print("cleaned springs", springs, "found", found) print("cleaned springs", springs, "found", found)
not_found = []
# not_found entry = (min_x, max_x, index)
nf = []
last_min = 0
for i in range(len(groups)):
if i in found:
if nf:
for x in nf:
not_found.append((last_min, found[i][0], x))
nf = []
last_min = sum(found[i])
else:
nf.append(i)
if nf:
for x in nf:
not_found.append((last_min, len(springs), x))
return springs, [x for x in range(len(groups)) if x not in found] return springs, not_found
def get_open_groups(springs: str) -> list[tuple[int, str]]: def get_open_groups(springs: str) -> list[tuple[int, str]]: