src/2018/day-14.lisp @ 5668f7ed5c2d

Day 14
author Steve Losh <steve@stevelosh.com>
date Sun, 16 Dec 2018 22:50:57 -0500
parents (none)
children 5b5c61ad8d2b
(defpackage :advent/2018/14 #.cl-user::*advent-use*)
(in-package :advent/2018/14)

(defun combine (recipes elves)
  (digits (summation elves :key (curry #'aref recipes)) :from-end t))

(defun move-elves (recipes elves)
  (do-array (elf elves)
    (setf elf (mod (+ elf (aref recipes elf) 1)
                   (length recipes)))))

(defun format-output (scores)
  (str:join "" (coerce scores 'list)))

(define-problem (2018 14) (data read)
  #+sbcl (sb-ext:gc :full t)
  (iterate
    (with recipes = (make-array 2
                      :adjustable t
                      :fill-pointer t
                      :initial-contents '(3 7)))
    (with elves = (make-array 2 :initial-contents '(0 1)))
    (with part-1 = nil)
    (with part-2 = nil)
    (with target = (digits data :from-end t :result-type 'vector))
    (with target-length = (length target))

    (until (and part-1 part-2))

    (unless part-1
      (when (>= (length recipes) (+ 10 data))
        (setf part-1 (format-output (subseq recipes data (+ data 10))))))

    (iterate (for new-recipe :in (combine recipes elves))
             (vector-push-extend new-recipe recipes)
             (for len = (length recipes))
             (for left = (- len target-length))
             (unless part-2
               (when (and (not (minusp left))
                          (search target recipes :start2 left))
                 (setf part-2 left))))

    (move-elves recipes elves)

    (finally (return (values part-1 part-2)))))

(1am:test test-2018/14
  (multiple-value-bind (part1 part2) (run)
    (1am:is (string= "3610281143" part1))
    (1am:is (= 20211326 part2))))