Initial commit
This commit is contained in:
commit
f242d2b0df
420 changed files with 62521 additions and 0 deletions
3
2019/.gitignore
vendored
Normal file
3
2019/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
*\~
|
||||
*.fasl
|
||||
compiled/
|
10
2019/README.org
Normal file
10
2019/README.org
Normal file
|
@ -0,0 +1,10 @@
|
|||
* Advent of Code 2019
|
||||
|
||||
My answers for [[https://adventofcode.com/2019][Advent of Code 2019]].
|
||||
|
||||
Racket tests:
|
||||
|
||||
#+begin_src sh
|
||||
raco make **/*.rkt
|
||||
raco test **/*.rkt
|
||||
#+end_src
|
4
2019/day01/day01.dyalog
Normal file
4
2019/day01/day01.dyalog
Normal file
|
@ -0,0 +1,4 @@
|
|||
p←⍎¨⊃⎕nget'input.txt'1
|
||||
f←{0⌈⌊2-⍨⍵÷3}
|
||||
+/f p ⍝ part 1
|
||||
+/,↑{(f⍣⍵)p}¨⍳10 ⍝ part 2
|
16
2019/day01/day01.lisp
Normal file
16
2019/day01/day01.lisp
Normal file
|
@ -0,0 +1,16 @@
|
|||
(defparameter *input-file* #P"input.txt")
|
||||
(defparameter *input* (uiop:read-file-lines *input-file*))
|
||||
|
||||
(defun part1 ()
|
||||
(loop for line in *input*
|
||||
sum (- (floor (/ (parse-integer line) 3)) 2)))
|
||||
|
||||
(defun total-fuel-requirements (total-fuel fuel)
|
||||
(let ((new-fuel (max 0 (- (floor (/ fuel 3)) 2))))
|
||||
(if (= new-fuel 0)
|
||||
(+ total-fuel fuel)
|
||||
(total-fuel-requirements (+ total-fuel fuel) new-fuel))))
|
||||
|
||||
(defun part2 ()
|
||||
(loop for line in *input*
|
||||
sum (total-fuel-requirements 0 (- (floor (/ (parse-integer line) 3)) 2))))
|
100
2019/day01/input.txt
Normal file
100
2019/day01/input.txt
Normal file
|
@ -0,0 +1,100 @@
|
|||
120847
|
||||
60347
|
||||
63340
|
||||
72773
|
||||
57020
|
||||
133960
|
||||
98163
|
||||
121548
|
||||
87233
|
||||
59150
|
||||
59712
|
||||
146816
|
||||
93205
|
||||
61936
|
||||
75319
|
||||
141998
|
||||
97125
|
||||
73450
|
||||
106250
|
||||
129939
|
||||
94854
|
||||
113782
|
||||
112044
|
||||
127923
|
||||
67114
|
||||
119770
|
||||
130034
|
||||
70876
|
||||
82204
|
||||
101939
|
||||
132604
|
||||
142836
|
||||
117066
|
||||
95861
|
||||
75597
|
||||
94630
|
||||
50085
|
||||
101107
|
||||
77937
|
||||
94286
|
||||
74091
|
||||
140875
|
||||
118543
|
||||
52767
|
||||
54544
|
||||
93062
|
||||
115681
|
||||
142065
|
||||
111737
|
||||
131214
|
||||
75160
|
||||
115432
|
||||
140504
|
||||
115376
|
||||
86589
|
||||
104631
|
||||
133012
|
||||
108690
|
||||
85993
|
||||
99533
|
||||
133725
|
||||
87698
|
||||
133480
|
||||
68379
|
||||
107852
|
||||
111209
|
||||
116623
|
||||
98717
|
||||
130227
|
||||
114356
|
||||
144516
|
||||
89663
|
||||
118355
|
||||
77816
|
||||
149914
|
||||
105080
|
||||
116793
|
||||
65259
|
||||
143900
|
||||
67838
|
||||
148389
|
||||
129753
|
||||
140524
|
||||
90005
|
||||
147305
|
||||
118428
|
||||
79940
|
||||
59110
|
||||
78120
|
||||
87066
|
||||
64722
|
||||
142066
|
||||
81410
|
||||
106958
|
||||
92984
|
||||
95584
|
||||
108534
|
||||
66362
|
||||
126340
|
||||
143660
|
5
2019/day02/day02.dyalog
Normal file
5
2019/day02/day02.dyalog
Normal file
|
@ -0,0 +1,5 @@
|
|||
⎕io←0
|
||||
p←⍎¨','(≠⊆⊢)⊃⊃⎕nget'input.txt'1
|
||||
f←{i←0 ⊣ s[1 2]←⍵ ⊣ s←p ⋄ ⊃s⊣{i+←4 ⊣ a x y z←s[i+⍳4] ⋄ s[z]←(a-1)⌷s[x](+,×)s[y]}⍣{99=i⌷s}0}
|
||||
f 12 2 ⍝ part 1
|
||||
nv←1+,⍳99 99 ⋄ +/100 1×⊃nv[(19690720=f¨nv)⍳1] ⍝ part 2
|
32
2019/day02/day02.lisp
Normal file
32
2019/day02/day02.lisp
Normal file
|
@ -0,0 +1,32 @@
|
|||
(ql:quickload "str")
|
||||
|
||||
(defparameter *input-file* #P"input.txt")
|
||||
(defparameter *input* (uiop:read-file-string *input-file*))
|
||||
|
||||
(defun execute (program)
|
||||
(loop for i from 0 by 4 until (= 99 (aref program i))
|
||||
do (let ((opcode (aref program i)))
|
||||
(cond ((= opcode 1)
|
||||
(setf (aref program (aref program (+ 3 i)))
|
||||
(+ (aref program (aref program (+ 1 i)))
|
||||
(aref program (aref program (+ 2 i))))))
|
||||
((= opcode 2)
|
||||
(setf (aref program (aref program (+ 3 i)))
|
||||
(* (aref program (aref program (+ 1 i)))
|
||||
(aref program (aref program (+ 2 i)))))))))
|
||||
program)
|
||||
|
||||
(defun execute-with-inputs (program-string noun verb)
|
||||
(let ((program (map 'vector #'parse-integer (str:split "," program-string))))
|
||||
(setf (aref program 1) noun)
|
||||
(setf (aref program 2) verb)
|
||||
(aref (execute program) 0)))
|
||||
|
||||
(defun part1 (program-string)
|
||||
(execute-with-inputs program-string 12 2))
|
||||
|
||||
(defun part2 (program-string)
|
||||
(dotimes (noun 99)
|
||||
(dotimes (verb 99)
|
||||
(when (= 19690720 (execute-with-inputs program-string noun verb))
|
||||
(return-from part2 (+ (* 100 noun) verb))))))
|
34
2019/day02/day02.rkt
Normal file
34
2019/day02/day02.rkt
Normal file
|
@ -0,0 +1,34 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../intcode.rkt"
|
||||
racket/vector)
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (part1 filename)
|
||||
(define program (parse-file filename))
|
||||
(vector-set! program 1 12)
|
||||
(vector-set! program 2 2)
|
||||
(define vm (execute (start-machine program '())))
|
||||
(vector-ref (machine-program vm) 0))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 "input.txt") 6627023))
|
||||
|
||||
(define (try-inputs program noun verb)
|
||||
(define my-program (vector-copy program))
|
||||
(vector-set! my-program 1 noun)
|
||||
(vector-set! my-program 2 verb)
|
||||
(define vm (execute (start-machine my-program '())))
|
||||
(vector-ref (machine-program vm) 0))
|
||||
|
||||
(define (part2 filename)
|
||||
(define program (parse-file filename))
|
||||
(for*/first ([noun (in-range 100)]
|
||||
[verb (in-range 100)]
|
||||
#:when (eq? 19690720 (try-inputs program noun verb)))
|
||||
(+ (* 100 noun) verb)))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part2 "input.txt") 4019))
|
1
2019/day02/input.txt
Normal file
1
2019/day02/input.txt
Normal file
|
@ -0,0 +1 @@
|
|||
1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,9,1,19,1,9,19,23,1,23,5,27,2,27,10,31,1,6,31,35,1,6,35,39,2,9,39,43,1,6,43,47,1,47,5,51,1,51,13,55,1,55,13,59,1,59,5,63,2,63,6,67,1,5,67,71,1,71,13,75,1,10,75,79,2,79,6,83,2,9,83,87,1,5,87,91,1,91,5,95,2,9,95,99,1,6,99,103,1,9,103,107,2,9,107,111,1,111,6,115,2,9,115,119,1,119,6,123,1,123,9,127,2,127,13,131,1,131,9,135,1,10,135,139,2,139,10,143,1,143,5,147,2,147,6,151,1,151,5,155,1,2,155,159,1,6,159,0,99,2,0,14,0
|
7
2019/day03/day03.dyalog
Normal file
7
2019/day03/day03.dyalog
Normal file
|
@ -0,0 +1,7 @@
|
|||
⎕io←0
|
||||
p←','(≠⊆⊢)¨⊃⎕nget'input.txt'1
|
||||
segment←{x y←⍺ ⋄ 'R'=⊃⍵:{x y+⍵}¨1↓,⍳(1+⍎1↓⍵),1 ⋄ 'L'=⊃⍵:{x y+⍵}¨1↓,-⍳(1+⍎1↓⍵),1 ⋄ 'D'=⊃⍵:{x y+⍵}¨1↓,-⍳1,1+⍎1↓⍵ ⋄ 'U'=⊃⍵:{x y+⍵}¨1↓,⍳1,1+⍎1↓⍵}
|
||||
path←{x←⊂0 0 ⋄ 1↓x⊣{x,←(⊃⌽x) segment ⍵}¨⍵}
|
||||
⌊/+/↑(path ⊃0⌷p) ∩ path ⊃1⌷p ⍝ part 1
|
||||
c←(path ⊃0⌷p)∩path ⊃1⌷p
|
||||
2+⌊/((path ⊃0⌷p)⍳c)+(path ⊃1⌷p)⍳c ⍝ part 2
|
2
2019/day03/input.txt
Normal file
2
2019/day03/input.txt
Normal file
|
@ -0,0 +1,2 @@
|
|||
R990,U803,R777,U157,R629,D493,R498,D606,R344,U241,L708,D403,R943,U961,L107,D755,R145,D77,L654,D297,L263,D904,R405,U676,R674,U139,L746,U935,R186,U433,L739,D774,R470,D459,R865,D209,L217,U525,R747,D218,R432,U769,L876,D477,R606,D161,R991,D338,R647,D958,R777,D148,R593,D873,L95,U707,R468,U518,R845,U285,R221,U771,R989,D107,R44,U833,L343,D420,R468,D954,L604,D270,L691,U401,R850,U70,R441,U461,R638,D743,R65,U673,L999,U110,R266,U759,R768,U569,L250,D577,R247,U420,L227,U437,L80,D647,L778,U935,R585,U35,L735,D201,R694,U635,L597,U215,R743,D542,L701,U946,L503,U589,R836,D687,L444,U409,L473,U132,L570,U374,R193,D908,L800,U294,L252,U851,R947,D647,L37,D20,L27,U620,L534,D356,L291,U611,L128,D670,L364,U200,L749,D708,R776,U99,R606,D999,L810,D373,R212,D138,R856,D966,L206,D23,L860,D731,L914,U716,L212,U225,R766,U348,L220,D69,L766,D15,L557,U71,R734,D295,R884,D822,R300,D152,L986,D170,R764,U24,R394,D710,L860,U830,L305,U431,R201,D44,R882,U667,R37,D727,R916,U460,L834,D771,R373,U96,L707,D576,R607,D351,R577,D200,L402,U364,L32,D512,L152,D283,L232,U804,R827,U352,R104,D323,L254,U273,L451,D967,R739,D53,L908,D866,R998,U897,L581,U538,R206,U644,L70,D17,L481,U912,L377,D922,L286,U547,R35,U292,L318,U256,R79,D52,R92,U160,R763,U428,R663,D634,R212,D325,R460,U142,L375,U382,R20,D321,L220,D578,R915,D465,L797,D849,L281,D491,L911,D624,R800,U629,L675,U428,L219,U694,R680,U350,R113,D903,L22,D683,L787,D1,R93,U315,L562,U756,R622,D533,L587,D216,L933,U972,R506,U536,R797,U828,L12,D965,L641,U165,R937,D675,R259
|
||||
L998,D197,L301,D874,L221,U985,L213,D288,R142,D635,R333,D328,R405,D988,L23,D917,R412,D971,R876,U527,R987,D884,R39,D485,L971,U200,R931,U79,L271,U183,R354,D18,R346,D866,L752,D204,L863,U784,R292,U676,R811,U721,L53,U983,L993,U822,R871,U539,L782,D749,R417,U667,R882,U467,R321,U894,R912,U756,L102,U154,L57,D316,R200,U372,L44,U406,L426,D613,R847,U977,R303,U469,R509,U839,L633,D267,L487,D976,R325,U399,L359,U161,L305,U935,R522,D848,R784,D273,L337,D55,L266,U406,L858,D650,L176,D124,R231,U513,L462,U328,L674,D598,R568,D742,L39,D438,L643,D254,R577,U519,R325,U124,R91,U129,L79,D52,R480,D46,R129,D997,R452,D992,L721,U490,L595,D666,R372,D198,R813,U624,L469,U59,R578,U184,R117,D749,L745,U302,R398,D951,L683,D360,R476,D788,R70,U693,R295,D547,L61,U782,R440,D818,L330,D321,L968,U622,R160,U571,L886,D43,L855,U272,R530,D267,L312,D519,L741,D697,R206,U148,L445,U857,R983,D192,L788,U826,R805,U932,R888,D250,L682,D52,R406,D176,R984,D637,L947,D416,L687,U699,L544,D710,L933,D171,L357,D134,L968,D538,R496,D240,L730,U771,R554,U708,R265,D748,L839,U668,L333,U335,R526,U809,L653,D6,R234,D130,R871,U911,R538,U372,L960,D535,L196,U236,L966,D185,L166,U789,L885,U453,R627,D586,R501,U222,L280,U124,R755,D159,L759,U78,R669,D889,L150,D888,L71,D917,L126,D97,L138,U726,R160,D971,R527,D988,R455,D413,R539,U923,R258,U734,L459,D954,R877,U613,R343,D98,R238,U478,R514,U814,L274,U119,L958,U698,R761,U693,R367,D111,L800,D531,L91,U616,R208,D255,R169,U145,R671,U969,L468,U566,R589,D455,R323,D303,R374,D890,R377,D262,L40,U85,L719
|
14
2019/day04/day04.dyalog
Normal file
14
2019/day04/day04.dyalog
Normal file
|
@ -0,0 +1,14 @@
|
|||
⎕io←0
|
||||
a b←245182 790572
|
||||
p←⊃(,(∘.,))/6/⊂⍳10
|
||||
x←{(1↓⍵)-¯1↓⍵}¨p
|
||||
n←10⊥¨((∨/¨0=x)∧∧/¨0≤x)/p
|
||||
≢((n>a)∧n<b)/n ⍝ part 1
|
||||
n2←10⊥¨(({∨/2=⍵}¨(⊢∘≢⌸)¨p)∧∧/¨0≤x)/p
|
||||
≢((n2>a)∧n2<b)/n2 ⍝ part 2
|
||||
|
||||
⍝ better version (inspired from
|
||||
⍝ https://github.com/jayfoad/aoc2019apl/blob/master/p4.dyalog)
|
||||
p←⍉10⊥⍣¯1⊢a+⍳1+b-a
|
||||
+/({∧/2≤/⍵}∧{∨/2=/⍵})p ⍝ part 1
|
||||
+/({∧/2≤/⍵}∧{∨/¨2=(⊢∘≢⌸)¨↓⍵})p ⍝ part 2
|
61
2019/day05/day05.lisp
Normal file
61
2019/day05/day05.lisp
Normal file
|
@ -0,0 +1,61 @@
|
|||
(defparameter *input-file* #P"input.txt")
|
||||
(defparameter *input* (uiop:read-file-string *input-file*))
|
||||
|
||||
(defvar *program*)
|
||||
|
||||
(defun opcode (pc)
|
||||
(mod (aref *program* pc) 100))
|
||||
|
||||
(defun parameter-mode (pc index)
|
||||
(mod (truncate (aref *program* pc) (expt 10 (+ 1 index))) 10))
|
||||
|
||||
(defun parameter (pc index)
|
||||
(ecase (parameter-mode pc index)
|
||||
(1 (aref *program* (+ index pc)))
|
||||
(0 (aref *program* (aref *program* (+ pc index))))))
|
||||
|
||||
(defun (setf parameter) (new-value pc index)
|
||||
(ecase (parameter-mode pc index)
|
||||
(0 (setf (aref *program* (aref *program* (+ pc index))) new-value))
|
||||
(1 (error "Cannot write with a parameter in immediate mode"))))
|
||||
|
||||
(defun execute (inputs)
|
||||
(defun execute-instruction (pc inputs outputs)
|
||||
(ecase (opcode pc)
|
||||
(99 (return-from execute-instruction outputs))
|
||||
(1 (setf (parameter pc 3) (+ (parameter pc 1) (parameter pc 2)))
|
||||
(execute-instruction (+ pc 4) inputs outputs))
|
||||
(2 (setf (parameter pc 3) (* (parameter pc 1) (parameter pc 2)))
|
||||
(execute-instruction (+ pc 4) inputs outputs))
|
||||
(3 (setf (parameter pc 1) (car inputs))
|
||||
(execute-instruction (+ pc 2) (cdr inputs) outputs))
|
||||
(4 (execute-instruction (+ pc 2) inputs (cons (parameter pc 1) outputs)))
|
||||
(5 (if (/= 0 (parameter pc 1))
|
||||
(execute-instruction (parameter pc 2) inputs outputs)
|
||||
(execute-instruction (+ pc 3) inputs outputs)))
|
||||
(6 (if (= 0 (parameter pc 1))
|
||||
(execute-instruction (parameter pc 2) inputs outputs)
|
||||
(execute-instruction (+ pc 3) inputs outputs)))
|
||||
(7 (if (< (parameter pc 1) (parameter pc 2))
|
||||
(setf (parameter pc 3) 1)
|
||||
(setf (parameter pc 3) 0))
|
||||
(execute-instruction (+ pc 4) inputs outputs))
|
||||
(8 (if (= (parameter pc 1) (parameter pc 2))
|
||||
(setf (parameter pc 3) 1)
|
||||
(setf (parameter pc 3) 0))
|
||||
(execute-instruction (+ pc 4) inputs outputs))))
|
||||
(execute-instruction 0 inputs nil))
|
||||
|
||||
(defun parse-program (program-string)
|
||||
(map 'vector #'parse-integer (uiop:split-string program-string :separator ",")))
|
||||
|
||||
(defun part1 ()
|
||||
(let ((*program* (parse-program *input*)))
|
||||
(car (execute '(1)))))
|
||||
|
||||
(defun part2 ()
|
||||
(let ((*program* (parse-program *input*)))
|
||||
(car (execute '(5)))))
|
||||
|
||||
(assert (= (part1) 12896948))
|
||||
(assert (= (part2) 7704130))
|
22
2019/day05/day05.rkt
Normal file
22
2019/day05/day05.rkt
Normal file
|
@ -0,0 +1,22 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../intcode.rkt")
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (part1 filename)
|
||||
(define program (parse-file filename))
|
||||
(define vm (execute (start-machine program '(1))))
|
||||
(car (machine-outputs vm)))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 "input.txt") 12896948))
|
||||
|
||||
(define (part2 filename)
|
||||
(define program (parse-file filename))
|
||||
(define vm (execute (start-machine program '(5))))
|
||||
(car (machine-outputs vm)))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part2 "input.txt") 7704130))
|
1
2019/day05/input.txt
Normal file
1
2019/day05/input.txt
Normal file
|
@ -0,0 +1 @@
|
|||
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
|
23
2019/day06/day06.rkt
Normal file
23
2019/day06/day06.rkt
Normal file
|
@ -0,0 +1,23 @@
|
|||
#lang racket
|
||||
|
||||
(require racket/string
|
||||
graph)
|
||||
|
||||
(define (read-graph filename)
|
||||
(with-input-from-file filename
|
||||
(lambda ()
|
||||
(define g (unweighted-graph/directed '()))
|
||||
(for ([line (in-lines)])
|
||||
(define bodies (string-split line ")"))
|
||||
(add-edge! g (car bodies) (cadr bodies)))
|
||||
g)))
|
||||
|
||||
(define (part1 filename)
|
||||
(define g (read-graph filename))
|
||||
(define-values (dists _) (bfs g "COM"))
|
||||
(for/sum ([i (in-hash-values dists)]) i))
|
||||
|
||||
(define (part2 filename)
|
||||
(define g (read-graph filename))
|
||||
(define-values (dists _) (bfs g "YOU"))
|
||||
(- (hash-ref dists "SAN") 2))
|
1514
2019/day06/input
Normal file
1514
2019/day06/input
Normal file
File diff suppressed because it is too large
Load diff
11
2019/day06/test
Normal file
11
2019/day06/test
Normal file
|
@ -0,0 +1,11 @@
|
|||
COM)B
|
||||
B)C
|
||||
C)D
|
||||
D)E
|
||||
E)F
|
||||
B)G
|
||||
G)H
|
||||
D)I
|
||||
E)J
|
||||
J)K
|
||||
K)L
|
13
2019/day06/test2
Normal file
13
2019/day06/test2
Normal file
|
@ -0,0 +1,13 @@
|
|||
COM)B
|
||||
B)C
|
||||
C)D
|
||||
D)E
|
||||
E)F
|
||||
B)G
|
||||
G)H
|
||||
D)I
|
||||
E)J
|
||||
J)K
|
||||
K)L
|
||||
K)YOU
|
||||
I)SAN
|
87
2019/day07/day07.lisp
Normal file
87
2019/day07/day07.lisp
Normal file
|
@ -0,0 +1,87 @@
|
|||
(ql:quickload :alexandria)
|
||||
|
||||
(defparameter *input-file* #P"input.txt")
|
||||
(defvar *input*)
|
||||
|
||||
(defvar *program*)
|
||||
(defvar *input-fn*)
|
||||
(defvar *output-fn*)
|
||||
|
||||
(defun opcode (pc)
|
||||
(mod (aref *program* pc) 100))
|
||||
|
||||
(defun parameter-mode (pc index)
|
||||
(mod (truncate (aref *program* pc) (expt 10 (+ 1 index))) 10))
|
||||
|
||||
(defun parameter (pc index)
|
||||
(ecase (parameter-mode pc index)
|
||||
(1 (aref *program* (+ index pc)))
|
||||
(0 (aref *program* (aref *program* (+ pc index))))))
|
||||
|
||||
(defun (setf parameter) (new-value pc index)
|
||||
(ecase (parameter-mode pc index)
|
||||
(0 (setf (aref *program* (aref *program* (+ pc index))) new-value))
|
||||
(1 (error "Cannot write with a parameter in immediate mode"))))
|
||||
|
||||
(defun execute-instruction (pc)
|
||||
(ecase (opcode pc)
|
||||
(99 (return-from execute-instruction))
|
||||
(1 (setf (parameter pc 3) (+ (parameter pc 1) (parameter pc 2)))
|
||||
(execute-instruction (+ pc 4)))
|
||||
(2 (setf (parameter pc 3) (* (parameter pc 1) (parameter pc 2)))
|
||||
(execute-instruction (+ pc 4)))
|
||||
(3 (setf (parameter pc 1) (funcall *input-fn*))
|
||||
(execute-instruction (+ pc 2)))
|
||||
(4 (funcall *output-fn* (parameter pc 1))
|
||||
(execute-instruction (+ pc 2)))
|
||||
(5 (if (/= 0 (parameter pc 1))
|
||||
(execute-instruction (parameter pc 2))
|
||||
(execute-instruction (+ pc 3))))
|
||||
(6 (if (= 0 (parameter pc 1))
|
||||
(execute-instruction (parameter pc 2))
|
||||
(execute-instruction (+ pc 3))))
|
||||
(7 (if (< (parameter pc 1) (parameter pc 2))
|
||||
(setf (parameter pc 3) 1)
|
||||
(setf (parameter pc 3) 0))
|
||||
(execute-instruction (+ pc 4)))
|
||||
(8 (if (= (parameter pc 1) (parameter pc 2))
|
||||
(setf (parameter pc 3) 1)
|
||||
(setf (parameter pc 3) 0))
|
||||
(execute-instruction (+ pc 4)))))
|
||||
|
||||
(defun execute (program &key (input 'input) (output 'output))
|
||||
(let ((*program* program)
|
||||
(*input-fn* input)
|
||||
(*output-fn* output))
|
||||
(execute-instruction 0)))
|
||||
|
||||
(defun parse-program (program-string)
|
||||
(map 'vector #'parse-integer (uiop:split-string program-string :separator ",")))
|
||||
|
||||
(defun amplify (phases)
|
||||
(let ((amp-input 0))
|
||||
(loop for phase in phases
|
||||
do (let ((program (alexandria:copy-array *program*))
|
||||
(inputs (list phase amp-input))
|
||||
(output nil))
|
||||
(execute program :input (lambda () (pop inputs)) :output (lambda (x) (setf output x)))
|
||||
(setf amp-input output)))
|
||||
amp-input))
|
||||
|
||||
(defun max-thrust ()
|
||||
(let ((res nil))
|
||||
(alexandria:map-permutations (lambda (x) (push (amplify x) res)) '(0 1 2 3 4))
|
||||
(apply #'max res)))
|
||||
|
||||
(assert (= 43210 (let ((*program* (parse-program "3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0")))
|
||||
(max-thrust))))
|
||||
|
||||
(assert (= 54321 (let ((*program* (parse-program "3,23,3,24,1002,24,10,24,1002,23,-1,23,101,5,23,23,1,24,23,23,4,23,99,0,0")))
|
||||
(max-thrust))))
|
||||
|
||||
(assert (= 65210 (let ((*program* (parse-program "3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0")))
|
||||
(max-thrust))))
|
||||
|
||||
(defun part1 ()
|
||||
(let ((*program* (parse-program (uiop:read-file-string *input-file*))))
|
||||
(max-thrust)))
|
51
2019/day07/day07.rkt
Normal file
51
2019/day07/day07.rkt
Normal file
|
@ -0,0 +1,51 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../intcode.rkt"
|
||||
racket/list)
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (part1 program)
|
||||
(apply max
|
||||
(for/list ([phases (in-permutations (range 5))])
|
||||
(for/fold ([signal 0])
|
||||
([phase (in-list phases)])
|
||||
(define vm (execute (start-machine program (list phase signal))))
|
||||
(car (machine-outputs vm))))))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 (parse "3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0")) 43210)
|
||||
(check-equal? (part1 (parse "3,23,3,24,1002,24,10,24,1002,23,-1,23,
|
||||
101,5,23,23,1,24,23,23,4,23,99,0,0")) 54321)
|
||||
(check-equal? (part1 (parse "3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,
|
||||
1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0")) 65210)
|
||||
(check-equal? (part1 (parse-file "input.txt")) 298586))
|
||||
|
||||
(define (part2 program)
|
||||
(define signals
|
||||
(for/list ([phases (in-permutations (range 5 10))])
|
||||
(define amplifiers
|
||||
(for/list ([phase (in-list phases)])
|
||||
(define vm (execute (start-machine program (list phase))))
|
||||
vm))
|
||||
(let loop ([signal 0]
|
||||
[amplifiers amplifiers])
|
||||
(if (empty? amplifiers)
|
||||
signal
|
||||
(let* ([amp (machine-program (car amplifiers))]
|
||||
[pc (machine-pc (car amplifiers))]
|
||||
[new-vm (execute (machine amp (list signal) pc 0 #f '()))]
|
||||
[new-amplifiers (if (machine-terminated new-vm)
|
||||
(cdr amplifiers)
|
||||
(append (cdr amplifiers) (list new-vm)))])
|
||||
(loop (car (machine-outputs new-vm)) new-amplifiers))))))
|
||||
(apply max signals))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part2 (parse "3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,
|
||||
27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5")) 139629729)
|
||||
(check-equal? (part2 (parse "3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,
|
||||
-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,
|
||||
53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10")) 18216)
|
||||
(check-equal? (part2 (parse-file "input.txt")) 9246095))
|
1
2019/day07/input.txt
Normal file
1
2019/day07/input.txt
Normal file
|
@ -0,0 +1 @@
|
|||
3,8,1001,8,10,8,105,1,0,0,21,42,67,84,109,126,207,288,369,450,99999,3,9,102,4,9,9,1001,9,4,9,102,2,9,9,101,2,9,9,4,9,99,3,9,1001,9,5,9,1002,9,5,9,1001,9,5,9,1002,9,5,9,101,5,9,9,4,9,99,3,9,101,5,9,9,1002,9,3,9,1001,9,2,9,4,9,99,3,9,1001,9,2,9,102,4,9,9,101,2,9,9,102,4,9,9,1001,9,2,9,4,9,99,3,9,102,2,9,9,101,5,9,9,1002,9,2,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,99,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,101,1,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,99
|
4
2019/day08/day08.dyalog
Normal file
4
2019/day08/day08.dyalog
Normal file
|
@ -0,0 +1,4 @@
|
|||
p←100 6 25⍴⍎¨⊃⊃⎕nget'input.txt'1
|
||||
x←,(⊃⍋+/+/0=p)⌷p
|
||||
(+/1=x)×+/2=x ⍝ part 1
|
||||
' ⌺'[{1⌷⍋⍵⍳0 1}¨⊂[1]p] ⍝ part 2
|
1
2019/day08/input.txt
Normal file
1
2019/day08/input.txt
Normal file
File diff suppressed because one or more lines are too long
29
2019/day09/day09.rkt
Normal file
29
2019/day09/day09.rkt
Normal file
|
@ -0,0 +1,29 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../intcode.rkt")
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (part12 program input)
|
||||
(define vm (execute (start-machine program (list input))))
|
||||
(car (machine-outputs vm)))
|
||||
|
||||
(module+ test
|
||||
(test-case "quine"
|
||||
(define quine (parse "109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99"))
|
||||
(define vm (execute (start-machine quine '())))
|
||||
(check-true (machine-terminated vm))
|
||||
(check-equal? (reverse (machine-outputs vm)) (vector->list quine)))
|
||||
(test-case "16-digit number"
|
||||
(define program (parse "1102,34915192,34915192,7,4,7,99,0"))
|
||||
(define vm (execute (start-machine program '())))
|
||||
(check-true (machine-terminated vm))
|
||||
(check-equal? (string-length (number->string (car (machine-outputs vm)))) 16))
|
||||
(test-case "large number"
|
||||
(define program (parse "104,1125899906842624,99"))
|
||||
(define vm (execute (start-machine program '())))
|
||||
(check-true (machine-terminated vm))
|
||||
(check-equal? (car (machine-outputs vm)) 1125899906842624))
|
||||
(check-equal? (part12 (parse-file "input") 1) 3601950151)
|
||||
(check-equal? (part12 (parse-file "input") 2) 64236))
|
1
2019/day09/input
Normal file
1
2019/day09/input
Normal file
|
@ -0,0 +1 @@
|
|||
1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1101,0,3,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1101,0,30,1016,1101,37,0,1005,1101,362,0,1023,1101,0,20,1014,1101,39,0,1013,1102,34,1,1007,1101,682,0,1027,1102,664,1,1025,1102,1,655,1028,1101,0,26,1002,1102,1,38,1015,1101,669,0,1024,1101,0,28,1017,1102,1,21,1000,1101,0,27,1012,1102,1,29,1008,1102,1,23,1019,1101,0,24,1011,1101,685,0,1026,1102,646,1,1029,1102,1,369,1022,1101,0,31,1003,1102,1,36,1001,1101,0,0,1020,1102,1,35,1009,1101,32,0,1010,1101,0,1,1021,1102,33,1,1004,1101,22,0,1006,1102,1,25,1018,109,14,1205,6,197,1001,64,1,64,1105,1,199,4,187,1002,64,2,64,109,-4,21107,40,39,9,1005,1019,219,1001,64,1,64,1105,1,221,4,205,1002,64,2,64,109,9,1206,1,239,4,227,1001,64,1,64,1106,0,239,1002,64,2,64,109,-9,2101,0,-8,63,1008,63,26,63,1005,63,261,4,245,1106,0,265,1001,64,1,64,1002,64,2,64,109,-6,2108,37,1,63,1005,63,287,4,271,1001,64,1,64,1105,1,287,1002,64,2,64,109,15,21108,41,44,-2,1005,1017,307,1001,64,1,64,1106,0,309,4,293,1002,64,2,64,109,-16,1207,1,34,63,1005,63,327,4,315,1105,1,331,1001,64,1,64,1002,64,2,64,109,8,1208,-9,29,63,1005,63,347,1106,0,353,4,337,1001,64,1,64,1002,64,2,64,109,4,2105,1,8,1001,64,1,64,1105,1,371,4,359,1002,64,2,64,109,-22,1201,9,0,63,1008,63,27,63,1005,63,391,1106,0,397,4,377,1001,64,1,64,1002,64,2,64,109,18,21107,42,43,5,1005,1016,415,4,403,1106,0,419,1001,64,1,64,1002,64,2,64,109,-8,1201,2,0,63,1008,63,37,63,1005,63,441,4,425,1105,1,445,1001,64,1,64,1002,64,2,64,109,27,1205,-9,463,4,451,1001,64,1,64,1106,0,463,1002,64,2,64,109,-1,1206,-8,475,1105,1,481,4,469,1001,64,1,64,1002,64,2,64,109,-6,21101,43,0,-8,1008,1015,43,63,1005,63,507,4,487,1001,64,1,64,1106,0,507,1002,64,2,64,109,-15,2101,0,-3,63,1008,63,35,63,1005,63,531,1001,64,1,64,1106,0,533,4,513,1002,64,2,64,109,-2,2102,1,-6,63,1008,63,18,63,1005,63,553,1105,1,559,4,539,1001,64,1,64,1002,64,2,64,109,7,21102,44,1,3,1008,1016,44,63,1005,63,581,4,565,1105,1,585,1001,64,1,64,1002,64,2,64,109,-11,1202,7,1,63,1008,63,34,63,1005,63,609,1001,64,1,64,1105,1,611,4,591,1002,64,2,64,109,6,1202,1,1,63,1008,63,35,63,1005,63,637,4,617,1001,64,1,64,1106,0,637,1002,64,2,64,109,16,2106,0,4,4,643,1001,64,1,64,1106,0,655,1002,64,2,64,109,-1,2105,1,1,4,661,1106,0,673,1001,64,1,64,1002,64,2,64,109,5,2106,0,-1,1105,1,691,4,679,1001,64,1,64,1002,64,2,64,109,-24,1208,-2,26,63,1005,63,709,4,697,1105,1,713,1001,64,1,64,1002,64,2,64,109,-10,2102,1,6,63,1008,63,21,63,1005,63,735,4,719,1105,1,739,1001,64,1,64,1002,64,2,64,109,25,21108,45,45,-9,1005,1010,757,4,745,1106,0,761,1001,64,1,64,1002,64,2,64,109,-12,1207,-7,20,63,1005,63,777,1106,0,783,4,767,1001,64,1,64,1002,64,2,64,109,-13,2108,22,6,63,1005,63,799,1106,0,805,4,789,1001,64,1,64,1002,64,2,64,109,17,21102,46,1,0,1008,1011,45,63,1005,63,825,1105,1,831,4,811,1001,64,1,64,1002,64,2,64,109,-6,2107,21,1,63,1005,63,849,4,837,1105,1,853,1001,64,1,64,1002,64,2,64,109,-3,2107,27,0,63,1005,63,873,1001,64,1,64,1105,1,875,4,859,1002,64,2,64,109,12,21101,47,0,0,1008,1014,48,63,1005,63,899,1001,64,1,64,1105,1,901,4,881,4,64,99,21102,27,1,1,21101,0,915,0,1105,1,922,21201,1,42931,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21101,942,0,0,1106,0,922,21202,1,1,-1,21201,-2,-3,1,21102,1,957,0,1106,0,922,22201,1,-1,-2,1106,0,968,22101,0,-2,-2,109,-3,2106,0,0
|
87
2019/day10/day10.rkt
Normal file
87
2019/day10/day10.rkt
Normal file
|
@ -0,0 +1,87 @@
|
|||
#lang racket
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (read-input filename)
|
||||
(string->grid (file->string filename)))
|
||||
|
||||
(define (string->grid str)
|
||||
(for/set ([line (string-split str)]
|
||||
[i (in-naturals)]
|
||||
#:when #t
|
||||
[c (in-string line)]
|
||||
[j (in-naturals)]
|
||||
#:when (eq? c #\#))
|
||||
(make-rectangular j i)))
|
||||
|
||||
(define (segment->direction x)
|
||||
(define a (real-part x))
|
||||
(define b (imag-part x))
|
||||
(define r (gcd a b))
|
||||
(make-rectangular (/ a r) (/ b r)))
|
||||
|
||||
(define (detected grid)
|
||||
(for/hash ([x (in-set grid)])
|
||||
(values x (for/set ([y (in-set grid)]
|
||||
#:unless (= x y))
|
||||
(segment->direction (- y x))))))
|
||||
|
||||
(define (find-station grid)
|
||||
(define visible (detected grid))
|
||||
(define max-visible (apply max (map set-count (hash-values visible))))
|
||||
(define pos (for/first ([(k v) (in-hash visible)]
|
||||
#:when (= max-visible (set-count v)))
|
||||
k))
|
||||
(values pos (hash-ref visible pos)))
|
||||
|
||||
(define (part1 filename)
|
||||
(define grid (read-input filename))
|
||||
(define-values (loc dirs) (find-station grid))
|
||||
(set-count dirs))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 "test") 8)
|
||||
(check-equal? (part1 "input") 286))
|
||||
|
||||
(define (find-target grid station direction)
|
||||
(define targets
|
||||
(for/list ([x (in-set grid)]
|
||||
#:unless (= x station)
|
||||
#:when (real? (/ (- x station) direction))
|
||||
#:when (<= 0 (/ (- x station) direction)))
|
||||
x))
|
||||
(car (sort targets
|
||||
(λ (x y) (< (magnitude (- x station))
|
||||
(magnitude (- y station)))))))
|
||||
|
||||
(define (rotate-left lst)
|
||||
(if (empty? lst)
|
||||
'()
|
||||
(append (cdr lst) (list (car lst)))))
|
||||
|
||||
(define (rotate-right lst)
|
||||
(reverse (rotate-left (reverse lst))))
|
||||
|
||||
(define (find-nth-target grid n)
|
||||
(define-values (station directions) (find-station grid))
|
||||
(define directions-sorted (rotate-right
|
||||
(sort (set->list directions)
|
||||
(λ (x y) (< (angle (* -i x)) (angle (* -i y)))))))
|
||||
(define-values (final-grid targets)
|
||||
(for/fold ([grid grid]
|
||||
[targets '()])
|
||||
([i (in-range n)]
|
||||
[dir (in-cycle directions-sorted)])
|
||||
(define target (find-target grid station dir))
|
||||
(values (set-remove grid target)
|
||||
(cons target targets))))
|
||||
(car targets))
|
||||
|
||||
(define (part2 filename)
|
||||
(define grid (read-input filename))
|
||||
(define target (find-nth-target grid 200))
|
||||
(+ (* 100 (real-part target)) (imag-part target)))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part2 "input") 504))
|
30
2019/day10/input
Normal file
30
2019/day10/input
Normal file
|
@ -0,0 +1,30 @@
|
|||
.#.####..#.#...#...##..#.#.##.
|
||||
..#####.##..#..##....#..#...#.
|
||||
......#.......##.##.#....##..#
|
||||
..#..##..#.###.....#.#..###.#.
|
||||
..#..#..##..#.#.##..###.......
|
||||
...##....#.##.#.#..##.##.#...#
|
||||
.##...#.#.##..#.#........#.#..
|
||||
.##...##.##..#.#.##.#.#.#.##.#
|
||||
#..##....#...###.#..##.#...##.
|
||||
.###.###..##......#..#...###.#
|
||||
.#..#.####.#..#....#.##..#.#.#
|
||||
..#...#..#.#######....###.....
|
||||
####..#.#.#...##...##....#..##
|
||||
##..#.##.#.#..##.###.#.##.##..
|
||||
..#.........#.#.#.#.......#..#
|
||||
...##.#.....#.#.##........#..#
|
||||
##..###.....#.............#.##
|
||||
.#...#....#..####.#.#......##.
|
||||
..#..##..###...#.....#...##..#
|
||||
...####..#.#.##..#....#.#.....
|
||||
####.#####.#.#....#.#....##.#.
|
||||
#.#..#......#.........##..#.#.
|
||||
#....##.....#........#..##.##.
|
||||
.###.##...##..#.##.#.#...#.#.#
|
||||
##.###....##....#.#.....#.###.
|
||||
..#...#......#........####..#.
|
||||
#....#.###.##.#...#.#.#.#.....
|
||||
.........##....#...#.....#..##
|
||||
###....#.........#..#..#.#.#..
|
||||
##...#...###.#..#.###....#.##.
|
5
2019/day10/test
Normal file
5
2019/day10/test
Normal file
|
@ -0,0 +1,5 @@
|
|||
.#..#
|
||||
.....
|
||||
#####
|
||||
....#
|
||||
...##
|
58
2019/day11/day11.rkt
Normal file
58
2019/day11/day11.rkt
Normal file
|
@ -0,0 +1,58 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../intcode.rkt"
|
||||
racket/set)
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (part12 program start-panel [show-grid #f])
|
||||
(define vm (execute (start-machine program '())))
|
||||
(define grid (make-hash))
|
||||
(hash-set! grid 0 start-panel)
|
||||
(define painted (mutable-set))
|
||||
(let loop ([vm vm]
|
||||
[direction 0+1i]
|
||||
[position 0])
|
||||
(define new-vm
|
||||
(execute (machine (machine-program vm)
|
||||
(list (hash-ref grid position 0))
|
||||
(machine-pc vm)
|
||||
(machine-relative-base vm)
|
||||
#f
|
||||
'())))
|
||||
(unless (machine-terminated new-vm)
|
||||
(hash-set! grid position (cadr (machine-outputs new-vm)))
|
||||
(set-add! painted position)
|
||||
(define new-direction (if (= 0 (car (machine-outputs new-vm)))
|
||||
(* direction 0+1i)
|
||||
(* direction 0-1i)))
|
||||
(define new-position (+ position new-direction))
|
||||
(loop new-vm new-direction new-position)))
|
||||
(when show-grid
|
||||
(display-grid grid))
|
||||
(set-count painted))
|
||||
|
||||
(define (display-grid grid)
|
||||
(define min-x (apply min (map real-part (hash-keys grid))))
|
||||
(define max-x (apply max (map real-part (hash-keys grid))))
|
||||
(define min-y (apply min (map imag-part (hash-keys grid))))
|
||||
(define max-y (apply max (map imag-part (hash-keys grid))))
|
||||
(for* ([j (in-range max-y (sub1 min-y) -1)]
|
||||
[i (in-range min-x max-x)])
|
||||
(if (= 1 (hash-ref grid (make-rectangular i j) 0))
|
||||
(printf "#")
|
||||
(printf " "))
|
||||
(when (= i (sub1 max-x))
|
||||
(printf "\n"))))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part12 (parse-file "input") 0) 2511))
|
||||
|
||||
;; > (part12 (parse-file "input") 1 #t)
|
||||
;; # # ## # # ## # # ## ### # #
|
||||
;; # # # # # # # # # # # # # #
|
||||
;; #### # ## # ## # # # ####
|
||||
;; # # # # # # # # # ## ### # #
|
||||
;; # # # # # # # # # # # # # # #
|
||||
;; # # ## # # ## # # ### # # #
|
1
2019/day11/input
Normal file
1
2019/day11/input
Normal file
|
@ -0,0 +1 @@
|
|||
3,8,1005,8,328,1106,0,11,0,0,0,104,1,104,0,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,0,10,4,10,1001,8,0,29,1,104,7,10,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,0,10,4,10,1001,8,0,55,1,2,7,10,1006,0,23,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,0,10,4,10,1001,8,0,84,1006,0,40,1,1103,14,10,1,1006,16,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,1,8,10,4,10,1002,8,1,116,1006,0,53,1,1104,16,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,102,1,8,146,2,1104,9,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,1001,8,0,172,1006,0,65,1,1005,8,10,1,1002,16,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,0,8,10,4,10,102,1,8,204,2,1104,9,10,1006,0,30,3,8,102,-1,8,10,101,1,10,10,4,10,108,0,8,10,4,10,102,1,8,233,2,1109,6,10,1006,0,17,1,2,6,10,3,8,102,-1,8,10,101,1,10,10,4,10,108,1,8,10,4,10,102,1,8,266,1,106,7,10,2,109,2,10,2,9,8,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,1001,8,0,301,1,109,9,10,1006,0,14,101,1,9,9,1007,9,1083,10,1005,10,15,99,109,650,104,0,104,1,21102,1,837548789788,1,21101,0,345,0,1106,0,449,21101,0,846801511180,1,21101,0,356,0,1106,0,449,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21101,235244981271,0,1,21101,403,0,0,1105,1,449,21102,1,206182744295,1,21101,0,414,0,1105,1,449,3,10,104,0,104,0,3,10,104,0,104,0,21102,837896937832,1,1,21101,0,437,0,1106,0,449,21101,867965862668,0,1,21102,448,1,0,1106,0,449,99,109,2,22102,1,-1,1,21101,40,0,2,21102,1,480,3,21101,0,470,0,1106,0,513,109,-2,2106,0,0,0,1,0,0,1,109,2,3,10,204,-1,1001,475,476,491,4,0,1001,475,1,475,108,4,475,10,1006,10,507,1101,0,0,475,109,-2,2106,0,0,0,109,4,1201,-1,0,512,1207,-3,0,10,1006,10,530,21102,1,0,-3,22102,1,-3,1,21201,-2,0,2,21102,1,1,3,21102,549,1,0,1106,0,554,109,-4,2105,1,0,109,5,1207,-3,1,10,1006,10,577,2207,-4,-2,10,1006,10,577,21202,-4,1,-4,1106,0,645,21202,-4,1,1,21201,-3,-1,2,21202,-2,2,3,21101,596,0,0,1106,0,554,21201,1,0,-4,21102,1,1,-1,2207,-4,-2,10,1006,10,615,21101,0,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,637,22102,1,-1,1,21101,637,0,0,105,1,512,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2106,0,0
|
64
2019/day12/day12.rkt
Normal file
64
2019/day12/day12.rkt
Normal file
|
@ -0,0 +1,64 @@
|
|||
#lang racket
|
||||
|
||||
(struct moon
|
||||
(x y z vx vy vz)
|
||||
#:transparent)
|
||||
|
||||
(define (read-input filename)
|
||||
(with-input-from-file filename
|
||||
(lambda ()
|
||||
(for/list ([line (in-lines)])
|
||||
(define positions-str
|
||||
(cdr (regexp-match #rx"<x=(-?[0-9]+), y=(-?[0-9]+), z=(-?[0-9]+)>" line)))
|
||||
(define positions (map string->number positions-str))
|
||||
(apply moon (append positions '(0 0 0)))))))
|
||||
|
||||
(define (step moons)
|
||||
(for/list ([cur moons])
|
||||
(define new-vx (moon-vx cur))
|
||||
(define new-vy (moon-vy cur))
|
||||
(define new-vz (moon-vz cur))
|
||||
(define (gravity-pull pos-cur pos-other)
|
||||
(cond
|
||||
[(> pos-other pos-cur) 1]
|
||||
[(< pos-other pos-cur) -1]
|
||||
[else 0]))
|
||||
(for ([other moons] #:unless (eq? other cur))
|
||||
(set! new-vx (+ new-vx (gravity-pull (moon-x cur) (moon-x other))))
|
||||
(set! new-vy (+ new-vy (gravity-pull (moon-y cur) (moon-y other))))
|
||||
(set! new-vz (+ new-vz (gravity-pull (moon-z cur) (moon-z other)))))
|
||||
(moon (+ (moon-x cur) new-vx)
|
||||
(+ (moon-y cur) new-vy)
|
||||
(+ (moon-z cur) new-vz)
|
||||
new-vx
|
||||
new-vy
|
||||
new-vz)))
|
||||
|
||||
(define (total-energy moons)
|
||||
(for/sum ([m moons])
|
||||
(* (+ (abs (moon-x m))
|
||||
(abs (moon-y m))
|
||||
(abs (moon-z m)))
|
||||
(+ (abs (moon-vx m))
|
||||
(abs (moon-vy m))
|
||||
(abs (moon-vz m))))))
|
||||
|
||||
(define (part1 filename)
|
||||
(define moons (read-input filename))
|
||||
(total-energy (for/fold ([ms moons]) ([i (in-range 1000)]) (step ms))))
|
||||
|
||||
(define (cycle-length moons pos speed)
|
||||
(define-values (states final)
|
||||
(for/fold ([states (mutable-set)] [ms moons])
|
||||
([_ (in-naturals)]
|
||||
#:break (set-member? states (append (map pos ms) (map speed ms))))
|
||||
(set-add! states (append (map pos ms) (map speed ms)))
|
||||
(values states (step ms))))
|
||||
(set-count states))
|
||||
|
||||
(define (part2 filename)
|
||||
(define moons (read-input filename))
|
||||
(define cycle-x (cycle-length moons moon-x moon-vx))
|
||||
(define cycle-y (cycle-length moons moon-y moon-vy))
|
||||
(define cycle-z (cycle-length moons moon-z moon-vz))
|
||||
(lcm cycle-x cycle-y cycle-z))
|
4
2019/day12/input
Normal file
4
2019/day12/input
Normal file
|
@ -0,0 +1,4 @@
|
|||
<x=-17, y=9, z=-5>
|
||||
<x=-1, y=7, z=13>
|
||||
<x=-19, y=12, z=5>
|
||||
<x=-6, y=-6, z=-4>
|
4
2019/day12/test
Normal file
4
2019/day12/test
Normal file
|
@ -0,0 +1,4 @@
|
|||
<x=-1, y=0, z=2>
|
||||
<x=2, y=-10, z=-7>
|
||||
<x=4, y=-8, z=8>
|
||||
<x=3, y=5, z=-1>
|
4
2019/day12/test2
Normal file
4
2019/day12/test2
Normal file
|
@ -0,0 +1,4 @@
|
|||
<x=-8, y=-10, z=0>
|
||||
<x=5, y=5, z=10>
|
||||
<x=2, y=-7, z=3>
|
||||
<x=9, y=-8, z=-3>
|
74
2019/day13/day13.rkt
Normal file
74
2019/day13/day13.rkt
Normal file
|
@ -0,0 +1,74 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../intcode.rkt"
|
||||
racket/list)
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (part1 program)
|
||||
(define vm (execute (start-machine program '())))
|
||||
(define screen
|
||||
(let loop ([screen (hash)]
|
||||
[instructions (reverse (machine-outputs vm))])
|
||||
(if (empty? instructions)
|
||||
screen
|
||||
(let ([x (car instructions)]
|
||||
[y (cadr instructions)]
|
||||
[tile-id (caddr instructions)])
|
||||
(loop (hash-set screen (list x y) tile-id)
|
||||
(cdddr instructions))))))
|
||||
(for/sum ([(k v) (in-hash screen)]
|
||||
#:when (= v 2))
|
||||
1))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 (parse-file "input")) 363))
|
||||
|
||||
(define (ball-x screen)
|
||||
(for/first ([(k v) (in-hash screen)]
|
||||
#:when (= v 4))
|
||||
(car k)))
|
||||
|
||||
(define (paddle-x screen)
|
||||
(for/first ([(k v) (in-hash screen)]
|
||||
#:when (= v 3))
|
||||
(car k)))
|
||||
|
||||
(define (block-count screen)
|
||||
(for/sum ([(k v) (in-hash screen)]
|
||||
#:when (= v 2))
|
||||
1))
|
||||
|
||||
(define (draw-screen screen instructions)
|
||||
(if (empty? instructions)
|
||||
screen
|
||||
(let ([x (car instructions)]
|
||||
[y (cadr instructions)]
|
||||
[tile-id (caddr instructions)])
|
||||
(draw-screen (hash-set screen (list x y) tile-id)
|
||||
(cdddr instructions)))))
|
||||
|
||||
(define (part2 program)
|
||||
(vector-set! program 0 2)
|
||||
(define vm (execute (start-machine program '())))
|
||||
(define screen
|
||||
(let loop ([vm vm]
|
||||
[screen (hash)])
|
||||
(define new-screen (draw-screen screen (reverse (machine-outputs vm))))
|
||||
(define ball-pos (ball-x new-screen))
|
||||
(define paddle-pos (paddle-x new-screen))
|
||||
(define joystick (cond
|
||||
[(< ball-pos paddle-pos) -1]
|
||||
[(= ball-pos paddle-pos) 0]
|
||||
[(> ball-pos paddle-pos) 1]))
|
||||
(define new-vm
|
||||
(execute (machine (machine-program vm) (list joystick)
|
||||
(machine-pc vm) (machine-relative-base vm) #f '())))
|
||||
(if (= 0 (block-count new-screen))
|
||||
new-screen
|
||||
(loop new-vm new-screen))))
|
||||
(hash-ref screen (list -1 0)))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part2 (parse-file "input")) 17159))
|
1
2019/day13/input
Normal file
1
2019/day13/input
Normal file
File diff suppressed because one or more lines are too long
81
2019/day14/day14.rkt
Normal file
81
2019/day14/day14.rkt
Normal file
|
@ -0,0 +1,81 @@
|
|||
#lang racket
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(module+ main
|
||||
(displayln "Day 14"))
|
||||
|
||||
(define (read-rules filename)
|
||||
(with-input-from-file filename
|
||||
(lambda ()
|
||||
(define h (make-hash))
|
||||
(for ([line (in-lines)])
|
||||
(define rule
|
||||
(for/list ([elt (regexp-match* #rx"([0-9]+) ([A-Z]+)" line #:match-select cdr)])
|
||||
(list (string->number (car elt)) (string->symbol (cadr elt)))))
|
||||
(define output (last rule))
|
||||
(hash-set! h
|
||||
(cadr output)
|
||||
(cons (car output)
|
||||
(make-hash (for/list ([elt (drop-right rule 1)])
|
||||
(cons (cadr elt) (car elt)))))))
|
||||
h)))
|
||||
|
||||
(define (generate! rules needed available)
|
||||
(for ([(target target-amount) (in-hash needed)]
|
||||
#:unless (eq? target 'ORE))
|
||||
(define inputs (cdr (hash-ref rules target)))
|
||||
(define output-amount (car (hash-ref rules target)))
|
||||
(define new-target-amount (- target-amount (hash-ref available target 0)))
|
||||
(define multiple (ceiling (/ new-target-amount output-amount)))
|
||||
(hash-set! available target (- (* multiple output-amount) new-target-amount))
|
||||
(hash-set! needed target 0)
|
||||
(for ([(input input-amount) (in-hash inputs)])
|
||||
(hash-update! needed input (lambda (v) (+ v (* multiple input-amount))) 0))))
|
||||
|
||||
(define (ore-per-fuel rules amount)
|
||||
(define needed (make-hash `((FUEL . ,amount))))
|
||||
(define available (make-hash))
|
||||
(for ([i (in-naturals)]
|
||||
#:break (= (apply + (hash-values needed)) (hash-ref needed 'ORE 0)))
|
||||
(generate! rules needed available))
|
||||
(hash-ref needed 'ORE))
|
||||
|
||||
(define (part1 filename)
|
||||
(define rules (read-rules filename))
|
||||
(ore-per-fuel rules 1))
|
||||
|
||||
(module+ test
|
||||
(check-eq? 31 (part1 "test1"))
|
||||
(check-eq? 165 (part1 "test2"))
|
||||
(check-eq? 13312 (part1 "test3"))
|
||||
(check-eq? 180697 (part1 "test4"))
|
||||
(check-eq? 2210736 (part1 "test5")))
|
||||
|
||||
(module+ main
|
||||
(display "Part 1: ")
|
||||
(displayln (part1 "input")))
|
||||
|
||||
(define (part2 filename)
|
||||
(define rules (read-rules filename))
|
||||
(define max-fuel 1000000000000)
|
||||
(define min-fuel 1)
|
||||
(bisect rules 1000000000000 min-fuel max-fuel))
|
||||
|
||||
(define (bisect rules target-ore min-fuel max-fuel)
|
||||
(define mid-fuel (floor (+ min-fuel (/ (- max-fuel min-fuel) 2))))
|
||||
(define ore (ore-per-fuel rules mid-fuel))
|
||||
(cond
|
||||
[(= 1 (- max-fuel min-fuel)) min-fuel]
|
||||
[(< ore target-ore) (bisect rules target-ore mid-fuel max-fuel)]
|
||||
[(< target-ore ore) (bisect rules target-ore min-fuel mid-fuel)]))
|
||||
|
||||
(module+ test
|
||||
(check-eq? 82892753 (part2 "test3"))
|
||||
(check-eq? 5586022 (part2 "test4"))
|
||||
(check-eq? 460664 (part2 "test5")))
|
||||
|
||||
(module+ main
|
||||
(display "Part 2: ")
|
||||
(displayln (part2 "input")))
|
60
2019/day14/input
Normal file
60
2019/day14/input
Normal file
|
@ -0,0 +1,60 @@
|
|||
29 PQJGK => 4 SRPZP
|
||||
6 XKJP, 4 LDSMT => 6 ZVSMJ
|
||||
9 CGCPW, 2 CFVS => 7 DWZH
|
||||
1 VQWZC, 1 FRTJG => 1 MGLKL
|
||||
3 GCTBC, 4 RGKB => 4 RLZR
|
||||
2 LGLCP => 9 GCTBC
|
||||
3 DFPW, 12 FRTJG => 2 XVSRT
|
||||
1 VBXFG => 3 VQWZC
|
||||
1 GCTBC, 1 BVHM => 8 DGMZB
|
||||
7 DFPW, 3 JQNL => 7 FRTJG
|
||||
6 BHQN, 4 VXNP => 5 HBLQT
|
||||
1 XNBR, 27 FTBNQ, 2 RGKB => 7 JZPMK
|
||||
6 HKMV, 4 JHDHS, 11 NMSKF => 9 STCX
|
||||
129 ORE => 5 NVXTP
|
||||
13 BVHM, 5 XNBR => 3 LKXML
|
||||
3 SBPM, 4 LDSMT, 13 GPBG => 6 HXFCJ
|
||||
1 XVSRT, 1 JHDHS => 4 FTBNQ
|
||||
6 LKXML, 6 HRLWP => 5 PSJK
|
||||
5 HRLWP, 19 PDHVG => 1 VRQD
|
||||
3 FTBNQ, 1 QLKTZ => 7 SBPM
|
||||
2 VXNP => 3 XKJP
|
||||
4 SRPZP, 7 XVSRT => 8 LMVF
|
||||
2 GPBG, 8 DWZH, 3 JTCHR, 10 RLZR, 1 CFVS, 20 BFCZ => 2 WZSTV
|
||||
130 ORE => 9 JQNL
|
||||
100 ORE => 4 VBXFG
|
||||
4 XNBR => 8 RDSHN
|
||||
2 CDBTL, 2 XNBR, 8 QLKTZ => 6 CGCPW
|
||||
7 CGCPW => 6 BFCZ
|
||||
7 FTBNQ, 7 VXNP => 1 BVHM
|
||||
1 HXFCJ, 15 CSXD => 1 DFXPB
|
||||
1 MCRW, 6 MGLKL, 1 HBLQT => 8 SWRV
|
||||
19 BZQGL, 10 NMSKF, 20 WZSTV, 15 LVGB, 26 FTBNQ, 45 DWZH, 2 FJWVP, 56 JZPMK => 1 FUEL
|
||||
12 JTCHR => 4 CDBTL
|
||||
1 MGLKL => 6 PQJGK
|
||||
1 NVXTP => 1 LDSMT
|
||||
3 SWRV, 1 LGLCP => 2 GHVJ
|
||||
4 DGMZB, 11 HXFCJ, 2 RLZR => 4 SHTB
|
||||
5 GHVJ, 1 RGKB, 1 GCTBC => 6 HKMV
|
||||
1 SRPZP => 9 XNBR
|
||||
1 ZVSMJ => 2 JHDHS
|
||||
9 SWRV => 5 NMSKF
|
||||
1 NVXTP => 3 XKBS
|
||||
7 BHQN => 2 GPBG
|
||||
21 NMSKF, 12 FTBNQ, 12 SBPM => 3 CMXK
|
||||
2 GPBG, 12 ZVSMJ, 2 PDHVG => 4 LGLCP
|
||||
158 ORE => 8 DFPW
|
||||
3 BVHM, 1 HXFCJ, 5 CGCPW, 5 BFCZ, 6 VRQD, 3 LDSMT => 7 LVGB
|
||||
1 XVSRT, 1 XKJP => 8 PDHVG
|
||||
3 VRQD, 16 SHTB, 5 SBPM => 9 BZQGL
|
||||
1 BVHM, 3 HKMV => 4 CFVS
|
||||
13 JQNL => 7 VXNP
|
||||
1 XKJP, 6 XVSRT => 7 MCRW
|
||||
15 NVXTP, 19 XKBS => 4 BHQN
|
||||
8 JHDHS, 5 CMXK, 2 GPBG => 8 CSXD
|
||||
1 JZBR, 13 LKXML, 1 HKMV, 9 DFXPB, 3 XKBS, 2 PSJK, 2 LMVF, 15 HRLWP => 7 FJWVP
|
||||
1 CGCPW, 3 RDSHN => 8 JZBR
|
||||
24 PQJGK => 5 JTCHR
|
||||
1 XVSRT, 5 LDSMT => 6 QLKTZ
|
||||
17 GPBG => 7 RGKB
|
||||
4 STCX => 1 HRLWP
|
6
2019/day14/test1
Normal file
6
2019/day14/test1
Normal file
|
@ -0,0 +1,6 @@
|
|||
10 ORE => 10 A
|
||||
1 ORE => 1 B
|
||||
7 A, 1 B => 1 C
|
||||
7 A, 1 C => 1 D
|
||||
7 A, 1 D => 1 E
|
||||
7 A, 1 E => 1 FUEL
|
7
2019/day14/test2
Normal file
7
2019/day14/test2
Normal file
|
@ -0,0 +1,7 @@
|
|||
9 ORE => 2 A
|
||||
8 ORE => 3 B
|
||||
7 ORE => 5 C
|
||||
3 A, 4 B => 1 AB
|
||||
5 B, 7 C => 1 BC
|
||||
4 C, 1 A => 1 CA
|
||||
2 AB, 3 BC, 4 CA => 1 FUEL
|
9
2019/day14/test3
Normal file
9
2019/day14/test3
Normal file
|
@ -0,0 +1,9 @@
|
|||
157 ORE => 5 NZVS
|
||||
165 ORE => 6 DCFZ
|
||||
44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL
|
||||
12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ
|
||||
179 ORE => 7 PSHF
|
||||
177 ORE => 5 HKGWZ
|
||||
7 DCFZ, 7 PSHF => 2 XJWVT
|
||||
165 ORE => 2 GPVTF
|
||||
3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT
|
12
2019/day14/test4
Normal file
12
2019/day14/test4
Normal file
|
@ -0,0 +1,12 @@
|
|||
2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG
|
||||
17 NVRVD, 3 JNWZP => 8 VPVL
|
||||
53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL
|
||||
22 VJHF, 37 MNCFX => 5 FWMGM
|
||||
139 ORE => 4 NVRVD
|
||||
144 ORE => 7 JNWZP
|
||||
5 MNCFX, 7 RFSQX, 2 FWMGM, 2 VPVL, 19 CXFTF => 3 HVMC
|
||||
5 VJHF, 7 MNCFX, 9 VPVL, 37 CXFTF => 6 GNMV
|
||||
145 ORE => 6 MNCFX
|
||||
1 NVRVD => 8 CXFTF
|
||||
1 VJHF, 6 MNCFX => 4 RFSQX
|
||||
176 ORE => 6 VJHF
|
17
2019/day14/test5
Normal file
17
2019/day14/test5
Normal file
|
@ -0,0 +1,17 @@
|
|||
171 ORE => 8 CNZTR
|
||||
7 ZLQW, 3 BMBT, 9 XCVML, 26 XMNCP, 1 WPTQ, 2 MZWV, 1 RJRHP => 4 PLWSL
|
||||
114 ORE => 4 BHXH
|
||||
14 VRPVC => 6 BMBT
|
||||
6 BHXH, 18 KTJDG, 12 WPTQ, 7 PLWSL, 31 FHTLT, 37 ZDVW => 1 FUEL
|
||||
6 WPTQ, 2 BMBT, 8 ZLQW, 18 KTJDG, 1 XMNCP, 6 MZWV, 1 RJRHP => 6 FHTLT
|
||||
15 XDBXC, 2 LTCX, 1 VRPVC => 6 ZLQW
|
||||
13 WPTQ, 10 LTCX, 3 RJRHP, 14 XMNCP, 2 MZWV, 1 ZLQW => 1 ZDVW
|
||||
5 BMBT => 4 WPTQ
|
||||
189 ORE => 9 KTJDG
|
||||
1 MZWV, 17 XDBXC, 3 XCVML => 2 XMNCP
|
||||
12 VRPVC, 27 CNZTR => 2 XDBXC
|
||||
15 KTJDG, 12 BHXH => 5 XCVML
|
||||
3 BHXH, 2 VRPVC => 7 MZWV
|
||||
121 ORE => 7 VRPVC
|
||||
7 XCVML => 6 RJRHP
|
||||
5 BHXH, 4 VRPVC => 5 LTCX
|
64
2019/day15/day15.rkt
Normal file
64
2019/day15/day15.rkt
Normal file
|
@ -0,0 +1,64 @@
|
|||
#lang racket/base
|
||||
|
||||
(require racket/random
|
||||
racket/list
|
||||
racket/match
|
||||
graph
|
||||
"../intcode.rkt")
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (possible-directions grid pos)
|
||||
(define unexplored-directions
|
||||
(for/list ([step '(-1 -i 1 +i)]
|
||||
#:unless (hash-has-key? grid (+ pos step)))
|
||||
step))
|
||||
(if (empty? unexplored-directions)
|
||||
(for/list ([step '(-1 -i 1 +i)]
|
||||
#:unless (eq? 'wall (hash-ref grid (+ pos step) 'floor)))
|
||||
step)
|
||||
unexplored-directions))
|
||||
|
||||
(define (shortest-distances grid source)
|
||||
(define g (unweighted-graph/undirected
|
||||
(for*/list ([(pos tile) (in-hash grid)]
|
||||
#:unless (eq? 'wall tile)
|
||||
[step '(-1 -i 1 +i)]
|
||||
#:unless (eq? 'wall (hash-ref grid (+ pos step) 'wall)))
|
||||
(list pos (+ pos step)))))
|
||||
(define-values (distances predecessors) (dijkstra g source))
|
||||
distances)
|
||||
|
||||
(define (part12 program)
|
||||
(define grid (make-hash '((0 'floor))))
|
||||
(let loop ([vm (execute (start-machine program '()))]
|
||||
[pos 0]
|
||||
[i 0])
|
||||
(define direction (random-ref (possible-directions grid pos)))
|
||||
(define direction-code (match direction
|
||||
[+i 1]
|
||||
[-i 2]
|
||||
[-1 3]
|
||||
[1 4]))
|
||||
(define new-vm (execute (struct-copy machine vm [inputs (list direction-code)])))
|
||||
(define next-pos (+ pos direction))
|
||||
(unless (> i 100000)
|
||||
(match (car (machine-outputs new-vm))
|
||||
[0 (hash-set! grid next-pos 'wall)
|
||||
(loop new-vm pos (add1 i))]
|
||||
[1 (hash-set! grid next-pos 'floor)
|
||||
(loop new-vm next-pos (add1 i))]
|
||||
[2 (hash-set! grid next-pos 'oxygen)
|
||||
(loop new-vm next-pos (add1 i))])))
|
||||
(define oxygen (for/first ([(pos tile) (in-hash grid)]
|
||||
#:when (eq? 'oxygen tile))
|
||||
pos))
|
||||
(define distances (shortest-distances grid oxygen))
|
||||
(values (hash-ref distances 0)
|
||||
(apply max (hash-values distances))))
|
||||
|
||||
(module+ test
|
||||
(define-values (p1 p2) (part12 (parse-file "input")))
|
||||
(check-equal? p1 296)
|
||||
(check-equal? p2 302))
|
1
2019/day15/input
Normal file
1
2019/day15/input
Normal file
|
@ -0,0 +1 @@
|
|||
3,1033,1008,1033,1,1032,1005,1032,31,1008,1033,2,1032,1005,1032,58,1008,1033,3,1032,1005,1032,81,1008,1033,4,1032,1005,1032,104,99,102,1,1034,1039,1001,1036,0,1041,1001,1035,-1,1040,1008,1038,0,1043,102,-1,1043,1032,1,1037,1032,1042,1105,1,124,102,1,1034,1039,102,1,1036,1041,1001,1035,1,1040,1008,1038,0,1043,1,1037,1038,1042,1105,1,124,1001,1034,-1,1039,1008,1036,0,1041,101,0,1035,1040,1002,1038,1,1043,1001,1037,0,1042,1105,1,124,1001,1034,1,1039,1008,1036,0,1041,102,1,1035,1040,1002,1038,1,1043,102,1,1037,1042,1006,1039,217,1006,1040,217,1008,1039,40,1032,1005,1032,217,1008,1040,40,1032,1005,1032,217,1008,1039,5,1032,1006,1032,165,1008,1040,1,1032,1006,1032,165,1101,0,2,1044,1105,1,224,2,1041,1043,1032,1006,1032,179,1102,1,1,1044,1105,1,224,1,1041,1043,1032,1006,1032,217,1,1042,1043,1032,1001,1032,-1,1032,1002,1032,39,1032,1,1032,1039,1032,101,-1,1032,1032,101,252,1032,211,1007,0,56,1044,1105,1,224,1102,0,1,1044,1106,0,224,1006,1044,247,102,1,1039,1034,1001,1040,0,1035,101,0,1041,1036,102,1,1043,1038,102,1,1042,1037,4,1044,1106,0,0,40,31,67,22,98,81,11,5,82,25,86,22,69,15,21,97,6,6,62,50,91,14,90,37,26,50,98,4,55,61,39,20,93,19,70,47,50,8,85,97,24,91,12,79,38,62,13,99,4,63,48,75,93,2,4,62,72,51,63,23,12,8,80,87,54,13,99,85,2,66,45,93,13,2,87,86,14,25,27,12,87,49,58,51,77,25,5,97,13,35,48,64,63,11,76,32,18,79,37,88,12,85,85,4,69,71,29,27,66,33,7,66,72,51,74,87,13,48,42,34,67,26,13,96,25,65,83,46,72,99,25,62,3,50,72,99,65,37,75,39,68,39,11,75,27,70,90,39,62,69,31,17,57,43,27,28,54,87,7,97,72,25,93,30,59,20,74,59,7,8,94,96,36,86,9,35,81,74,21,73,15,59,6,80,42,5,67,34,55,95,96,31,98,70,50,17,64,36,79,34,31,20,58,60,9,4,55,39,94,49,17,95,81,85,31,26,62,80,4,71,80,17,37,80,97,9,16,25,89,6,46,76,50,99,20,62,73,6,79,66,96,2,42,72,45,96,30,94,73,42,38,63,12,36,68,70,50,54,26,74,49,92,26,33,38,66,65,79,90,55,37,71,48,66,5,57,86,17,42,89,5,97,81,46,99,74,19,69,13,86,60,93,7,16,86,42,81,26,95,91,93,14,94,76,91,33,44,42,58,87,26,41,9,22,63,1,82,63,20,49,50,71,75,5,32,73,14,45,98,50,91,54,69,61,27,60,40,88,16,34,18,64,18,50,81,67,67,28,95,7,89,80,37,26,97,25,29,58,77,60,22,22,43,64,15,66,69,33,20,50,84,70,53,11,64,80,16,80,74,15,90,67,33,12,57,8,52,78,10,18,25,40,82,63,93,93,28,18,51,68,58,6,60,58,14,54,72,68,91,41,70,67,3,74,18,3,27,65,71,11,11,99,49,88,21,42,7,78,35,4,78,2,2,82,26,65,97,67,46,63,1,68,55,85,94,16,1,22,41,67,86,35,10,83,64,11,95,50,46,86,74,5,68,81,62,22,75,68,26,58,40,62,44,38,65,22,69,20,90,5,10,42,99,96,51,63,64,7,64,36,92,89,54,4,68,63,85,9,38,95,89,51,50,75,86,5,41,40,59,31,82,99,8,95,5,43,45,60,60,29,84,15,5,96,64,55,97,44,35,7,93,96,43,22,50,20,70,81,39,8,90,50,66,49,31,29,34,97,90,1,59,3,5,82,85,85,47,29,6,65,31,70,76,33,35,82,43,98,62,29,44,76,70,59,89,30,25,97,83,75,79,43,98,93,40,59,36,55,64,29,31,98,65,47,33,91,75,62,71,68,38,33,81,10,73,83,6,13,88,92,45,94,15,1,88,59,22,7,36,89,59,36,12,80,3,80,78,29,85,75,28,7,15,82,41,1,81,26,7,72,46,85,71,16,40,73,11,81,7,24,10,87,75,9,87,35,40,86,5,16,69,98,45,43,8,68,20,83,73,47,86,77,35,89,71,1,37,62,62,65,44,26,83,52,87,89,40,62,61,97,7,42,79,9,1,64,99,86,5,86,51,23,25,32,71,28,91,26,87,64,47,17,2,90,64,42,10,85,36,31,79,75,79,21,59,5,9,88,12,36,74,59,72,6,82,34,80,10,78,81,33,91,22,94,18,88,10,63,23,87,58,65,20,66,74,65,18,96,22,98,13,86,48,67,14,96,58,73,14,67,2,65,48,92,42,93,18,96,32,81,0,0,21,21,1,10,1,0,0,0,0,0,0
|
73
2019/day16/day16.rkt
Normal file
73
2019/day16/day16.rkt
Normal file
|
@ -0,0 +1,73 @@
|
|||
#lang racket
|
||||
|
||||
(require racket/sequence)
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (pattern n i)
|
||||
(define index (remainder (add1 i) (* 4 n)))
|
||||
(cond
|
||||
[(< index n) 0]
|
||||
[(< index (* 2 n)) 1]
|
||||
[(< index (* 3 n)) 0]
|
||||
[(< index (* 4 n)) -1]))
|
||||
|
||||
(define (last-digit n)
|
||||
(abs (remainder n 10)))
|
||||
|
||||
(define (phase signal)
|
||||
(for/list ([i (in-range (length signal))])
|
||||
(last-digit (for/sum ([d (in-list signal)]
|
||||
[j (in-naturals)]
|
||||
#:when (>= j i))
|
||||
(* d (pattern (add1 i) j))))))
|
||||
|
||||
(define (number->digits n)
|
||||
(define (aux n)
|
||||
(define-values (q r) (quotient/remainder n 10))
|
||||
(if (> q 0)
|
||||
(cons r (aux q))
|
||||
(list r)))
|
||||
(reverse (aux n)))
|
||||
|
||||
(define (digits->number lst)
|
||||
(for/sum ([d (in-list (reverse lst))]
|
||||
[i (in-naturals)])
|
||||
(* d (expt 10 i))))
|
||||
|
||||
(define (apply-n-times f n x)
|
||||
(for/fold ([val x]) ([i (in-range n)])
|
||||
(f val)))
|
||||
|
||||
(define (part1 n)
|
||||
(digits->number (take (apply-n-times phase 100 n) 8)))
|
||||
|
||||
(module+ test
|
||||
(check-eq? (part1 (number->digits 80871224585914546619083218645595)) 24176176)
|
||||
(check-eq? (part1 (number->digits 19617804207202209144916044189917)) 73745418)
|
||||
(check-eq? (part1 (number->digits 69317163492948606335995924319873)) 52432133))
|
||||
|
||||
(module+ main
|
||||
(define input (number->digits
|
||||
(string->number
|
||||
(string-trim
|
||||
(port->string (open-input-file "input") #:close? #t)))))
|
||||
(displayln (part1 input)))
|
||||
|
||||
(define (phase2 signal)
|
||||
(define-values (s res)
|
||||
(for/fold ([s (apply + signal)]
|
||||
[res '()])
|
||||
([d (in-list signal)])
|
||||
(values (- s d) (cons (last-digit s) res))))
|
||||
(reverse res))
|
||||
|
||||
(define (part2 input)
|
||||
(define offset (digits->number (take input 7)))
|
||||
(define n (drop input offset))
|
||||
(digits->number (take (apply-n-times phase2 100 n) 8)))
|
||||
|
||||
(module+ main
|
||||
(define input2 (flatten (make-list 10000 input)))
|
||||
(displayln (part2 input2)))
|
1
2019/day16/input
Normal file
1
2019/day16/input
Normal file
|
@ -0,0 +1 @@
|
|||
59749012692497360857047467554796667139266971954850723493205431123165826080869880148759586023048633544809012786925668551639957826693687972765764376332866751104713940802555266397289142675218037547096634248307260671899871548313611756525442595930474639845266351381011380170903695947253040751698337167594183713030695951696818950161554630424143678657203441568388368475123279525515262317457621810448095399401556723919452322199989580496608898965260381604485810760050252737127446449982328185199195622241930968611065497781555948187157418339240689789877555108205275435831320988202725926797165070246910002881692028525921087207954194585166525017611171911807360959
|
105
2019/day17/day17.rkt
Normal file
105
2019/day17/day17.rkt
Normal file
|
@ -0,0 +1,105 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../intcode.rkt"
|
||||
racket/match
|
||||
racket/set
|
||||
racket/list
|
||||
racket/string)
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (get-grid program)
|
||||
(define vm (execute (start-machine program '())))
|
||||
(define map-str (list->ascii (reverse (machine-outputs vm))))
|
||||
(define-values (grid robot-pos robot-dir pos)
|
||||
(for/fold ([grid (set)]
|
||||
[robot-pos #f]
|
||||
[robot-dir #f]
|
||||
[pos 0])
|
||||
([c (in-list (reverse (machine-outputs vm)))])
|
||||
(match (integer->char c)
|
||||
[#\newline (values grid robot-pos robot-dir (make-rectangular 0 (add1 (imag-part pos))))]
|
||||
[#\# (values (set-add grid pos) robot-pos robot-dir (add1 pos))]
|
||||
[#\^ (values grid pos -i (add1 pos))]
|
||||
[#\v (values grid pos +i (add1 pos))]
|
||||
[#\< (values grid pos -1 (add1 pos))]
|
||||
[#\> (values grid pos 1 (add1 pos))]
|
||||
[x (values grid robot-pos robot-dir (add1 pos))])))
|
||||
(values map-str grid robot-pos robot-dir))
|
||||
|
||||
(define (part1 program)
|
||||
(define-values (map-str grid robot-pos robot-dir) (get-grid program))
|
||||
(define intersections
|
||||
(for/list ([x (in-set grid)]
|
||||
#:when (for/and ([step '(-i -1 +i 1)])
|
||||
(set-member? grid (+ x step))))
|
||||
x))
|
||||
(for/sum ([int (in-list intersections)])
|
||||
(* (real-part int) (imag-part int))))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 (parse-file "input")) 5972))
|
||||
|
||||
(define (find-direction grid robot-pos robot-dir)
|
||||
(for/first ([step '(-i +i -1 1)]
|
||||
#:unless (= step (- robot-dir))
|
||||
#:when (set-member? grid (+ robot-pos step)))
|
||||
step))
|
||||
|
||||
(define (get-path grid robot-pos robot-dir)
|
||||
(define path
|
||||
(let loop ([pos robot-pos]
|
||||
[dir robot-dir]
|
||||
[len 0]
|
||||
[path '()])
|
||||
(if (set-member? grid (+ pos dir))
|
||||
(loop (+ pos dir) dir (add1 len) path)
|
||||
(let ([new-dir (find-direction grid pos dir)]
|
||||
[new-path (cons len path)])
|
||||
(if new-dir
|
||||
(loop pos new-dir 0 (cons (match (/ new-dir dir) [+i 'R] [-i 'L]) new-path))
|
||||
(cdr (reverse new-path)))))))
|
||||
path)
|
||||
|
||||
(define (remove-substring lst sublst)
|
||||
(cond
|
||||
[(empty? lst) '()]
|
||||
[(list-prefix? sublst lst) (remove-substring (drop lst (length sublst)) sublst)]
|
||||
[else (cons (car lst) (remove-substring (cdr lst) sublst))]))
|
||||
|
||||
(define (compress path)
|
||||
(define (prefixes lst)
|
||||
(for/list ([size (in-range 2 10 2)])
|
||||
(take lst size)))
|
||||
(define possibilities
|
||||
(for*/list ([a (in-list (prefixes path))]
|
||||
[b (in-list (prefixes (remove-substring path a)))]
|
||||
[c (in-list (prefixes (remove-substring (remove-substring path a) b)))]
|
||||
#:when (empty? (remove-substring (remove-substring (remove-substring path a) b) c)))
|
||||
(list a b c)))
|
||||
(for/last ([poss (in-list possibilities)])
|
||||
(match-define (list a b c) poss)
|
||||
(define result (let loop ([lst path])
|
||||
(cond
|
||||
[(empty? lst) '()]
|
||||
[(list-prefix? c lst) (cons 'C (loop (drop lst (length c))))]
|
||||
[(list-prefix? b lst) (cons 'B (loop (drop lst (length b))))]
|
||||
[(list-prefix? a lst) (cons 'A (loop (drop lst (length a))))]
|
||||
[else '(#f)])))
|
||||
#:final (last result)
|
||||
(list result a b c)))
|
||||
|
||||
(define (lst->str path)
|
||||
(string-join (map (λ (v) (format "~a" v)) path) ","))
|
||||
|
||||
(define (part2 program)
|
||||
(define-values (map-str grid robot-pos robot-dir) (get-grid program))
|
||||
(define path (get-path grid robot-pos robot-dir))
|
||||
(define inputs (string-join (append (map lst->str (compress path)) '("n\n")) "\n"))
|
||||
(vector-set! program 0 2)
|
||||
(define vm (execute (start-machine program inputs)))
|
||||
(car (machine-outputs vm)))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part2 (parse-file "input")) 933214))
|
1
2019/day17/input
Normal file
1
2019/day17/input
Normal file
|
@ -0,0 +1 @@
|
|||
1,330,331,332,109,3546,1101,0,1182,15,1101,1481,0,24,1001,0,0,570,1006,570,36,102,1,571,0,1001,570,-1,570,1001,24,1,24,1105,1,18,1008,571,0,571,1001,15,1,15,1008,15,1481,570,1006,570,14,21102,58,1,0,1106,0,786,1006,332,62,99,21101,0,333,1,21101,0,73,0,1106,0,579,1101,0,0,572,1101,0,0,573,3,574,101,1,573,573,1007,574,65,570,1005,570,151,107,67,574,570,1005,570,151,1001,574,-64,574,1002,574,-1,574,1001,572,1,572,1007,572,11,570,1006,570,165,101,1182,572,127,1002,574,1,0,3,574,101,1,573,573,1008,574,10,570,1005,570,189,1008,574,44,570,1006,570,158,1105,1,81,21102,1,340,1,1106,0,177,21102,1,477,1,1106,0,177,21101,0,514,1,21102,1,176,0,1105,1,579,99,21102,1,184,0,1106,0,579,4,574,104,10,99,1007,573,22,570,1006,570,165,102,1,572,1182,21102,375,1,1,21101,211,0,0,1106,0,579,21101,1182,11,1,21101,0,222,0,1106,0,979,21102,388,1,1,21102,1,233,0,1106,0,579,21101,1182,22,1,21102,1,244,0,1106,0,979,21101,0,401,1,21102,255,1,0,1106,0,579,21101,1182,33,1,21102,266,1,0,1105,1,979,21102,414,1,1,21102,1,277,0,1105,1,579,3,575,1008,575,89,570,1008,575,121,575,1,575,570,575,3,574,1008,574,10,570,1006,570,291,104,10,21102,1,1182,1,21102,1,313,0,1105,1,622,1005,575,327,1102,1,1,575,21101,0,327,0,1106,0,786,4,438,99,0,1,1,6,77,97,105,110,58,10,33,10,69,120,112,101,99,116,101,100,32,102,117,110,99,116,105,111,110,32,110,97,109,101,32,98,117,116,32,103,111,116,58,32,0,12,70,117,110,99,116,105,111,110,32,65,58,10,12,70,117,110,99,116,105,111,110,32,66,58,10,12,70,117,110,99,116,105,111,110,32,67,58,10,23,67,111,110,116,105,110,117,111,117,115,32,118,105,100,101,111,32,102,101,101,100,63,10,0,37,10,69,120,112,101,99,116,101,100,32,82,44,32,76,44,32,111,114,32,100,105,115,116,97,110,99,101,32,98,117,116,32,103,111,116,58,32,36,10,69,120,112,101,99,116,101,100,32,99,111,109,109,97,32,111,114,32,110,101,119,108,105,110,101,32,98,117,116,32,103,111,116,58,32,43,10,68,101,102,105,110,105,116,105,111,110,115,32,109,97,121,32,98,101,32,97,116,32,109,111,115,116,32,50,48,32,99,104,97,114,97,99,116,101,114,115,33,10,94,62,118,60,0,1,0,-1,-1,0,1,0,0,0,0,0,0,1,12,18,0,109,4,2102,1,-3,587,20101,0,0,-1,22101,1,-3,-3,21101,0,0,-2,2208,-2,-1,570,1005,570,617,2201,-3,-2,609,4,0,21201,-2,1,-2,1106,0,597,109,-4,2106,0,0,109,5,2102,1,-4,630,20102,1,0,-2,22101,1,-4,-4,21101,0,0,-3,2208,-3,-2,570,1005,570,781,2201,-4,-3,653,20102,1,0,-1,1208,-1,-4,570,1005,570,709,1208,-1,-5,570,1005,570,734,1207,-1,0,570,1005,570,759,1206,-1,774,1001,578,562,684,1,0,576,576,1001,578,566,692,1,0,577,577,21101,0,702,0,1105,1,786,21201,-1,-1,-1,1106,0,676,1001,578,1,578,1008,578,4,570,1006,570,724,1001,578,-4,578,21102,731,1,0,1105,1,786,1106,0,774,1001,578,-1,578,1008,578,-1,570,1006,570,749,1001,578,4,578,21102,1,756,0,1105,1,786,1105,1,774,21202,-1,-11,1,22101,1182,1,1,21101,0,774,0,1106,0,622,21201,-3,1,-3,1106,0,640,109,-5,2106,0,0,109,7,1005,575,802,21001,576,0,-6,20102,1,577,-5,1106,0,814,21102,1,0,-1,21102,0,1,-5,21102,0,1,-6,20208,-6,576,-2,208,-5,577,570,22002,570,-2,-2,21202,-5,59,-3,22201,-6,-3,-3,22101,1481,-3,-3,2101,0,-3,843,1005,0,863,21202,-2,42,-4,22101,46,-4,-4,1206,-2,924,21102,1,1,-1,1105,1,924,1205,-2,873,21102,35,1,-4,1105,1,924,2101,0,-3,878,1008,0,1,570,1006,570,916,1001,374,1,374,1202,-3,1,895,1101,0,2,0,2101,0,-3,902,1001,438,0,438,2202,-6,-5,570,1,570,374,570,1,570,438,438,1001,578,558,921,21002,0,1,-4,1006,575,959,204,-4,22101,1,-6,-6,1208,-6,59,570,1006,570,814,104,10,22101,1,-5,-5,1208,-5,35,570,1006,570,810,104,10,1206,-1,974,99,1206,-1,974,1101,0,1,575,21102,973,1,0,1105,1,786,99,109,-7,2105,1,0,109,6,21101,0,0,-4,21102,0,1,-3,203,-2,22101,1,-3,-3,21208,-2,82,-1,1205,-1,1030,21208,-2,76,-1,1205,-1,1037,21207,-2,48,-1,1205,-1,1124,22107,57,-2,-1,1205,-1,1124,21201,-2,-48,-2,1106,0,1041,21102,1,-4,-2,1106,0,1041,21101,0,-5,-2,21201,-4,1,-4,21207,-4,11,-1,1206,-1,1138,2201,-5,-4,1059,1202,-2,1,0,203,-2,22101,1,-3,-3,21207,-2,48,-1,1205,-1,1107,22107,57,-2,-1,1205,-1,1107,21201,-2,-48,-2,2201,-5,-4,1090,20102,10,0,-1,22201,-2,-1,-2,2201,-5,-4,1103,1202,-2,1,0,1105,1,1060,21208,-2,10,-1,1205,-1,1162,21208,-2,44,-1,1206,-1,1131,1105,1,989,21101,0,439,1,1106,0,1150,21102,477,1,1,1106,0,1150,21101,0,514,1,21102,1,1149,0,1105,1,579,99,21101,0,1157,0,1106,0,579,204,-2,104,10,99,21207,-3,22,-1,1206,-1,1138,2101,0,-5,1176,1201,-4,0,0,109,-6,2105,1,0,6,13,27,13,6,1,11,1,27,1,11,1,6,1,11,1,27,1,11,1,6,1,11,1,27,1,11,1,6,1,11,1,27,1,11,1,6,1,11,1,27,1,11,1,6,1,11,1,1,9,9,11,9,1,6,1,11,1,1,1,7,1,9,1,7,1,1,1,9,1,6,1,11,13,7,1,7,1,1,1,9,1,6,1,13,1,7,1,1,1,7,1,7,1,1,1,9,1,6,1,13,1,7,1,1,1,5,11,1,1,9,1,6,1,13,1,7,1,1,1,5,1,1,1,9,1,9,1,6,11,3,1,7,1,1,1,5,1,1,1,9,1,1,9,16,1,3,1,7,1,1,1,5,1,1,1,9,1,1,1,24,1,3,1,7,13,7,1,1,1,24,1,3,1,9,1,5,1,1,1,1,1,7,1,1,1,24,1,3,1,9,9,1,1,7,11,16,1,3,1,15,1,3,1,9,1,7,1,12,9,15,1,3,1,9,1,7,1,16,1,19,1,3,1,9,1,7,1,16,1,19,11,3,1,7,1,16,1,23,1,5,1,3,1,7,1,8,9,23,11,7,1,8,1,37,1,11,1,8,1,37,1,11,1,8,1,37,1,11,1,8,1,37,1,11,1,8,1,37,1,11,1,8,1,37,13,8,1,58,1,58,1,58,1,58,1,50,9,50
|
29
2019/day19/day19.rkt
Normal file
29
2019/day19/day19.rkt
Normal file
|
@ -0,0 +1,29 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../intcode.rkt")
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (pulled? program x y)
|
||||
(define vm (execute (start-machine program (list x y))))
|
||||
(= 1 (car (machine-outputs vm))))
|
||||
|
||||
(define (part1 program)
|
||||
(length (for*/list ([x (in-range 50)]
|
||||
[y (in-range 50)]
|
||||
#:when (pulled? program x y))
|
||||
(list x y))))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 (parse-file "input")) 229))
|
||||
|
||||
(define (part2 program)
|
||||
(let loop ([x 0] [y 99])
|
||||
(cond
|
||||
[(not (pulled? program x y)) (loop (add1 x) y)]
|
||||
[(pulled? program (+ x 99) (- y 99)) (+ (* 10000 x) (- y 99))]
|
||||
[else (loop x (add1 y))])))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part2 (parse-file "input")) 6950903))
|
1
2019/day19/input
Normal file
1
2019/day19/input
Normal file
|
@ -0,0 +1 @@
|
|||
109,424,203,1,21101,11,0,0,1105,1,282,21102,1,18,0,1106,0,259,1201,1,0,221,203,1,21101,0,31,0,1106,0,282,21101,0,38,0,1105,1,259,21002,23,1,2,21201,1,0,3,21101,0,1,1,21101,0,57,0,1106,0,303,2102,1,1,222,21002,221,1,3,20102,1,221,2,21102,259,1,1,21101,0,80,0,1105,1,225,21102,1,118,2,21102,91,1,0,1105,1,303,2102,1,1,223,21001,222,0,4,21102,259,1,3,21101,0,225,2,21101,225,0,1,21101,0,118,0,1105,1,225,20101,0,222,3,21102,1,72,2,21102,133,1,0,1106,0,303,21202,1,-1,1,22001,223,1,1,21102,1,148,0,1105,1,259,1201,1,0,223,20101,0,221,4,20101,0,222,3,21101,22,0,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21102,1,195,0,106,0,108,20207,1,223,2,20101,0,23,1,21102,-1,1,3,21102,214,1,0,1105,1,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,1201,-4,0,249,22101,0,-3,1,22101,0,-2,2,22101,0,-1,3,21101,0,250,0,1105,1,225,21202,1,1,-4,109,-5,2105,1,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2106,0,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,22102,1,-2,-2,109,-3,2105,1,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,22101,0,-2,3,21101,0,343,0,1106,0,303,1105,1,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,21202,-4,1,1,21101,384,0,0,1106,0,303,1106,0,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,21201,1,0,-4,109,-5,2106,0,0
|
43
2019/day21/day21.rkt
Normal file
43
2019/day21/day21.rkt
Normal file
|
@ -0,0 +1,43 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../intcode.rkt")
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (part1 program)
|
||||
(define inputs #<<EOF
|
||||
OR A J
|
||||
AND B J
|
||||
AND C J
|
||||
NOT J J
|
||||
AND D J
|
||||
WALK
|
||||
|
||||
EOF
|
||||
)
|
||||
(define vm (execute (start-machine program inputs)))
|
||||
(car (machine-outputs vm)))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 (parse-file "input")) 19359533))
|
||||
|
||||
(define (part2 program)
|
||||
(define inputs #<<EOF
|
||||
OR A J
|
||||
AND B J
|
||||
AND C J
|
||||
NOT J J
|
||||
AND D J
|
||||
OR E T
|
||||
OR H T
|
||||
AND T J
|
||||
RUN
|
||||
|
||||
EOF
|
||||
)
|
||||
(define vm (execute (start-machine program inputs)))
|
||||
(car (machine-outputs vm)))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part2 (parse-file "input")) 1140310551))
|
1
2019/day21/input
Normal file
1
2019/day21/input
Normal file
File diff suppressed because one or more lines are too long
117
2019/day22/day22.rkt
Normal file
117
2019/day22/day22.rkt
Normal file
|
@ -0,0 +1,117 @@
|
|||
#lang racket
|
||||
|
||||
(require racket/string
|
||||
math/number-theory)
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(module+ main
|
||||
(displayln "Day 22"))
|
||||
|
||||
(define (read-instructions filename)
|
||||
(with-input-from-file filename
|
||||
(lambda ()
|
||||
(for/list ([line (in-lines)])
|
||||
(cond
|
||||
[(string-prefix? line "deal into new stack") 'deal]
|
||||
[(string-prefix? line "cut") `(cut ,(string->number (last (string-split line " "))))]
|
||||
[(string-prefix? line "deal with increment") `(increment ,(string->number (last (string-split line " "))))]
|
||||
[else 'other])))))
|
||||
|
||||
(define (deal deck)
|
||||
(reverse deck))
|
||||
|
||||
(define (cut deck n)
|
||||
(define split-fn (if (> n 0) split-at split-at-right))
|
||||
(define-values (a b) (split-fn deck (abs n)))
|
||||
(append b a))
|
||||
|
||||
(define (increment deck n)
|
||||
(for/list ([i (in-range (length deck))])
|
||||
(list-ref deck
|
||||
(remainder (* i (modular-inverse n (length deck))) (length deck)))))
|
||||
|
||||
(define (execute instruction deck)
|
||||
(match instruction
|
||||
['deal (deal deck)]
|
||||
[(list 'cut n) (cut deck n)]
|
||||
[(list 'increment n) (increment deck n)]))
|
||||
|
||||
(define (shuffle deck instructions)
|
||||
(for/fold ([d deck]) ([i instructions])
|
||||
(execute i d)))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (shuffle (range 10) (read-instructions "test1")) '(0 3 6 9 2 5 8 1 4 7))
|
||||
(check-equal? (shuffle (range 10) (read-instructions "test2")) '(3 0 7 4 1 8 5 2 9 6))
|
||||
(check-equal? (shuffle (range 10) (read-instructions "test3")) '(6 3 0 7 4 1 8 5 2 9))
|
||||
(check-equal? (shuffle (range 10) (read-instructions "test4")) '(9 2 5 8 1 4 7 0 3 6)))
|
||||
|
||||
(module+ main
|
||||
(displayln "Part 1:")
|
||||
(define instructions (read-instructions "input"))
|
||||
(define deck (range 10007))
|
||||
(time (index-of (shuffle deck instructions) 2019)))
|
||||
|
||||
(define (deal-card deck-size card)
|
||||
(- (sub1 deck-size) card))
|
||||
|
||||
(define (cut-card deck-size n card)
|
||||
(modulo (- card n) deck-size))
|
||||
|
||||
(define (increment-card deck-size n card)
|
||||
(modulo (* n card) deck-size))
|
||||
|
||||
(define (execute-card deck-size instruction card)
|
||||
(match instruction
|
||||
['deal (deal-card deck-size card)]
|
||||
[(list 'cut n) (cut-card deck-size n card)]
|
||||
[(list 'increment n) (increment-card deck-size n card)]))
|
||||
|
||||
(define (shuffle-card deck-size instructions card)
|
||||
(for/fold ([c card]) ([i instructions])
|
||||
(execute-card deck-size i c)))
|
||||
|
||||
(module+ main
|
||||
(displayln "Part 1 (better):")
|
||||
(time (shuffle-card 10007 instructions 2019)))
|
||||
|
||||
(define (deal-card-inv deck-size card)
|
||||
(- (sub1 deck-size) card))
|
||||
|
||||
(define (cut-card-inv deck-size n card)
|
||||
(modulo (+ card n) deck-size))
|
||||
|
||||
(define (increment-card-inv deck-size n card)
|
||||
(remainder (* card (modular-inverse n deck-size)) deck-size))
|
||||
|
||||
(define (execute-card-inv deck-size instruction card)
|
||||
(match instruction
|
||||
['deal (deal-card-inv deck-size card)]
|
||||
[(list 'cut n) (cut-card-inv deck-size n card)]
|
||||
[(list 'increment n) (increment-card-inv deck-size n card)]))
|
||||
|
||||
(define (shuffle-card-inv deck-size reversed-instructions card)
|
||||
(for/fold ([c card]) ([i reversed-instructions])
|
||||
(execute-card-inv deck-size i c)))
|
||||
|
||||
(module+ main
|
||||
(displayln "Part 2:")
|
||||
(define deck-size 119315717514047)
|
||||
(define iterations 101741582076661)
|
||||
|
||||
;; Operations are linear, we find the coefficients and apply them directly
|
||||
(define x 2020)
|
||||
(define y (shuffle-card-inv deck-size (reverse instructions) x))
|
||||
(define z (shuffle-card-inv deck-size (reverse instructions) y))
|
||||
|
||||
(define a (modulo (* (- z y) (modular-inverse (- y x) deck-size)) deck-size))
|
||||
(define b (modulo (- y (* a x)) deck-size))
|
||||
|
||||
(modulo (+ (* (modular-expt a iterations deck-size)
|
||||
x)
|
||||
(* (sub1 (modular-expt a iterations deck-size))
|
||||
(modular-inverse (sub1 a) deck-size)
|
||||
b))
|
||||
deck-size))
|
100
2019/day22/input
Normal file
100
2019/day22/input
Normal file
|
@ -0,0 +1,100 @@
|
|||
deal with increment 55
|
||||
cut -6984
|
||||
deal into new stack
|
||||
cut -2833
|
||||
deal with increment 75
|
||||
cut 2488
|
||||
deal with increment 54
|
||||
cut 9056
|
||||
deal with increment 52
|
||||
cut -2717
|
||||
deal with increment 4
|
||||
deal into new stack
|
||||
cut -852
|
||||
deal with increment 21
|
||||
cut -3041
|
||||
deal with increment 38
|
||||
cut -6871
|
||||
deal into new stack
|
||||
deal with increment 32
|
||||
cut 988
|
||||
deal with increment 29
|
||||
deal into new stack
|
||||
deal with increment 68
|
||||
cut 5695
|
||||
deal with increment 36
|
||||
cut -27
|
||||
deal with increment 33
|
||||
deal into new stack
|
||||
cut -1306
|
||||
deal with increment 30
|
||||
cut -4033
|
||||
deal with increment 28
|
||||
cut -442
|
||||
deal into new stack
|
||||
deal with increment 30
|
||||
cut -6295
|
||||
deal with increment 56
|
||||
cut -4065
|
||||
deal into new stack
|
||||
cut 5275
|
||||
deal with increment 64
|
||||
cut 9747
|
||||
deal into new stack
|
||||
deal with increment 63
|
||||
cut -3772
|
||||
deal with increment 61
|
||||
deal into new stack
|
||||
cut 1021
|
||||
deal with increment 73
|
||||
deal into new stack
|
||||
deal with increment 7
|
||||
cut -1232
|
||||
deal with increment 52
|
||||
cut -3439
|
||||
deal with increment 31
|
||||
cut 1128
|
||||
deal into new stack
|
||||
deal with increment 55
|
||||
deal into new stack
|
||||
deal with increment 39
|
||||
cut -3424
|
||||
deal with increment 11
|
||||
deal into new stack
|
||||
cut 4139
|
||||
deal with increment 15
|
||||
deal into new stack
|
||||
cut 5333
|
||||
deal with increment 16
|
||||
cut -6787
|
||||
deal with increment 39
|
||||
cut -5817
|
||||
deal into new stack
|
||||
deal with increment 62
|
||||
cut -2704
|
||||
deal with increment 64
|
||||
deal into new stack
|
||||
deal with increment 70
|
||||
cut 3436
|
||||
deal with increment 65
|
||||
cut -8686
|
||||
deal with increment 22
|
||||
cut -6190
|
||||
deal with increment 13
|
||||
cut -100
|
||||
deal into new stack
|
||||
cut -619
|
||||
deal into new stack
|
||||
cut 3079
|
||||
deal with increment 53
|
||||
cut 1725
|
||||
deal with increment 19
|
||||
cut 3440
|
||||
deal with increment 64
|
||||
cut 8578
|
||||
deal with increment 5
|
||||
cut 2341
|
||||
deal with increment 45
|
||||
cut 2217
|
||||
deal with increment 13
|
||||
deal into new stack
|
3
2019/day22/test1
Normal file
3
2019/day22/test1
Normal file
|
@ -0,0 +1,3 @@
|
|||
deal with increment 7
|
||||
deal into new stack
|
||||
deal into new stack
|
3
2019/day22/test2
Normal file
3
2019/day22/test2
Normal file
|
@ -0,0 +1,3 @@
|
|||
cut 6
|
||||
deal with increment 7
|
||||
deal into new stack
|
3
2019/day22/test3
Normal file
3
2019/day22/test3
Normal file
|
@ -0,0 +1,3 @@
|
|||
deal with increment 7
|
||||
deal with increment 9
|
||||
cut -2
|
10
2019/day22/test4
Normal file
10
2019/day22/test4
Normal file
|
@ -0,0 +1,10 @@
|
|||
deal into new stack
|
||||
cut -2
|
||||
deal with increment 7
|
||||
cut 8
|
||||
cut -4
|
||||
deal with increment 7
|
||||
cut 3
|
||||
deal with increment 9
|
||||
deal with increment 3
|
||||
cut -1
|
30
2019/day23/day23.rkt
Normal file
30
2019/day23/day23.rkt
Normal file
|
@ -0,0 +1,30 @@
|
|||
#lang racket/base
|
||||
|
||||
(require "../intcode.rkt"
|
||||
racket/match
|
||||
racket/list)
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (get-packets vms)
|
||||
(let loop ([packets (reverse (append* (map machine-outputs vms)))]
|
||||
[h (hash)])
|
||||
(match packets
|
||||
['() h]
|
||||
[(list* addr x y r) (loop r (hash-update h addr (λ (lst) (append (list x y) lst)) '()))])))
|
||||
|
||||
(define (part1 program)
|
||||
(define vms (for/list ([i (in-range 50)])
|
||||
(execute (start-machine program (list i)))))
|
||||
(let loop ([vms vms])
|
||||
(define packets (get-packets vms))
|
||||
(if (hash-has-key? packets 255)
|
||||
(cadr (hash-ref packets 255))
|
||||
(loop
|
||||
(for/list ([i (in-range 50)]
|
||||
[vm (in-list vms)])
|
||||
(execute (struct-copy machine vm [inputs (hash-ref packets i '(-1))])))))))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 (parse-file "input")) 23266))
|
1
2019/day23/input
Normal file
1
2019/day23/input
Normal file
File diff suppressed because one or more lines are too long
66
2019/day24/day24.rkt
Normal file
66
2019/day24/day24.rkt
Normal file
|
@ -0,0 +1,66 @@
|
|||
#lang racket
|
||||
|
||||
(module+ test
|
||||
(require rackunit))
|
||||
|
||||
(define (read-input filename)
|
||||
(for/set ([line (file->lines filename)]
|
||||
[i (in-naturals)]
|
||||
#:when #t
|
||||
[c (in-string line)]
|
||||
[j (in-naturals)]
|
||||
#:when (eq? c #\#))
|
||||
(make-rectangular j i)))
|
||||
|
||||
(define (grid-size grid)
|
||||
(define indices (flatten (map (λ (x) (list (real-part x) (imag-part x))) (set->list grid))))
|
||||
(add1 (apply max indices)))
|
||||
|
||||
(define (display-grid grid)
|
||||
(define size (grid-size grid))
|
||||
(for ([j (in-range size)])
|
||||
(for ([i (in-range size)])
|
||||
(if (set-member? grid (make-rectangular i j))
|
||||
(printf "#")
|
||||
(printf ".")))
|
||||
(printf "~n")))
|
||||
|
||||
(define (count-neighbours grid pos)
|
||||
(for/sum ([step '(-i -1 +i 1)]
|
||||
#:when (set-member? grid (+ pos step)))
|
||||
1))
|
||||
|
||||
(define (lives? grid pos)
|
||||
(define n (count-neighbours grid pos))
|
||||
(define alive (set-member? grid pos))
|
||||
(cond
|
||||
[(and alive (not (= 1 n))) #f]
|
||||
[(and (not alive) (or (= 1 n) (= 2 n))) #t]
|
||||
[else alive]))
|
||||
|
||||
(define (step grid)
|
||||
(define size (grid-size grid))
|
||||
(for*/set ([i (in-range size)]
|
||||
[j (in-range size)]
|
||||
#:when (lives? grid (make-rectangular i j)))
|
||||
(make-rectangular i j)))
|
||||
|
||||
(define (biodiversity-rating grid)
|
||||
(define size (grid-size grid))
|
||||
(for*/sum ([i (in-range size)]
|
||||
[j (in-range size)]
|
||||
#:when (set-member? grid (make-rectangular i j)))
|
||||
(expt 2 (+ i (* j size)))))
|
||||
|
||||
(define (part1 filename)
|
||||
(define grid (read-input filename))
|
||||
(define final
|
||||
(car (for/fold ([grids (list grid)])
|
||||
([i (in-naturals)]
|
||||
#:break (member (car grids) (cdr grids)))
|
||||
(cons (step (car grids)) grids))))
|
||||
(biodiversity-rating final))
|
||||
|
||||
(module+ test
|
||||
(check-equal? (part1 "test") 2129920)
|
||||
(check-equal? (part1 "input") 32573535))
|
5
2019/day24/input
Normal file
5
2019/day24/input
Normal file
|
@ -0,0 +1,5 @@
|
|||
..#.#
|
||||
#.##.
|
||||
.#..#
|
||||
#....
|
||||
....#
|
5
2019/day24/test
Normal file
5
2019/day24/test
Normal file
|
@ -0,0 +1,5 @@
|
|||
....#
|
||||
#..#.
|
||||
#..##
|
||||
..#..
|
||||
#....
|
158
2019/intcode.rkt
Normal file
158
2019/intcode.rkt
Normal file
|
@ -0,0 +1,158 @@
|
|||
#lang racket/base
|
||||
|
||||
(provide parse
|
||||
parse-file
|
||||
(struct-out machine)
|
||||
start-machine
|
||||
ascii->list
|
||||
list->ascii
|
||||
execute)
|
||||
|
||||
(require racket/list
|
||||
racket/string
|
||||
racket/file
|
||||
racket/match)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Program I/O ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (parse str)
|
||||
(list->vector (map string->number (map string-trim (string-split str ",")))))
|
||||
|
||||
(define (parse-file filename)
|
||||
(parse (string-trim (file->string filename))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Instructions ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(struct instruction
|
||||
(name
|
||||
parameter-modes
|
||||
inparams
|
||||
outparams)
|
||||
#:transparent)
|
||||
|
||||
(define opcodes
|
||||
(hash
|
||||
99 'terminate
|
||||
1 '(add 2 1)
|
||||
2 '(mul 2 1)
|
||||
3 '(input 0 1)
|
||||
4 '(output 1 0)
|
||||
5 '(jmpt 2 0)
|
||||
6 '(jmpf 2 0)
|
||||
7 '(lt 2 1)
|
||||
8 '(eq 2 1)
|
||||
9 '(rel 1 0)))
|
||||
|
||||
(define (parse-instruction program pc relative-base)
|
||||
(define opcode (vector-ref program pc))
|
||||
|
||||
(define-values (name nin nout)
|
||||
(match (hash-ref opcodes (remainder opcode 100))
|
||||
[(list name n m) (values name n m)]
|
||||
[name (values name 0 0)]))
|
||||
|
||||
(define parameter-modes (make-hash))
|
||||
(for/fold ([n (quotient opcode 100)])
|
||||
([i (in-naturals)]
|
||||
#:break (= n 0))
|
||||
(hash-set! parameter-modes i (remainder n 10))
|
||||
(quotient n 10))
|
||||
|
||||
(define inparams
|
||||
(for/list ([i (in-range nin)])
|
||||
(match (hash-ref parameter-modes i 0)
|
||||
[0 (vector-ref program (vector-ref program (+ pc i 1)))]
|
||||
[1 (vector-ref program (+ pc i 1))]
|
||||
[2 (vector-ref program (+ relative-base (vector-ref program (+ pc i 1))))])))
|
||||
|
||||
(define outparams
|
||||
(for/list ([i (in-range nout)])
|
||||
(match (hash-ref parameter-modes (+ nin i) 0)
|
||||
[0 (vector-ref program (+ pc nin i 1))]
|
||||
[1 (error "output parameter cannot be in immediate mode" name pc)]
|
||||
[2 (+ relative-base (vector-ref program (+ pc nin i 1)))])))
|
||||
|
||||
(instruction name parameter-modes inparams outparams))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Virtual machine interfaces ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(struct machine
|
||||
(program
|
||||
inputs
|
||||
pc
|
||||
relative-base
|
||||
terminated
|
||||
outputs)
|
||||
#:transparent
|
||||
#:guard (lambda (program inputs pc relative-base terminated outputs name)
|
||||
(when (not (<= 0 pc (vector-length program)))
|
||||
(error "invalid program counter" pc))
|
||||
(values program
|
||||
(preprocess-inputs inputs)
|
||||
pc
|
||||
relative-base
|
||||
terminated outputs)))
|
||||
|
||||
(define (start-machine program inputs)
|
||||
(machine program inputs 0 0 #f '()))
|
||||
|
||||
(define (ascii->list str)
|
||||
(map char->integer (string->list str)))
|
||||
|
||||
(define (list->ascii lst)
|
||||
(list->string (map integer->char lst)))
|
||||
|
||||
(define (preprocess-inputs inputs)
|
||||
(cond
|
||||
[(list? inputs) inputs]
|
||||
[(string? inputs) (ascii->list inputs)]
|
||||
[else (error "unsupported input type: " inputs)]))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
; Virtual machine execution ;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(define (execute vm)
|
||||
(define p (make-vector 10000 0))
|
||||
(vector-copy! p 0 (machine-program vm))
|
||||
|
||||
(let loop ([pc (machine-pc vm)]
|
||||
[relative-base (machine-relative-base vm)]
|
||||
[inputs (machine-inputs vm)]
|
||||
[outputs (machine-outputs vm)])
|
||||
(define instr (parse-instruction p pc relative-base))
|
||||
(define inparams (instruction-inparams instr))
|
||||
(define outparams (instruction-outparams instr))
|
||||
(define next-pc (+ pc (length inparams) (length outparams) 1))
|
||||
|
||||
(match (instruction-name instr)
|
||||
['terminate (machine p inputs pc relative-base #t outputs)]
|
||||
['add (vector-set! p (car outparams) (apply + inparams))
|
||||
(loop next-pc relative-base inputs outputs)]
|
||||
['mul (vector-set! p (car outparams) (apply * inparams))
|
||||
(loop next-pc relative-base inputs outputs)]
|
||||
['input (if (empty? inputs)
|
||||
(machine p inputs pc relative-base #f outputs)
|
||||
(begin
|
||||
(vector-set! p (car outparams) (car inputs))
|
||||
(loop next-pc relative-base (cdr inputs) outputs)))]
|
||||
['output (loop next-pc relative-base inputs (cons (car inparams) outputs))]
|
||||
['jmpt (if (not (= 0 (car inparams)))
|
||||
(loop (cadr inparams) relative-base inputs outputs)
|
||||
(loop next-pc relative-base inputs outputs))]
|
||||
['jmpf (if (= 0 (car inparams))
|
||||
(loop (cadr inparams) relative-base inputs outputs)
|
||||
(loop next-pc relative-base inputs outputs))]
|
||||
['lt (vector-set! p (car outparams)
|
||||
(if (< (car inparams) (cadr inparams)) 1 0))
|
||||
(loop next-pc relative-base inputs outputs)]
|
||||
['eq (vector-set! p (car outparams)
|
||||
(if (= (car inparams) (cadr inparams)) 1 0))
|
||||
(loop next-pc relative-base inputs outputs)]
|
||||
['rel (loop next-pc (+ relative-base (car inparams)) inputs outputs)])))
|
Loading…
Add table
Add a link
Reference in a new issue