day 10 CRT and CLOG

maybe kind of cool
the addx and noop didn't have to be changed
only additional code for TICK
This commit is contained in:
efim 2022-12-11 17:17:21 +00:00
parent 5990ef5d0b
commit c31d22d69d
3 changed files with 501 additions and 0 deletions

142
day10-input.txt Normal file
View File

@ -0,0 +1,142 @@
addx 1
addx 5
noop
addx -1
noop
noop
addx 6
addx 15
addx -9
noop
addx -1
addx 4
addx 2
addx -22
addx 27
addx -1
addx 4
noop
addx 1
addx 2
noop
noop
noop
noop
addx 1
addx -33
addx 2
addx 5
addx 2
addx 3
addx -2
addx 7
noop
addx -2
addx -8
addx 15
addx 5
noop
noop
addx -2
addx 2
noop
noop
addx 7
addx -14
noop
addx -2
addx -17
addx 5
addx -4
noop
addx 23
addx -18
noop
noop
noop
addx 28
addx -18
addx 4
noop
noop
addx -5
addx 1
addx 10
addx 2
noop
noop
addx -30
addx 33
addx -32
noop
noop
addx -2
addx 6
addx -2
addx 4
addx 3
addx 19
addx 10
addx -5
addx -16
addx 3
addx -2
addx 17
addx -19
addx 11
addx 2
addx 9
noop
addx -4
addx -6
addx -7
addx -24
noop
addx 7
addx -2
addx 5
addx 2
addx 3
addx -2
addx 2
addx 5
addx 2
addx 7
addx -2
noop
addx 3
addx -2
addx 2
addx 7
noop
addx -2
addx -34
addx 1
addx 1
noop
noop
noop
addx 5
noop
noop
addx 5
addx -1
noop
addx 6
addx -1
noop
addx 4
addx 3
addx 4
addx -1
addx 5
noop
addx 5
noop
noop
noop
noop
noop
addx 1
noop
noop

146
day10-test.txt Normal file
View File

@ -0,0 +1,146 @@
addx 15
addx -11
addx 6
addx -3
addx 5
addx -1
addx -8
addx 13
addx 4
noop
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx 5
addx -1
addx -35
addx 1
addx 24
addx -19
addx 1
addx 16
addx -11
noop
noop
addx 21
addx -15
noop
noop
addx -3
addx 9
addx 1
addx -3
addx 8
addx 1
addx 5
noop
noop
noop
noop
noop
addx -36
noop
addx 1
addx 7
noop
noop
noop
addx 2
addx 6
noop
noop
noop
noop
noop
addx 1
noop
noop
addx 7
addx 1
noop
addx -13
addx 13
addx 7
noop
addx 1
addx -33
noop
noop
noop
addx 2
noop
noop
noop
addx 8
noop
addx -1
addx 2
addx 1
noop
addx 17
addx -9
addx 1
addx 1
addx -3
addx 11
noop
noop
addx 1
noop
addx 1
noop
noop
addx -13
addx -19
addx 1
addx 3
addx 26
addx -30
addx 12
addx -1
addx 3
addx 1
noop
noop
noop
addx -9
addx 18
addx 1
addx 2
noop
noop
addx 9
noop
noop
noop
addx -1
addx 2
addx -37
addx 1
addx 3
noop
addx 15
addx -21
addx 22
addx -6
addx 1
noop
addx 2
addx 1
noop
addx -10
noop
noop
addx 20
addx 1
addx 2
addx 2
addx -6
addx -11
noop
noop
noop

213
day10.lisp Normal file
View File

