From c31d22d69d212b7712be882c3ffd8204cd749b44 Mon Sep 17 00:00:00 2001 From: efim Date: Sun, 11 Dec 2022 17:17:21 +0000 Subject: [PATCH] day 10 CRT and CLOG maybe kind of cool the addx and noop didn't have to be changed only additional code for TICK --- day10-input.txt | 142 ++++++++++++++++++++++++++++++++ day10-test.txt | 146 +++++++++++++++++++++++++++++++++ day10.lisp | 213 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 501 insertions(+) create mode 100644 day10-input.txt create mode 100644 day10-test.txt create mode 100644 day10.lisp diff --git a/day10-input.txt b/day10-input.txt new file mode 100644 index 0000000..36431be --- /dev/null +++ b/day10-input.txt @@ -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 diff --git a/day10-test.txt b/day10-test.txt new file mode 100644 index 0000000..37ee8ee --- /dev/null +++ b/day10-test.txt @@ -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 diff --git a/day10.lisp b/day10.lisp new file mode 100644 index 0000000..41062d3 --- /dev/null +++ b/day10.lisp @@ -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)))