Skip to content

Instantly share code, notes, and snippets.

@sotolf2
Created December 5, 2019 17:04
Show Gist options
  • Save sotolf2/6dca5c6d5a7b55970a602a5dc59dba43 to your computer and use it in GitHub Desktop.
Save sotolf2/6dca5c6d5a7b55970a602a5dc59dba43 to your computer and use it in GitHub Desktop.
#lang racket
(define (get-input)
(map string->number (string-split (car (file->lines "day5.txt")) ",")))
(struct parameter (value immediate) #:transparent)
(struct opcode (op a b c) #:transparent)
(define (run-code code input)
(define (decode-op code ip)
(let* ([base (vector-ref code ip)]
[pm1 (= 1 (modulo (quotient base 100) 10))]
[pm2 (= 1 (modulo (quotient base 1000) 10))]
[pm3 (= 1 (modulo (quotient base 10000) 10))]
[op (modulo base 100)])
(opcode op (parameter 1 pm1) (parameter 2 pm2) (parameter 3 pm3))))
(define (parameter-get parameter code ip)
(if (parameter-immediate parameter)
(vector-ref code (+ ip (parameter-value parameter)))
(vector-ref code (vector-ref code (+ ip (parameter-value parameter))))))
(define (add code ain bin ip)
(let ([a (parameter-get ain code ip)]
[b (parameter-get bin code ip)])
(vector-set! code (vector-ref code (+ ip 3)) (+ a b))
code))
(define (mul code ain bin ip)
(let ([a (parameter-get ain code ip)]
[b (parameter-get bin code ip)])
(vector-set! code (vector-ref code (+ ip 3)) (* a b))
code))
(define (inp code ain ip input)
(vector-set! code (vector-ref code (+ ip (parameter-value ain))) input)
code)
(define (out code ain ip output)
(let ([a (parameter-get ain code ip)])
(cons a output)))
(define (jit code ain bin ip)
(let ([a (parameter-get ain code ip)]
[b (parameter-get bin code ip)])
(if (zero? a)
(+ 3 ip)
b)))
(define (jif code ain bin ip)
(let ([a (parameter-get ain code ip)]
[b (parameter-get bin code ip)])
(if (zero? a)
b
(+ 3 ip))))
(define (ilt code ain bin ip)
(let ([a (parameter-get ain code ip)]
[b (parameter-get bin code ip)])
(if (< a b)
(vector-set! code (vector-ref code (+ ip 3)) 1)
(vector-set! code (vector-ref code (+ ip 3)) 0))
code))
(define (ieq code ain bin ip)
(let ([a (parameter-get ain code ip)]
[b (parameter-get bin code ip)])
(if (= a b)
(vector-set! code (vector-ref code (+ ip 3)) 1)
(vector-set! code (vector-ref code (+ ip 3)) 0))
code))
(define (run-op code ip input output)
(let ([op (decode-op code ip)])
(cond [(= 99 (opcode-op op)) output]
[(= 1 (opcode-op op)) (run-op (add code (opcode-a op) (opcode-b op) ip) (+ 4 ip) input output)]
[(= 2 (opcode-op op)) (run-op (mul code (opcode-a op) (opcode-b op) ip) (+ 4 ip) input output)]
[(= 3 (opcode-op op)) (run-op (inp code (opcode-a op) ip input) (+ 2 ip) input output)]
[(= 4 (opcode-op op)) (run-op code (+ 2 ip) input (out code (opcode-a op) ip output))]
[(= 5 (opcode-op op)) (run-op code (jit code (opcode-a op) (opcode-b op) ip) input output)]
[(= 6 (opcode-op op)) (run-op code (jif code (opcode-a op) (opcode-b op) ip) input output)]
[(= 7 (opcode-op op)) (run-op (ilt code (opcode-a op) (opcode-b op) ip) (+ 4 ip) input output)]
[(= 8 (opcode-op op)) (run-op (ieq code (opcode-a op) (opcode-b op) ip) (+ 4 ip) input output)])))
(let ([code (list->vector code)])
(run-op code 0 input '())))
(writeln "Part1: ")
(writeln (run-code (get-input) 1))
(writeln "Part2: ")
(writeln (run-code (get-input) 5))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment