aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2022/25/solver.lisp
blob: 9b9495675de54bf343aee39a982ddc4a69aa47ed (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
(ql:quickload '(fiveam uiop))

(defconstant +num-encoding+
  '((2 . #\2)
    (1 . #\1)
    (0 . #\0)
    (-1 . #\-)
    (-2 . #\=)))

(defun encode-char (c)
  (cdr (assoc c +num-encoding+)))

(defun decode-char (c)
  (car (rassoc c +num-encoding+)))

(defun parse-snafu (num)
  (loop for a across (reverse num)
        for pow = 1 then (* pow 5)
        sum (* pow (decode-char a))))

(defun write-snafu (num &optional coeffs)
  (if (zerop num)
      (concatenate 'string coeffs)
      (multiple-value-bind (div rest) (floor num 5)
        (if (> rest 2)
            (write-snafu (1+ div) (cons (encode-char (- rest 5)) coeffs))
            (write-snafu     div  (cons (encode-char    rest)    coeffs))))))

(defun solver (filename)
  (write-snafu (apply #'+ (mapcar #'parse-snafu (uiop:read-file-lines filename)))))

(fiveam:test solutions
  (fiveam:is (string= "2=-1=0" (solver "eg-in")))
  (fiveam:is (string= "2-212-2---=00-1--102" (solver "input"))))