day 10 part 2 in common lisp
This commit is contained in:
parent
11756bd23e
commit
a8dec662b5
|
@ -25,15 +25,26 @@
|
||||||
|
|
||||||
(in-package :advent-of-code-day-10)
|
(in-package :advent-of-code-day-10)
|
||||||
|
|
||||||
(defun signal-strength-at-cycle (instructions cycle)
|
(defun register-value-at-cycle (instructions cycle)
|
||||||
(iter (for instruction in instructions)
|
(iter (for instruction in instructions)
|
||||||
(for noop? = (not (consp instruction)))
|
(for noop? = (not (consp instruction)))
|
||||||
(for counter initially 1 then (+ counter (if noop? 1 2)))
|
(for counter initially 1 then (+ counter (if noop? 1 2)))
|
||||||
(for register initially 1 then (if noop? register (+ register (cdr instruction))))
|
(for register initially 1 then (if noop? register (+ register (cdr instruction))))
|
||||||
(for previous-counter previous counter)
|
(for previous-register-value previous register)
|
||||||
(for previous-register previous register)
|
|
||||||
(when (> counter cycle)
|
(when (> counter cycle)
|
||||||
(return (* cycle previous-register)))))
|
(return (if (first-iteration-p)
|
||||||
|
1
|
||||||
|
previous-register-value)))
|
||||||
|
(finally (return register))))
|
||||||
|
|
||||||
|
(defun signal-strength-at-cycle (instructions cycle)
|
||||||
|
(* (register-value-at-cycle instructions cycle) cycle))
|
||||||
|
|
||||||
|
(defun sprite-intersects? (pixel sprite)
|
||||||
|
(let ((sprite-start (- sprite 1))
|
||||||
|
(sprite-end (+ sprite 1)))
|
||||||
|
(and (>= pixel sprite-start)
|
||||||
|
(<= pixel sprite-end))))
|
||||||
|
|
||||||
(defun parse-input (lines)
|
(defun parse-input (lines)
|
||||||
(iter (for line in lines)
|
(iter (for line in lines)
|
||||||
|
@ -41,6 +52,25 @@
|
||||||
:noop
|
:noop
|
||||||
(cons :addx (parse-integer (cadr (str:split " " line))))))))
|
(cons :addx (parse-integer (cadr (str:split " " line))))))))
|
||||||
|
|
||||||
|
(defun solution-part-2 (instructions)
|
||||||
|
(iter (with screen = (make-array '(6 40) :element-type 'character :initial-element #\.))
|
||||||
|
(for cycle from 1 to 240)
|
||||||
|
(for register = (register-value-at-cycle instructions cycle))
|
||||||
|
(for x = (mod (- cycle 1) 40))
|
||||||
|
(for (values y nil) = (floor (- cycle 1) 40))
|
||||||
|
(when (sprite-intersects? x register)
|
||||||
|
(setf (aref screen y x) #\#))
|
||||||
|
(finally (return screen))))
|
||||||
|
|
||||||
|
(defun print-screen (screen stream)
|
||||||
|
(iter (for y from 0 to 5)
|
||||||
|
(iter (for x from 0 to 39)
|
||||||
|
(format stream "~a" (aref screen y x)))
|
||||||
|
(format stream "~%")))
|
||||||
|
|
||||||
|
|
||||||
|
;; test cases
|
||||||
|
|
||||||
(let ((input (parse-input (read-file-lines "example.txt"))))
|
(let ((input (parse-input (read-file-lines "example.txt"))))
|
||||||
(assert (= 420 (signal-strength-at-cycle input 20)))
|
(assert (= 420 (signal-strength-at-cycle input 20)))
|
||||||
(assert (= 1140 (signal-strength-at-cycle input 60)))
|
(assert (= 1140 (signal-strength-at-cycle input 60)))
|
||||||
|
@ -55,6 +85,20 @@
|
||||||
(assert (= 14320 (iter (for cycle from 20 to 240 by 40)
|
(assert (= 14320 (iter (for cycle from 20 to 240 by 40)
|
||||||
(sum (signal-strength-at-cycle input cycle))))))
|
(sum (signal-strength-at-cycle input cycle))))))
|
||||||
|
|
||||||
|
|
||||||
|
;; this puzzle relies on visual confirmation to determine whether its correct or not
|
||||||
|
;; so we just print the result to the terminal
|
||||||
|
|
||||||
|
(let* ((input (parse-input (read-file-lines "example.txt")))
|
||||||
|
(screen (solution-part-2 input)))
|
||||||
|
(format t "~&~%screen for example input~%~%")
|
||||||
|
(print-screen screen t))
|
||||||
|
|
||||||
|
(let* ((input (parse-input (read-file-lines "input.txt")))
|
||||||
|
(screen (solution-part-2 input)))
|
||||||
|
(format t "~&~%screen for normal input~%~%")
|
||||||
|
(print-screen screen t))
|
||||||
|
|
||||||
;; Local Variables:
|
;; Local Variables:
|
||||||
;; mode: lisp
|
;; mode: lisp
|
||||||
;; End:
|
;; End:
|
||||||
|
|
Loading…
Reference in a new issue