day 10 cleanup

This commit is contained in:
efim 2022-12-11 18:33:10 +00:00
parent c31d22d69d
commit 65de39af73
1 changed files with 103 additions and 0 deletions

View File

@ -211,3 +211,106 @@
while line
do (parse-command-line line my-machine))
(accumulated-signal my-machine)))
;;; Cleaning up:
;;; part 1
;; state of the CPU
(defclass machine ()
((clock :reader clock :initform 0)
(register :reader register :initform 1)
(accumulated-signal :reader accumulated-signal :initform 0)
(next-special-clock :reader next-special-clock :initform 20)))
(defmethod print-object ((obj machine) stream)
(print-unreadable-object (obj stream :type t)
(with-accessors ((clock clock )
(register register )
(accumulated-signal accumulated-signal)
(next-special-clock next-special-clock))
obj
(format stream "clock: ~a, register: ~a, accum: ~a; next-special: ~a" clock register accumulated-signal next-special-clock))))
;; passing of sinlge step
(defgeneric tick (obj)
(:method ((obj machine))
(incf (slot-value obj 'clock))
(when (= (next-special-clock obj) (clock obj))
(incf (slot-value obj 'accumulated-signal) (* (clock obj) (register obj)))
(update-special-clock obj))))
(defgeneric update-special-clock (obj)
(:method ((obj machine))
(incf (slot-value obj 'next-special-clock) 40)))
;; actual cpu commands in terms of ticks and register changes:
(defgeneric noop (mach)
(:method ((mach machine))
(tick mach)))
(defgeneric addx (mach num)
(:method ((mach machine) num)
(tick mach)
(tick mach)
(incf (slot-value mach 'register) num )))
(require 'cl-ppcre)
(defun parse-command-line (line machine)
(let* ((the-split (cl-ppcre:split " " line))
(command (intern (string-upcase (first the-split)))))
(case command
('addx (addx machine (parse-integer (second the-split))))
('noop (noop machine))
(t "hello"))))
;; now it's time to simiulate the file evaluation
(let ((my-machine (make-instance 'machine)))
(with-open-file (in "day10-test.txt")
(loop
for line = (read-line in nil nil)
while line
do (parse-command-line line my-machine))
(accumulated-signal my-machine)))
(let ((my-machine (make-instance 'machine)))
(with-open-file (in "day10-input.txt")
(loop
for line = (read-line in nil nil)
while line
do (parse-command-line line my-machine))
(accumulated-signal my-machine)))
;;; PART 2
(defclass crt (machine)
((next-special-clock :reader next-special-clock :initform 40)))
(defun cur-pixel-in-sprite (pixel-index sprite-center)
(and (>= pixel-index (1- sprite-center))
(<= pixel-index (1+ sprite-center))))
(defmethod tick :before ((obj crt))
(let ((pixel (if (cur-pixel-in-sprite (clock obj) (register obj))
"#"
".")))
(format t pixel))
(when (= (clock obj) (1- (next-special-clock obj)))
(incf (slot-value obj 'register) 40)
(terpri)))
;; and same code reading in commands, but with CRT results in printing
(let ((my-machine (make-instance 'crt)))
(with-open-file (in "day10-test.txt")
(loop
for line = (read-line in nil nil)
while line
do (parse-command-line line my-machine))
(accumulated-signal my-machine)))
(let ((my-machine (make-instance 'crt)))
(with-open-file (in "day10-input.txt")
(loop
for line = (read-line in nil nil)
while line
do (parse-command-line line my-machine))
(accumulated-signal my-machine)))