Advent-of-Code/day25.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)))) )