solve day22 part 1 and 2

This commit is contained in:
Peter Tillemans 2024-12-22 13:46:27 +01:00
parent a327aef2bf
commit 28881608de
2 changed files with 120 additions and 17 deletions

View file

@ -1,18 +1,20 @@
(defpackage :aoc/2024/22 (defpackage :aoc/2024/22
(:use :cl :aoc :alexandria :trivia :lla) (:use :cl :aoc :alexandria :lla :arrow-macros)
(:export (:export
#:sample-data #:sample-data
#:sample-data2 #:sample-data2
#:part1 #:part1
#:part2 #:part2
#:next-random
#:repeat-random
)) ))
(in-package :aoc/2024/22) (in-package :aoc/2024/22)
(defun parse-line (line) (defun parse-line (line)
line) (parse-integer line))
(defun parse-input (lines) (defun parse-input (lines)
@ -21,15 +23,99 @@
(defparameter input-text (test-input 2024 22)) (defparameter input-text (test-input 2024 22))
(defparameter input-data (parse-input input-text)) (defparameter input-data (parse-input input-text))
(defparameter sample-text (aoc:split-lines "")) (defparameter sample-text (aoc:split-lines "1
10
100
2024
"))
(defparameter sample-data (defparameter sample-data
(parse-input sample-text)) (parse-input sample-text))
(defparameter PRUNE (ash 1 24))
(defun rnd-step (n d)
(mod (logxor n (ash n d)) PRUNE))
(defun next-random (n)
(-> n
(rnd-step 6)
(rnd-step -5)
(rnd-step 11)))
(defun repeat-random (seed n)
(loop
for i from 1 to n
do (setf seed (next-random seed))
finally (return seed)))
(defun part1 (data) (defun part1 (data)
(length data)) (loop
for buyer in data
sum (repeat-random buyer 2000)))
(defun day-prices (seed)
(make-array '(2001)
:initial-contents
(loop
for i from 1 to 2001
collect (mod seed 10)
do (setf seed (next-random seed))
)
))
(defun sum-table (a b)
(loop
for i from 0 below (array-total-size a)
for x = (aref b i)
if (plusp x)
do (incf (aref a i) x))
as)
(defun make-diff (prices)
(let ((diffs (copy-array prices)))
(loop
for i from 1 below (array-dimension prices 0)
do (decf (aref diffs i) (aref prices (1- i))))
diffsG))
(defun make-buyer-table (seed)
(let* ((prices (day-prices seed))
(diffs (make-diff prices))
(buyer-table (make-array (list 19 19 19 19) :initial-element -1)))
(loop
for i from 4 below (array-dimension prices 0)
for p = (aref prices i)
for d1 = (+ 9 (aref diffs i))
for d2 = (+ 9 (aref diffs (1- i)))
for d3 = (+ 9 (aref diffs (- i 2)))
for d4 = (+ 9 (aref diffs (- i 3)))
for bp = (aref buyer-table d1 d2 d3 d4)
if (minusp bp)
do (setf (aref buyer-table d1 d2 d3 d4) p))
buyer-table))
(defun price-diff-table (seeds)
(let ((table (make-array (list 19 19 19 19) :initial-element 0)))
(loop
for buyer from 0
for s in seeds
do (sum-table table (make-buyer-table s)))
table))
(defun maxtable (table)
(loop
for i from 0 below (array-total-size table)
maximize (row-major-aref table i)))
(defparameter sample-data2 '(1 2 3 2024))
(defun part2 (data) (defun part2 (data)
(length data)) (maxtable (price-diff-table data)))
(defun solve-day () (defun solve-day ()
(format t "part1: ~A~%" (part1 input-data)) (format t "part1: ~A~%" (part1 input-data))

View file

@ -7,21 +7,38 @@
;:parent suite-2024 ;:parent suite-2024
) )
(define-test test-foo (define-test test-next-random
:parent suite-2024-22 :parent suite-2024-22
) (let ((rnd 123))
(loop
for expected in '(15887950
16495136
527345
704524
1553684
12683156
11100544
12249484
7753432
5908254)
do (setf rnd (next-random rnd))
do (is = expected rnd))))
(define-test test-bar (define-test test-buyers-end-of-day
:parent suite-2024-22 :parent suite-2024-22
) (loop
for buyer in '((1 . 8685429)
(10 . 4700978)
(100 . 15273692)
(2024 . 8667524))
do (is = (cdr buyer) (repeat-random (car buyer) 2000))))
(define-test+run test-part1 (define-test+run test-part1
:parent suite-2024-22 :parent suite-2024-22
(is equal nil (part1 sample-data))) (is equal 37327623 (part1 sample-data)))
(define-test+run test-part2 (define-test+run test-part2
:parent suite-2024-22 :parent suite-2024-22
(is equal nil (part2 sample-data))) (is equal 23 (part2 sample-data2)))