;; 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)))) )