@ -0,0 +1,213 @@
;; https://adventofcode.com/2022/day/10
;;
;; cathode ray tube. hm.
;; so, starting from 20th cycle, step by 40 and calculate the value in the Register
;; to get desired value multiply the cicle number by value.
;; and for result - sum them all
;; cool.
;;
;; main part: we need Register value "during" the 20th, etc cycle
;; so it's "end the end of 19th"
;; at 0 we have value 1
;; then each operation does some amount of ticks.
;; well,
;; i guess i could write (tick) function that increases the timer, and if timer of required time - adds current value to result
;; let's finally use CLOS?
(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))))
(defparameter *test-machine* (make-instance 'machine))
(setf (clock *test-machine*) 7)
(setf (slot-value *test-machine* 'clock) 9)
;; can the method be private in the class?
;; so that clock would be incremented by (tick)
;; and (tick) only called from the (run-command) ?
;; and also for register to also only have reader?
;; can I disallow setting values to register?
;; they are still writeable by (slot-value) link
;; it seems that if I don't need polymorphism, I don't need DEFGENERIC
;; and can just define some functions
;; and classes don't change their scopes in any way, and don't really encapsulate their state, as slots are writeable
(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))))
(tick *test-machine*)
(defparameter *test-machine* (make-instance 'machine))
(progn
(tick *test-machine*)
(print *test-machine*))
(next-special-clock *test-machine*)
(defgeneric update-special-clock (obj)
(:method ((obj machine))
(incf (slot-value obj 'next-special-clock) 40)))
(update-special-clock *test-machine*)
;; now that i'm thinking about modifying accumulated signal on tick,
;; i'm thinking about storing "next-special-clock" starting with 20, and rewriting by x + 40
;; and comparing with (1- next-special-clock) for value during that special time
;; i need to slow down. how would commands look:
;; addx 4 (tick) (tick) (set-new-value)
;; noop (tick)
;; so. if clock is at 19, meaning we endedn 19th cycle. and we start 20th which is noop
;; the tick should increase the clock
;; check if it's special. if it's 20 then add current Register * 20 and add to sum
;; now tick seems to work.
;; let's implement noop and addx
(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 )))
(defparameter *test-machine* (make-instance 'machine))
(print *test-machine*)
(addx *test-machine* 4)
;; and all i need now is to simulate the input file
(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"))))
(defparameter *test-machine* (make-instance 'machine))
(print *test-machine*)
(parse-command-line "addx 31" *test-machine*)
(parse-command-line "noop" *test-machine*)
(intern "addx")
(intern "ADDX")
(string-upcase "addx")
;; 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
;; suppose would want to implement the screen as a class as well?
;; it would do what?
;; it should have logic on top of the machine?
;; maybe run it's code after machine tick?
;; maybe extending machine
;; afther cycle that starts at 0 and ends at 1 first pixel finishes
;; after cycle that starts at 39 and ends at 40 last pixes finishes
;; so, yeah. if i have crt extend machine, it could have it's own special cycles
;; and tick could be extended to run after, and also produce pixel \ string \ char
;; & newline when needed - into the string buffer of crt?
(print "hello/nman")
;; i guess i could just print to terminal
;; and improvement could be configuring the output stream
(format t "hello")
(terpri)
(defclass crt (machine)
((next-special-clock :reader next-special-clock :initform 40)))
(defparameter *test-crt* (make-instance 'crt))
(update-special-clock *test-crt*)
(tick *test-crt*)
;; now on each tick i want to print a char.
;; what is the logic here?
;; on each tick print # if current clock is within +-1 of register value
;; and . otherwise
;; on the special-clock to (terpri)
;; simplified printing
(defmethod tick :before ((obj crt))
(format t "@")
(when (= (clock obj) (1- (next-special-clock obj)))
(terpri)))
(defparameter *test-crt* (make-instance 'crt))
(next-special-clock *test-crt*)
(tick *test-crt*)
(noop *test-crt*)
;; so my problem was the crt method runs "before"
;; and never reaches clock == next-special-clock
;; because when tick runs on 39 it increases clock to 40 and also increases next-sp to 80
;; but i suppose doing new line on 39 is what i want
(defun cur-pixel-in-sprite (pixel-index sprite-center)
(and (>= pixel-index (1- sprite-center))
(<= pixel-index (1+ sprite-center))))
(cur-pixel-in-sprite 0 0)
(cur-pixel-in-sprite 0 1)
(cur-pixel-in-sprite 0 2)
(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)))
(defparameter *test-crt* (make-instance 'crt))
(noop *test-crt*)
(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)))