summaryrefslogtreecommitdiffstats
path: root/2021/13/code.tl
blob: f222e2761d4bbc8ccc54d24a94e84c3ff7925976 (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
(defstruct board ()
  (w 0)
  (h 0)
  (a (hash))

  (:method print (bo stream pretty-p)
    (put-line `board @{bo.w}x@{bo.h}:`)
    (each ((y 0..bo.h))
      (each ((x 0..bo.w))
        (put-char (if [bo x y] #\# #\space) stream))
      (put-line)))

  (:method lambda (bo x y)
    [(or [bo.a y] nil) x])

  (:method lambda-set (bo x y nv)
    (let ((row (or [bo.a y]
                   (set [bo.a y] (hash)))))
      (set [row x] nv)
      (upd bo.h (max (succ y)))
      (upd bo.w (max (succ x)))))

  (:method fold-y (bo yline)
    (let ((a bo.a))
      (del [a yline])
      (set bo.h yline)
      (dohash (y row a bo)
        (when (> y yline)
          (let ((ry (- (* 2 yline) y)))
            (if [a ry]
              (set [a ry]
                   [hash-uni [a ry] [a y] or])
              (set [a ry] row)))
          (del [a y])))))

  (:method fold-x (bo xline)
    (let ((a bo.a))
      (dohash (y row a bo)
        (each ((x (succ xline)..bo.w))
          (when [row x]
            (set [row (- (* 2 xline) x)] t)
            (del [row x])))))
    (set bo.w xline))

  (:method count (bo)
    (let ((count 0))
      (dohash (y row bo.a count)
        (dohash (x v row)
          (if v (inc count)))))))

(defun solve-two (: (name "input"))
  (let ((bo (new board)))
    (each ((line (file-get-lines name)))
      (match-case line
        (`@x,@y` (set [bo (toint x) (toint y)] t))
        (`fold along x=@x` bo.(fold-x (toint x)))
        (`fold along y=@y` bo.(fold-y (toint y)))))
    (print bo)
    nil))