~rauhl/advent-of-code

advent-of-code/2019-12-02.lisp -rw-r--r-- 1.9 KiB
f1ff392aRobert A. Uhl Day 5 11 months ago
                                                                                
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
(defpackage "AOC/2019/2" (:use "CL"))
(in-package "AOC/2019/2")

(defconstant +test+ "1,9,10,3,2,3,11,0,99,30,40,50")

(defconstant +input+ "1,12,2,3,1,1,2,3,1,3,4,3,1,5,0,3,2,1,9,19,1,10,19,23,2,9,23,27,1,6,27,31,2,31,9,35,1,5,35,39,1,10,39,43,1,10,43,47,2,13,47,51,1,10,51,55,2,55,10,59,1,9,59,63,2,6,63,67,1,5,67,71,1,71,5,75,1,5,75,79,2,79,13,83,1,83,5,87,2,6,87,91,1,5,91,95,1,95,9,99,1,99,6,103,1,103,13,107,1,107,5,111,2,111,13,115,1,115,6,119,1,6,119,123,2,123,13,127,1,10,127,131,1,131,2,135,1,135,5,0,99,2,14,0,0")

(defun interpret (vector)
  (check-type vector (vector fixnum))
  (loop for i from 0 by 4
        for opcode = (aref vector i)
	do (when (= opcode 99)
	     (return-from interpret vector))
	do (let ((a (aref vector (1+ i)))
		 (b (aref vector (+ i 2)))
		 (out (aref vector (+ i 3))))
	     (cond
	       ((= opcode 1) (setf (aref vector out)
				   (+ (aref vector a) (aref vector b))))
	       ((= opcode 2) (setf (aref vector out)
				   (* (aref vector a) (aref vector b))))
	       (t (error "unknown opcode ~s" opcode))))))

(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 +input+)))

(defun part2 ()
  (loop for noun from 0 to 255
	do (loop for verb from 0 to 255
		 do (let ((vector (parse-string +input+))
			  result)
		      (setf (aref vector 1) noun
			    (aref vector 2) verb
			    result (aref (interpret vector) 0))
		      (when (= result 19690720)
			(return-from part2 (+ (* 100 noun) verb)))))))