From 3ad4d12ce108c7523bac1816f63034db13d53805 Mon Sep 17 00:00:00 2001 From: Mistivia Date: Mon, 4 Mar 2024 22:20:25 +0800 Subject: solve day 12 part 2 --- 12/2.rkt | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 12/2.rkt diff --git a/12/2.rkt b/12/2.rkt new file mode 100644 index 0000000..69bfdae --- /dev/null +++ b/12/2.rkt @@ -0,0 +1,93 @@ +#lang racket + +(require "../lib/utils.rkt") + +(define lines + (call-with-input-file "input" + (λ (fp) + (get-lines fp)))) + +(define (unfold-pattern x) + (append x (list #\?) x (list #\?) x (list #\?) x (list #\?) x)) + +(define (unfold-num x) + (append x x x x x)) + +(define (parse-line line) + (define line-splited (string-split line)) + (define arr-list (string->list (car line-splited))) + (define conds (map string->number (string-split (cadr line-splited) ","))) + (cons (reverse (cons #\. (reverse (unfold-pattern arr-list)))) (unfold-num conds))) + +(define (cont-lava scanned) + (define nums (filter (λ (n) (not (= 0 n))) + (map string-length (string-split scanned ".")))) + (if (null? nums) + #f + (car nums))) + +(define (can-match? scanned remain) + (if (null? scanned) + 'unknown + (if (char=? #\# (car scanned)) + 'unknown + (let () + (define num (cont-lava (list->string scanned))) + (if (not num) + 'unknown + (if (null? remain) + 'no + (if (= num (car remain)) + 'yes + 'no))))))) + +(define (check-terminal scanned remain) + (define can-match (can-match? scanned remain)) + (if (and (eq? 'yes can-match) + (null? (cdr remain))) + 1 + (if (eq? 'no can-match) + 0 + (if (null? remain) + 1 + 0)))) + +(define (possible-arr-num instance) + (define conds (cdr instance)) + (define (impl recur scanned unscanned remain) + (define can-match (can-match? scanned remain)) + (define (gen-next-scanned c lst) + (if (and (null? lst) (char=? c #\.)) + '() + (cons c lst))) + (if (null? unscanned) + (check-terminal scanned remain) + (if (eq? can-match 'no) + 0 + (let () + (define next-scanned + (if (eq? 'yes can-match) + '() + scanned)) + (define next-remain + (if (eq? 'yes can-match) + (cdr remain) + remain)) + (define head (car unscanned)) + (if (not (char=? head #\?)) + (recur recur (gen-next-scanned head next-scanned) (cdr unscanned) next-remain) + (+ (recur recur (gen-next-scanned #\. next-scanned) (cdr unscanned) next-remain) + (recur recur (gen-next-scanned #\# next-scanned) (cdr unscanned) next-remain))))))) + (define memo (make-hash)) + (define (memo-impl recur scanned unscanned remain) + (if (null? scanned) + (if (hash-has-key? memo (list unscanned remain)) + (hash-ref memo (list unscanned remain)) + (let () + (define ret (impl recur scanned unscanned remain)) + (hash-set! memo (list unscanned remain) ret) + ret)) + (impl recur scanned unscanned remain))) + (memo-impl memo-impl '() (car instance) conds)) + +(apply + (map possible-arr-num (map parse-line lines))) \ No newline at end of file -- cgit v1.0