From 2d9cb2fb12833781a954818a66ba40679674ef5d Mon Sep 17 00:00:00 2001 From: Shahar Talmi Date: Tue, 12 Dec 2023 23:35:40 +0200 Subject: [PATCH] moved to nachshons solution --- src/2015/day22.js | 7 ++--- src/2023/day12.js | 67 +++++++++++++++++++++++------------------------ 2 files changed, 35 insertions(+), 39 deletions(-) diff --git a/src/2015/day22.js b/src/2015/day22.js index c64ed662..a64f2f4f 100644 --- a/src/2015/day22.js +++ b/src/2015/day22.js @@ -78,12 +78,9 @@ function playBoss(game) { function memoize(fn) { const memo = {}; - return function (x) { + return function (...x) { const s = JSON.stringify(x); - if (!memo[s]) { - memo[s] = fn(x); - } - return memo[s]; + return (memo[s] = memo[s] ?? fn(...x)); }; } diff --git a/src/2023/day12.js b/src/2023/day12.js index 7a134383..890bdf19 100644 --- a/src/2023/day12.js +++ b/src/2023/day12.js @@ -1,41 +1,39 @@ -function add(queue, next) { - const remain = (next.pattern.match(/[^.]/g) || []).length; - if (remain + next.buffer < next.counts.reduce((a, b) => a + b, 0)) return; +function memoize(fn) { + const memo = {}; + return function (...x) { + const s = JSON.stringify(x); + return (memo[s] = memo[s] ?? fn(...x)); + }; +} - const { pattern, counts, buffer } = next; - const queued = queue.map.get(JSON.stringify({ pattern, counts, buffer })); - if (queued) queued.x += next.x; - else { - queue.arr.push(next); - queue.map.set(JSON.stringify({ pattern, counts, buffer }), next); - } +function advance(options, char) { + const { len, groups, i, left } = options; + let update = {}; + if (char === '#') update = { len: len + 1, left: left - 1 }; + else if (len > 0) update = { len: 0, groups: [...groups, len] }; + return { ...options, ...update, i: i + 1 }; } -function solve(pattern, counts) { - let result = 0; - const queue = { arr: [], map: new Map() }; - add(queue, { pattern, counts, buffer: 0, x: 1 }); - while (queue.arr.length > 0) { - const next = queue.arr.shift(); - const { pattern, counts, buffer, x } = next; - const c = pattern[0]; - next.pattern = pattern.slice(1); - if (c === undefined) { - if (buffer === 0 && counts.length === 0) result += x; - if (buffer > 0 && buffer === counts[0] && counts.length === 1) - result += x; - } else if (buffer === 0) { - if (c !== '#') add(queue, { ...next, buffer: 0 }); - if (c !== '.') add(queue, { ...next, buffer: 1 }); - } else if (counts.length > 0) { - if (c !== '#' && buffer === counts[0]) - add(queue, { ...next, counts: counts.slice(1), buffer: 0 }); - if (c !== '.' && buffer !== counts[0]) - add(queue, { ...next, buffer: buffer + 1 }); - } +const solve = memoize((pattern, counts, options) => { + options = options || { groups: [], len: 0, i: 0 }; + options.left = options.left ?? counts.reduce((a, b) => a + b, 0); + + if (options.i >= pattern.length) { + if (options.len > 0) options.groups = [...options.groups, options.len]; + if (options.groups.length !== counts.length) return 0; + return options.groups.every((x, i) => x === counts[i]) ? 1 : 0; + } else { + if (options.groups.some((x, i) => x !== counts[i])) return 0; + if (options.len > counts[options.groups.length]) return 0; + if (options.left > pattern.length - options.i) return 0; } + + let result = 0; + const c = pattern[options.i]; + if (c !== '#') result += solve(pattern, counts, advance(options, '.')); + if (c !== '.') result += solve(pattern, counts, advance(options, '#')); return result; -} +}); export function part1(input) { return input @@ -49,7 +47,7 @@ export function part1(input) { } export function part2(input) { - return input + const x = input .split('\n') .map(line => { let [pattern, counts] = line.split(' '); @@ -60,4 +58,5 @@ export function part2(input) { return solve(pattern, counts); }) .reduce((a, b) => a + b); + return x; }