2023 day 12 in Guile
40.40s user 0.06s system 731% cpu 5.530 total
This commit is contained in:
parent
18bb954afd
commit
5bebefc587
|
@ -0,0 +1,6 @@
|
|||
???.### 1,1,3
|
||||
.??..??...?##. 1,1,3
|
||||
?#?#?#?#?#?#?#? 1,3,1,6
|
||||
????.#...#... 4,1,1
|
||||
????.######..#####. 1,6,5
|
||||
?###???????? 3,2,1
|
|
@ -0,0 +1,92 @@
|
|||
(use-modules (ice-9 textual-ports)
|
||||
(ice-9 format)
|
||||
(ice-9 threads)
|
||||
(srfi srfi-1)
|
||||
(srfi srfi-13))
|
||||
|
||||
(define (read-input)
|
||||
(get-string-all (current-input-port)))
|
||||
|
||||
(define (string-present? s)
|
||||
(not (string-null? s)))
|
||||
|
||||
(define (parse-input line)
|
||||
(map parse-line
|
||||
(filter string-present? (string-split line #\Newline))))
|
||||
|
||||
(define (parse-line line)
|
||||
(define (parse-number-list l)
|
||||
(map string->number (filter string-present? (string-split l #\,))))
|
||||
|
||||
(let* ((parts (string-split line #\Space))
|
||||
(springs (car parts))
|
||||
(numbers (cadr parts)))
|
||||
(list (string->list springs)
|
||||
(parse-number-list numbers))))
|
||||
|
||||
(define (expanded-option-count l g)
|
||||
(define cache (make-hash-table 4096))
|
||||
|
||||
(define (with-cache l g c)
|
||||
(let* ((cached (hash-ref cache (list l g c))))
|
||||
(if cached
|
||||
cached
|
||||
(let ((computed (inner l g c)))
|
||||
(hash-set! cache (list l g c) computed)
|
||||
computed))))
|
||||
|
||||
(define (inner l g c)
|
||||
(cond
|
||||
((and (null? l) (null? g)) 1)
|
||||
((and (null? l) (= c (car g)))
|
||||
(with-cache l (cdr g) 0))
|
||||
((null? l) 0)
|
||||
((char=? #\? (car l))
|
||||
(let ((calculated (+ (with-cache (cons #\# (cdr l)) g c)
|
||||
(with-cache (cons #\. (cdr l)) g c))))
|
||||
(hash-set! cache (list l g c) calculated)))
|
||||
((char=? #\. (car l))
|
||||
(cond
|
||||
((zero? c)
|
||||
(with-cache (cdr l) g c))
|
||||
((null? g)
|
||||
(with-cache (cdr l) g c))
|
||||
((= c (car g))
|
||||
(with-cache (cdr l) (cdr g) 0))
|
||||
(#t 0)))
|
||||
((char=? #\# (car l))
|
||||
(cond
|
||||
((null? g) 0)
|
||||
((>= c (car g)) 0)
|
||||
(#t (with-cache (cdr l) g (+ 1 c)))))))
|
||||
|
||||
(inner l g 0))
|
||||
|
||||
(define (part1 input)
|
||||
(reduce + 0
|
||||
(par-map
|
||||
(lambda (row) (expanded-option-count (car row) (cadr row)))
|
||||
input)))
|
||||
|
||||
(define (intersperse l s)
|
||||
(let loop ((c (car l))
|
||||
(l (cdr l))
|
||||
(acc '()))
|
||||
(cond
|
||||
((and (null? c) (null? l)) (reverse acc))
|
||||
((null? c) (loop (car l) (cdr l) (cons s acc)))
|
||||
(#t (loop (cdr c) l (cons (car c) acc))))))
|
||||
|
||||
(define (repeat n l)
|
||||
(map (lambda (x) l) (iota n)))
|
||||
|
||||
(define (part2 input)
|
||||
(define (expand-row row)
|
||||
(list (intersperse (repeat 5 (car row)) #\?)
|
||||
(concatenate (repeat 5 (cadr row)))))
|
||||
|
||||
(part1 (map expand-row input)))
|
||||
|
||||
(let ((input (parse-input (read-input))))
|
||||
(format #t "Part 1: ~a~%" (part1 input))
|
||||
(format #t "Part 2: ~a~%" (part2 input)))
|
Loading…
Reference in New Issue