src/2017/days/day-17.lisp @ 4febe2904f45
2017/18 part 2
| author | Steve Losh <steve@stevelosh.com> |
|---|---|
| date | Fri, 06 Dec 2019 23:23:26 -0500 |
| parents | 2078ac8647c6 |
| children | 182bdd87fd9e |
(defpackage :advent/2017/17 #.cl-user::*advent-use*) (in-package :advent/2017/17) (defun-inline spin (ring shift n) (iterate (for i :from 1 :to n) (ring-movef ring shift) (ring-insertf-after ring i)) ring) (defun simple-part-2 (shift) (-<> (ring 0) (spin <> shift 50000000) (ring-find <> 0) ring-next ring-data)) (defun fast-part-2 (shift) (declare (optimize speed (debug 1) (safety 1))) (check-type shift fixnum) ;; Hack: the only actual value we care about is the one that's after 0, so we ;; don't actually have to store a list of the rest. We can just compute the ;; offset of where we *would* insert into the list, and keep track of the last ;; value we set index 1 to. (iterate (declare (iterate:declare-variables)) (with result) (for (the fixnum size) :from 1) (for (the fixnum val) :from 1 :to 50000000) (for (the fixnum pos) :seed 0 :then (1+ (mod (+ pos shift) size))) (when (= 1 pos) (setf result val)) (returning result))) (define-problem (2017 17) (data read) (1244 11162912) (values (-<> (ring 0) (spin <> data 2017) ring-next ring-data) (fast-part-2 data)))