From d9a9209d76ff48bebe5281111ced06c3d2798042 Mon Sep 17 00:00:00 2001 From: Stefan Harmuth Date: Tue, 12 Dec 2023 16:59:43 +0100 Subject: [PATCH] Day 12 - still unfinished --- day12.py | 117 ++++++++++++++++++++----------------------------------- 1 file changed, 43 insertions(+), 74 deletions(-) diff --git a/day12.py b/day12.py index 7470b33..2fce487 100644 --- a/day12.py +++ b/day12.py @@ -1,64 +1,6 @@ -import re from tools.aoc import AOCDay from tools.int_seq import triangular -from typing import Any, Iterable - - -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 +from typing import Any 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) to_determine = [] 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 = [] - for need in list(not_found): - print("check", need, groups[need]) - if groups[need] > len(group_str): + for min_x, max_x, idx_need in list(not_found): + print("check", min_x, "<", start, "<", max_x, idx_need, groups[idx_need]) + if groups[idx_need] > len(group_str): continue - elif not assigned or sum(assigned) + len(assigned) + groups[need] <= len(group_str): - assigned.append(groups[need]) + elif (not assigned or sum(assigned) + len(assigned) + groups[idx_need] <= len(group_str)) and ( + min_x <= start <= max_x + ): + assigned.append(groups[idx_need]) not_found = not_found[1:] else: break @@ -126,26 +70,51 @@ def clean_springs(springs: str, groups: list[int]) -> (str, list[int]): hashes.append((start, c_size)) print("cleaning", springs, "with hashes", hashes, "and groups", groups) - found = [] + found = {} for i, s in enumerate(groups): for h in hashes: 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], "<", len(springs) - (sum(groups[i:]) + len(groups) - i) + 1) + # print(h[0], ">", sum(groups[:i]) + i) + # print(h[0], "<", len(springs) - (sum(groups[i:]) + len(groups) - i) + 1) if h[1] == s: - found.append(i) - if i == 0: + found[i] = (h[0], s) + if h[0] == 0: springs = "#" * h[1] + "." + springs[h[0] + h[1] + 1 :] - elif i == len(springs) - 1: - springs = springs[: -(h[0] + h[1] + 1)] + "." + "#" * h[1] + elif h[0] + h[1] == len(springs): + springs = springs[: -(h[1] + 1)] + "." + "#" * h[1] else: 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 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]]: