aboutsummaryrefslogtreecommitdiff
path: root/day10.scm
blob: 516331a7aa9041753386008ad4e2ab4f7f7e0ed0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
(define-module (day10)
	       #:use-module (ice-9 rdelim)
	       #:use-module (srfi srfi-1))

(define (read-input port)
  (define (iter acc)
    (define line (read-line port))
    (if (or (eof-object? line) (string= "" line))
      (list->typed-array 'u8 2 (reverse acc))
      (iter (cons (map
		    (lambda (c) (- (char->integer c) (char->integer #\0)))
		    (string->list line))
		  acc))))
  (iter '()))

(define (dp! inp mp num join cellinit)
  (define-values (m n) (apply values (array-dimensions inp)))
  (unless (negative? num)
   (let iter-row ((i 0))
     (unless (= i m)
       (let iter-cell ((j 0))
	 (unless (= j n)
	   (when (= num (array-ref inp i j))
	     (array-set! 
	       mp
	       (fold (lambda (di dj acc)
		       (if (and (array-in-bounds? inp (+ i di) (+ j dj))
				(= (+ 1 num) (array-ref inp (+ i di) (+ j dj))))
			 (join
				  acc (array-ref mp (+ i di) (+ j dj)))
			 acc))
		     cellinit
		     '(1 -1 0 0) '(0 0 1 -1))
	       i j))
	   (iter-cell (+ j 1))))
       (iter-row (+ i 1))))
   (dp! inp mp (- num 1) join cellinit)))

(define (doit port score join cellinit 9init)
  (define inp (read-input port))
  (define-values (m n) (apply values (array-dimensions inp)))
  (define mp (make-array 0 m n))
  (define idx 0)
  (array-map! mp (lambda (s) (if (= s 9) (9init) cellinit)) inp)
  (dp! inp mp 8 join cellinit)
  ;(display mp)
  (let iter-row ((i 0) (acc 0))
    (if (= i m)
      acc
      (iter-row (+ i 1)
		(let iter-cell ((j 0) (acc acc))
		  (if (= j n)
		    acc
		    (iter-cell (+ j 1)
			       (+ acc (if (= (array-ref inp i j) 0)
					(score (array-ref mp i j))
					0)))))))))

(define (part1 port)
  (define idx 0)
  (doit port length (lambda (a b) (lset-union = a b))
	'()
(lambda () (set! idx (+ idx 1)) (list idx))))

(define (part2 port)
  (doit port values + 0 (lambda () 1)))