~rauhl/advent-of-code

advent-of-code/2019-12-05.lisp -rw-r--r-- 4.9 KiB View raw
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
(defpackage #:aoc/2019/5 (:use #:cl))
(in-package #:aoc/2019/5)

(defvar *debug* nil)

(defun interpret (vector)
  (check-type vector (vector fixnum))
  (let ((pc 0))
    (tagbody
     start
       (multiple-value-bind (modes opcode)
	   (floor (aref vector pc) 100)
	 (when *debug*
	   (format t "~&~d: ~d (~d)" pc opcode modes))
	 (incf pc)
	 (flet ((pop-arg ()
		  (multiple-value-bind (rest mode)
		      (floor modes 10)
		    (setf modes rest)
		    (prog1
			(if (zerop mode)
			    (aref vector (aref vector pc))
			    (aref vector pc))
		      (incf pc)))))
	   (case opcode
	     (99 (return-from interpret vector))
	     (1
	      (let ((a (pop-arg))
		    (b (pop-arg)))
		(when *debug*
		  (format t "(+ ~d ~d) → ~d" a b (aref vector pc)))
		(setf (aref vector (aref vector pc)) (+ a b))))
	     (2
	      (let ((a (pop-arg))
		    (b (pop-arg)))
		(when *debug*
		  (format t "(* ~d ~d) → ~d" a b (aref vector pc)))
		(setf (aref vector (aref vector pc)) (* a b))))
	     (3
	      (setf (aref vector (aref vector pc)) (parse-integer (read-line))))
	     (4
	      (format t "> ~d~%" (pop-arg))
	      (go start))
	     (5
	      (let ((cond (pop-arg))
		    (branch (pop-arg)))
		(when *debug*
		  (format t "(when ~d ~d)" cond branch))
		(unless (zerop cond)
		  (setq pc branch))
		  (go start)))
	     (6
	      (let ((cond (pop-arg))
		    (branch (pop-arg)))
		(when *debug*
		  (format t "(unless ~d ~d)" cond branch))
		(when (zerop cond)
		  (setq pc branch))
		  (go start)))
	     (7
	      (let ((a (pop-arg))
		    (b (pop-arg)))
		(setf (aref vector (aref vector pc)) (if (< a b) 1 0))))
	     (8
	      (let ((a (pop-arg))
		    (b (pop-arg)))
		(setf (aref vector (aref vector pc)) (if (= a b) 1 0))))
	     (t (error "Unknown opcode ~d." opcode)))))
       (when *debug*
	 (format t "~%~a~%" vector))
       (incf pc)
       (go start))))

(defun parse-string (s)
  (loop with start = 0 and vector = (make-array 0 :element-type 'fixnum :adjustable t :fill-pointer t)
	while (< start (length s))
	do (multiple-value-bind (n end)
	       (parse-integer s :start start :junk-allowed t)
             (unless n
	       (return-from part1))
	     (unless (or (= end (length s)) (char= (aref s end) #\,))
	       (error "unexpected character ~s" (aref s end)))
	     (setq start (1+ end))
	     (vector-push-extend n vector))
	finally (return vector)))

(defun part1 ()
  (interpret (parse-string "3,225,1,225,6,6,1100,1,238,225,104,0,1102,46,47,225,2,122,130,224,101,-1998,224,224,4,224,1002,223,8,223,1001,224,6,224,1,224,223,223,1102,61,51,225,102,32,92,224,101,-800,224,224,4,224,1002,223,8,223,1001,224,1,224,1,223,224,223,1101,61,64,225,1001,118,25,224,101,-106,224,224,4,224,1002,223,8,223,101,1,224,224,1,224,223,223,1102,33,25,225,1102,73,67,224,101,-4891,224,224,4,224,1002,223,8,223,1001,224,4,224,1,224,223,223,1101,14,81,225,1102,17,74,225,1102,52,67,225,1101,94,27,225,101,71,39,224,101,-132,224,224,4,224,1002,223,8,223,101,5,224,224,1,224,223,223,1002,14,38,224,101,-1786,224,224,4,224,102,8,223,223,1001,224,2,224,1,223,224,223,1,65,126,224,1001,224,-128,224,4,224,1002,223,8,223,101,6,224,224,1,224,223,223,1101,81,40,224,1001,224,-121,224,4,224,102,8,223,223,101,4,224,224,1,223,224,223,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,1008,677,226,224,1002,223,2,223,1005,224,329,1001,223,1,223,107,677,677,224,102,2,223,223,1005,224,344,101,1,223,223,1107,677,677,224,102,2,223,223,1005,224,359,1001,223,1,223,1108,226,226,224,1002,223,2,223,1006,224,374,101,1,223,223,107,226,226,224,1002,223,2,223,1005,224,389,1001,223,1,223,108,226,226,224,1002,223,2,223,1005,224,404,1001,223,1,223,1008,677,677,224,1002,223,2,223,1006,224,419,1001,223,1,223,1107,677,226,224,102,2,223,223,1005,224,434,1001,223,1,223,108,226,677,224,102,2,223,223,1006,224,449,1001,223,1,223,8,677,226,224,102,2,223,223,1006,224,464,1001,223,1,223,1007,677,226,224,1002,223,2,223,1006,224,479,1001,223,1,223,1007,677,677,224,1002,223,2,223,1005,224,494,1001,223,1,223,1107,226,677,224,1002,223,2,223,1006,224,509,101,1,223,223,1108,226,677,224,102,2,223,223,1005,224,524,1001,223,1,223,7,226,226,224,102,2,223,223,1005,224,539,1001,223,1,223,8,677,677,224,1002,223,2,223,1005,224,554,101,1,223,223,107,677,226,224,102,2,223,223,1006,224,569,1001,223,1,223,7,226,677,224,1002,223,2,223,1005,224,584,1001,223,1,223,1008,226,226,224,1002,223,2,223,1006,224,599,101,1,223,223,1108,677,226,224,102,2,223,223,1006,224,614,101,1,223,223,7,677,226,224,102,2,223,223,1005,224,629,1001,223,1,223,8,226,677,224,1002,223,2,223,1006,224,644,101,1,223,223,1007,226,226,224,102,2,223,223,1005,224,659,101,1,223,223,108,677,677,224,1002,223,2,223,1006,224,674,1001,223,1,223,4,223,99,226")))

(let ((*debug* t))
  (interpret (parse-string "3,9,8,9,10,9,4,9,99,-1,8")))