diff --git a/README.md b/README.md index ee20252..9bd71de 100644 --- a/README.md +++ b/README.md @@ -10,5 +10,5 @@ - Day 8: 25:00; I was doing pretty decent here. - Day 9: 57:00; my input parse function did not consider negative values... - Day 10: 180:00; this one was hard for me. -- Day 11: 68:00; okay but not elegant and way too slow ofc. -- Day 12: +- Day 11: 68:00; okay but not elegant and way too slow ofc; x-ray solution would have been neat +- Day 12: 52:00 and 22:00 for leaderboard; had the right idea and I am good at this type of problem diff --git a/d12.py b/d12.py index 2a533a0..8a80cf5 100644 --- a/d12.py +++ b/d12.py @@ -1,43 +1,69 @@ import lib +from functools import lru_cache EXAMPLE = """ +???.### 1,1,3 +.??..??...?##. 1,1,3 +?#?#?#?#?#?#?#? 1,3,1,6 +????.#...#... 4,1,1 +????.######..#####. 1,6,5 +?###???????? 3,2,1 """ -def solve(lines: list[str]): +@lru_cache +def count(elems, groups): + if not elems and not groups: + return 1 + elif elems and not groups: + if all(e in ['.', '?'] for e in elems): + return 1 + return 0 + elif not elems and groups: + return 0 + + r = 0 + if elems[0] in ['?', '.']: + r += count(elems[1:], groups) + + g = groups[0] + if len(elems) < g: + return 0 + + es, rest = elems[:g], elems[g:] + if all(e in ['?', '#'] for e in es) and (len(rest) == 0 or rest[0] in ['.', '?']): + r += count(rest[1:], groups[1:]) + return r + + +def solve(lines: list[str], repeat=1): + all = [] + for (_, line) in enumerate(lines): + springs, numbers = line.split() + numbers = tuple(lib.str_to_int_list(numbers)) + ns = "?".join([springs for _ in range(repeat)]) + all.append((tuple(ns), numbers * repeat)) + res = 0 - - # g = list(map(list, lines)) - # for (ri, r) in enumerate(g): - # for (ci, c) in enumerate(r): - # pass - - for (i, line) in enumerate(lines): - print(i, line) - # digits = lib.str_to_int_list(line) - # digit = lib.str_to_single_int(line) + for a in all: + # print(a, count(*a)) + res += count(*a) + # 28:00 + # 50:00 total return res -def solve2(lines: list[str]): - res = 0 - for (i, line) in enumerate(lines): - print(i, line) - return res def main(): lines = lib.str_to_lines_no_empty(EXAMPLE) print("Example 1:", solve(lines)) - return lines = lib.str_to_lines_no_empty(open("i12.txt").read()) print("Solution 1:", solve(lines)) - return lines = lib.str_to_lines_no_empty(EXAMPLE) - print("Example 2:", solve2(lines)) - return + print("Example 2:", solve(lines, 5)) lines = lib.str_to_lines_no_empty(open("i12.txt").read()) - print("Solution 2:", solve2(lines)) + print("Solution 2:", solve(lines, 5)) if __name__ == "__main__": main()