Skip to content

Commit

Permalink
Day 19
Browse files Browse the repository at this point in the history
Added solution for day 19. Adapted day16 a bit on the way.
  • Loading branch information
abraemer committed Dec 19, 2018
1 parent 882559a commit 7ebcc21
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 5 deletions.
4 changes: 3 additions & 1 deletion advent-of-code-2018.asd
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,6 @@
(:file "day13")
(:file "day14")
(:file "day16")
(:file "day17")))
(:file "day17")
(:file "day18")
(:file "day19")))
17 changes: 13 additions & 4 deletions day16.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,28 @@

(in-package :advent-of-code-2018)

(defun day16-make-test-case (line1 line2 line3)
(let ((before (extract-integers line1))
(instruction (extract-integers line2))
(after (extract-integers line3)))
(list (make-array (length before) :initial-contents before)
instruction
(make-array (length after) :initial-contents after))))

(defun day16-parse-input ()
(with-open-file (in (puzzlepath "input16.txt"))
(loop :for line := (read-line in nil)
:while line
:unless (= 0 (length line))
:when (char= #\B (char line 0))
:collect (mapcar #'extract-integers (list line (read-line in) (read-line in))) :into test-cases
:collect (day16-make-test-case line (read-line in) (read-line in)) :into test-cases
:else :collect (extract-integers line) :into test-prog
:finally (return (list test-cases test-prog)))))

(defun day16-execute! (register command)
(destructuring-bind (cmd inp1 inp2 out) command
(macrolet ((reg (x)
`(nth ,x register)))
`(aref register ,x)))
(setf (reg out)
(case cmd
(addr (+ (reg inp1) (reg inp2)))
Expand Down Expand Up @@ -65,7 +73,8 @@
:count (<= 3 (length (day16-test-case case))) :into count
:finally (format t "There are ~a test cases with 3 or more possible instructions.~%" count))
(loop :with id->opcode := (day16-construct-opcode-ids cases)
:with registers := (list 0 0 0 0)
:with registers := #(0 0 0 0)
:for (id . args) :in prog
:do (setf registers (day16-execute! registers (cons (aref id->opcode id) args)))
:finally (format t "After executing the test program the value in register 0 is ~a.~%" (first registers)))))
:finally (format t "After executing the test program the value in register 0 is ~a.~%"
(aref registers 0)))))
63 changes: 63 additions & 0 deletions day19.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
;;;; day19.lisp

(in-package :advent-of-code-2018)

(defstruct (program-state (:conc-name pstate-))
instructions
(ip 0)
(ip-binding nil)
(registers (make-array 6 :initial-element 0 :element-type 'integer)))

(defun day19-parse-input (&optional (file (puzzlepath "input19.txt")))
(loop-line-by-line file
:when (char= #\# (char line 0)) :collect (list 'ip (parse-integer line :start 4))
:else :collect (cons (read-from-string line) (extract-integers line))))

(defun day19-initialize-program (instruction-list)
(make-program-state :instructions (make-array (1- (length instruction-list))
:initial-contents (rest instruction-list))
:ip-binding (second (first instruction-list))))

(defun day19-execute! (program-state)
(with-accessors ((instr pstate-instructions)
(ip pstate-ip)
(ip-binding pstate-ip-binding)
(registers pstate-registers))
program-state
(when ip-binding
(setf (aref registers ip-binding) ip))
;(format t "before: ~a~%" registers)
(let ((command (aref instr ip)))
(if (eq 'ip (first command))
(setf ip-binding (second command))
(day16-execute! registers command))
; (format t "command: ~a~%~%" command)
)
(when ip-binding
(setf ip (aref registers ip-binding)))
(incf ip)
(< -1 ip (length instr))))

;;; runs FOREVER
(defun day19-brute-force ()
(loop :with prog := (day19-initialize-program (day19-parse-input))
:count t :into loops
:while (day19-execute! prog)
:finally (format t "The first background process exits with the value ~a in the zeroth register.~%"
(aref (pstate-registers prog) 0)))
(let ((prog (day19-initialize-program (day19-parse-input))))
(setf (aref (pstate-registers prog) 0) 1)
(loop :while (day19-execute! prog)
:finally
(format t "The second background process exits with the value ~a in the zeroth register.~%"
(aref (pstate-registers prog) 0)))))

(defun day19-analytic (input)
(loop :for a :from 1 :upto (ceiling (sqrt input))
:when (= 0 (mod input a)) :sum (+ a (/ input a))))

(defun day19 ()
(format t "The first background process exits with the value ~a in the zeroth register.~%"
(day19-analytic 931))
(format t "The second background process exits with the value ~a in the zeroth register.~%"
(day19-analytic 10551331)))

0 comments on commit 7ebcc21

Please sign in to comment.