69 lines
1.9 KiB
Common Lisp
69 lines
1.9 KiB
Common Lisp
;; https://adventofcode.com/2022/day/25
|
|
(defpackage :day-25
|
|
(:use :cl))
|
|
|
|
(in-package :day-25)
|
|
(ql:quickload 'alexandria)
|
|
|
|
(defun snafu-to-dec (snafu-alist)
|
|
(loop
|
|
for (pow . mul) in snafu-alist
|
|
sum (* mul (expt 5 pow))))
|
|
|
|
;; let's do that as alist as well?
|
|
(defparameter *snafu-char-to-mul*
|
|
'((#\2 . 2)
|
|
(#\1 . 1)
|
|
(#\0 . 0)
|
|
(#\- . -1)
|
|
(#\= . -2)))
|
|
|
|
(defun char-to-mul (char)
|
|
(alexandria:assoc-value *snafu-char-to-mul* char))
|
|
(defun mul-to-char (n)
|
|
(alexandria:rassoc-value *snafu-char-to-mul* n))
|
|
|
|
;; into the alist power representation
|
|
(defun read-snafu (str)
|
|
(loop
|
|
for char across (reverse (coerce str 'array))
|
|
for pow from 0
|
|
collect (cons pow (char-to-mul char))))
|
|
|
|
(defun decimal-to-pows-5 (num)
|
|
(let ((str (format nil "~5R" num)))
|
|
(loop
|
|
for char across (reverse (coerce str 'array))
|
|
for pow from 0
|
|
;; do (print char)
|
|
collect (cons pow (- (char-code char) (char-code #\0))))))
|
|
|
|
(defun pows-5-to-snafu (pows-5)
|
|
(let ((copied-list (copy-alist pows-5)))
|
|
(loop
|
|
for pow from 0 below (length pows-5)
|
|
when (> (alexandria:assoc-value copied-list pow) 2)
|
|
do (progn
|
|
(incf (cdr (assoc pow copied-list)) -5)
|
|
(when (not (assoc (1+ pow) copied-list))
|
|
(push (cons (1+ pow) 0) copied-list))
|
|
(incf (cdr (assoc (1+ pow) copied-list)))))
|
|
copied-list))
|
|
|
|
(defun snafu-pows-print (snafu-alist)
|
|
(coerce (loop
|
|
for pow from (1- (length snafu-alist)) downto 0
|
|
collect (mul-to-char (alexandria:assoc-value snafu-alist pow))
|
|
)
|
|
'string))
|
|
|
|
(defun decimal-to-snafu (num)
|
|
(pows-5-to-snafu (decimal-to-pows-5 num)))
|
|
|
|
(defun part-1-calc (filename)
|
|
(loop
|
|
for line in (uiop:read-file-lines filename)
|
|
for dec = (snafu-to-dec (read-snafu line))
|
|
summing dec into the-sum
|
|
finally (return (snafu-pows-print (decimal-to-snafu the-sum)))) )
|