Skip to content

Instantly share code, notes, and snippets.

@sotolf2
Created December 9, 2019 10:58
Show Gist options
  • Save sotolf2/0b2f94d94ae38c6c10de0e5d8b5840af to your computer and use it in GitHub Desktop.
Save sotolf2/0b2f94d94ae38c6c10de0e5d8b5840af to your computer and use it in GitHub Desktop.
#lang racket
(define (get-input)
(map string->number (string-split (car (file->lines "day9.txt")) ",")))
(define test-code '(109 1 204 -1 1001 100 1 100 1008 100 16 101 1006 101 0 99))
(define test-code2 '(1102 34915192 34915192 7 4 7 99 0))
(define test-code3 '(104 1125899906842624 99))
(define (code->hash code)
(define (step code ip hsh)
(if (empty? code)
hsh
(step (cdr code) (+ 1 ip) (hash-set hsh ip (car code)))))
(step code 0 #hash()))
(struct parameter (value mode) #:transparent)
(struct opcode (op a b c) #:transparent)
(struct state (output code ip base) #:transparent)
(define (run-code code input [feedback #f] [ip 0])
(define (decode-op code ip)
(let* ([base (hash-ref code ip 0)]
[pm1 (modulo (quotient base 100) 10)]
[pm2 (modulo (quotient base 1000) 10)]
[pm3 (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 base)
(cond [(= 1 (parameter-mode parameter)) (hash-ref code (+ ip (parameter-value parameter)) 0)]
[(= 0 (parameter-mode parameter)) (hash-ref code (hash-ref code (+ ip (parameter-value parameter)) 0) 0)]
[(= 2 (parameter-mode parameter)) (hash-ref code (+ base (hash-ref code (+ ip (parameter-value parameter))) 0) 0)]))
(define (parameter-get-address parameter code ip base)
(cond [(= 1 (parameter-mode parameter)) (+ ip (parameter-value parameter) 0)]
[(= 0 (parameter-mode parameter)) (hash-ref code (+ ip (parameter-value parameter)) 0)]
[(= 2 (parameter-mode parameter)) (+ base (hash-ref code (+ ip (parameter-value parameter))) 0)]))
(define (add code ain bin cin ip base)
(let ([a (parameter-get ain code ip base)]
[b (parameter-get bin code ip base)]
[c (parameter-get-address cin code ip base)])
(hash-set code c (+ a b))))
(define (mul code ain bin cin ip base)
(let ([a (parameter-get ain code ip base)]
[b (parameter-get bin code ip base)]
[c (parameter-get-address cin code ip base)])
(hash-set code c (* a b))))
(define (inp code ain ip input base)
(let ([a (parameter-get-address ain code ip base)])
(hash-set code a input)))
(define (out code ain ip output base)
(let ([a (parameter-get ain code ip base)])
(cons a output)))
(define (jit code ain bin ip base)
(let ([a (parameter-get ain code ip base)]
[b (parameter-get bin code ip base)])
(if (zero? a)
(+ 3 ip)
b)))
(define (jif code ain bin ip base)
(let ([a (parameter-get ain code ip base)]
[b (parameter-get bin code ip base)])
(if (zero? a)
b
(+ 3 ip))))
(define (ilt code ain bin cin ip base)
(let ([a (parameter-get ain code ip base)]
[b (parameter-get bin code ip base)]
[c (parameter-get-address cin code ip base)])
(if (< a b)
(hash-set code c 1)
(hash-set code c 0))))
(define (ieq code ain bin cin ip base)
(let ([a (parameter-get ain code ip base)]
[b (parameter-get bin code ip base)]
[c (parameter-get-address cin code ip base)])
(if (= a b)
(hash-set code c 1)
(hash-set code c 0))))
(define (stb code ain ip base)
(let ([a (parameter-get ain code ip base)])
(+ base a)))
(define (run-op code ip input output base)
;(displayln ip)
;(displayln base)
;(displayln input)
;(displayln output)
;(displayln code)
(let ([op (decode-op code ip)])
(cond [(= 99 (opcode-op op)) (reverse output)]
[(= 1 (opcode-op op)) (run-op (add code (opcode-a op) (opcode-b op) (opcode-c op) ip base) (+ 4 ip) input output base)]
[(= 2 (opcode-op op)) (run-op (mul code (opcode-a op) (opcode-b op) (opcode-c op) ip base) (+ 4 ip) input output base)]
[(= 3 (opcode-op op)) (run-op (inp code (opcode-a op) ip (car input) base) (+ 2 ip) (cdr input) output base)]
[(and (= 4 (opcode-op op)) feedback) (state (car (out code (opcode-a op) ip output base)) code (+ 2 ip) base)]
[(= 4 (opcode-op op)) (run-op code (+ 2 ip) input (out code (opcode-a op) ip output base) base)]
[(= 5 (opcode-op op)) (run-op code (jit code (opcode-a op) (opcode-b op) ip base) input output base)]
[(= 6 (opcode-op op)) (run-op code (jif code (opcode-a op) (opcode-b op) ip base) input output base)]
[(= 7 (opcode-op op)) (run-op (ilt code (opcode-a op) (opcode-b op) (opcode-c op) ip base) (+ 4 ip) input output base)]
[(= 8 (opcode-op op)) (run-op (ieq code (opcode-a op) (opcode-b op) (opcode-c op) ip base) (+ 4 ip) input output base)]
[(= 9 (opcode-op op)) (run-op code (+ 2 ip) input output (stb code (opcode-a op) ip base))])))
(let ([code (code->hash code)])
(run-op code ip input '() 0)))
(define (part1)
(run-code (get-input) '(1)))
(part1)
(define (part2)
(run-code (get-input) '(2)))
(part2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment