aboutsummaryrefslogtreecommitdiff
path: root/14/1.rkt
blob: 79dcefc168b445c5ba85b74b03d8be313fecd49b (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
#lang racket

(require "../lib/utils.rkt")

(define lines
  (call-with-input-file "input"
    (λ (fp) (get-lines fp))))

(define mat (list->vector lines))

(define (char-at x y)
  (string-ref (vector-ref mat y) x))

(define (set-mat! x y c)
  (string-set! (vector-ref mat y) x c))

(define (move-stone x1 y1 x2 y2)
  (define t (char-at x1 y1))
  (set-mat! x1 y1 (char-at x2 y2))
  (set-mat! x2 y2 t))

(define (find-new-pos x y)
  (let loop ((new-y y))
    (if (or (= new-y 0)
            (not (char=? #\. (char-at x (- new-y 1)))))
        new-y
        (loop (- new-y 1)))))

(define height (vector-length mat))
(define width (string-length (vector-ref mat 0)))

(define (tilt)
  (let loop ((y 0))
    (if (>= y height)
        (void)
        (let ()
          (let loop1 ((x 0))
            (if (>= x width)
                (void)
                (let ()
                  (define c (char-at x y))
                  (if (char=? #\O c)
                      (let ()
                        (define new-y (find-new-pos x y))
                        (move-stone x y x new-y)
                        (loop1 (+ 1 x)))
                      (loop1 (+ 1 x))))))
          (loop (+ 1 y))))))

(define (count)
  (let loop ((x 0) (y 0) (sum 0))
    (if (>= y height)
        sum
        (if (>= x width)
            (loop 0 (+ 1 y) sum)
            (let ()
              (define c (char-at x y))
              (if (char=? c #\O)
                  (loop (+ 1 x) y (+ sum (- height y)))
                  (loop (+ 1 x) y sum)))))))

(tilt)
(count)