87 lines
3.1 KiB
Scheme
87 lines
3.1 KiB
Scheme
(import (chicken io)
|
|
(chicken format)
|
|
srfi-1
|
|
srfi-42
|
|
srfi-69
|
|
srfi-152
|
|
matchable)
|
|
|
|
(define (parse-line s)
|
|
(map (lambda (c) (eq? c #\#)) (string->list s)))
|
|
|
|
(define (read-input #!optional (port (current-input-port)))
|
|
(let* ((lines (read-lines port))
|
|
(algo (list->vector (parse-line (car lines))))
|
|
(img (map parse-line (cddr lines)))
|
|
(h (make-hash-table)))
|
|
(do-ec (: line (index i) img)
|
|
(: x (index j) line)
|
|
(if x)
|
|
(hash-table-set! h (list i j) #t))
|
|
(values algo h #f)))
|
|
|
|
(define (kernel img bg i j)
|
|
(fold-ec 0 (: k (- i 1) (+ i 2)) (: l (- j 1) (+ j 2))
|
|
(hash-table-ref/default img (list k l) bg)
|
|
(lambda (n acc) (+ (* 2 acc) (if n 1 0)))))
|
|
|
|
(define (enhance algo img bg)
|
|
(let* ((indices (hash-table-keys img))
|
|
(min-i (hash-table-fold img (lambda (k v acc) (min (car k) acc)) 0))
|
|
(max-i (hash-table-fold img (lambda (k v acc) (max (car k) acc)) 0))
|
|
(min-j (hash-table-fold img (lambda (k v acc) (min (cadr k) acc)) 0))
|
|
(max-j (hash-table-fold img (lambda (k v acc) (max (cadr k) acc)) 0))
|
|
(new-img (make-hash-table))
|
|
(new-bg (vector-ref algo (if bg 511 0))))
|
|
(do-ec (:range i (- min-i 1) (+ max-i 2))
|
|
(:range j (- min-j 1) (+ max-j 2))
|
|
(:let pixel (vector-ref algo (kernel img bg i j)))
|
|
(hash-table-set! new-img (list i j) pixel))
|
|
(values new-img new-bg)))
|
|
|
|
(define (count-pixels img)
|
|
(hash-table-fold img (lambda (k v acc) (if v (+ 1 acc) acc)) 0))
|
|
|
|
(define (part12 algo img bg times)
|
|
(if (zero? times)
|
|
(count-pixels img)
|
|
(let-values (((img bg) (enhance algo img bg)))
|
|
;; (with-output-to-file (sprintf "imgs/img~a.pbm" times)
|
|
;; (lambda () (img->pbm img bg)))
|
|
(part12 algo img bg (sub1 times)))))
|
|
|
|
(let-values (((algo img bg) (read-input)))
|
|
(print (part12 algo img bg 2))
|
|
(print (part12 algo img bg 50)))
|
|
|
|
(define (visualize img bg)
|
|
(let* ((indices (hash-table-keys img))
|
|
(min-i (hash-table-fold img (lambda (k v acc) (min (car k) acc)) 0))
|
|
(max-i (hash-table-fold img (lambda (k v acc) (max (car k) acc)) 0))
|
|
(min-j (hash-table-fold img (lambda (k v acc) (min (cadr k) acc)) 0))
|
|
(max-j (hash-table-fold img (lambda (k v acc) (max (cadr k) acc)) 0)))
|
|
(do-ec (:range i (index k) (- min-i 1) (+ max-i 2))
|
|
(:range j (index l) (- min-j 1) (+ max-j 2))
|
|
(begin
|
|
(when (and (not (= k 0)) (= l 0)) (display "\n"))
|
|
(if (hash-table-ref/default img (list i j) bg)
|
|
(display "#")
|
|
(display "."))))
|
|
(display "\n")))
|
|
|
|
(define (img->pbm img bg)
|
|
(let* ((indices (hash-table-keys img))
|
|
(min-i (hash-table-fold img (lambda (k v acc) (min (car k) acc)) 0))
|
|
(max-i (hash-table-fold img (lambda (k v acc) (max (car k) acc)) 0))
|
|
(min-j (hash-table-fold img (lambda (k v acc) (min (cadr k) acc)) 0))
|
|
(max-j (hash-table-fold img (lambda (k v acc) (max (cadr k) acc)) 0)))
|
|
(printf "P1 ~a ~a~n" (+ 2 (- max-i min-i)) (+ 2 (- max-j min-j)))
|
|
(do-ec (:range i (index k) (- min-i 1) (+ max-i 2))
|
|
(:range j (index l) (- min-j 1) (+ max-j 2))
|
|
(begin
|
|
(when (and (not (= k 0)) (= l 0)) (display "\n"))
|
|
(if (hash-table-ref/default img (list i j) bg)
|
|
(display "1")
|
|
(display "0"))))
|
|
(display "\n")))
|
|
|