aoc2019/2.rkt

62 lines
1.8 KiB
Racket

#lang racket
(define input (map string->number (string-split
(string-trim (file->string "input.2.txt")) ",")))
(define pos1-replacement 12)
(define pos2-replacement 2)
(define mutated-input (list-set (list-set input 1 pos1-replacement) 2 pos2-replacement))
(define op-add 1)
(define op-mul 2)
(define op-exit 99)
(define (intcode-arith op tape pos)
(let ([lhs (list-ref tape (+ pos 1))]
[rhs (list-ref tape (+ pos 2))]
[dst (list-ref tape (+ pos 3))])
(intcode-eval (list-set tape dst (op (list-ref tape lhs) (list-ref tape rhs)))
(+ pos 4))))
(define intcode-add ((curry intcode-arith) +))
(define intcode-mul ((curry intcode-arith) *))
(define (intcode-eval tape pos)
(let ([op (list-ref tape pos)])
(cond [(= op op-add) (intcode-add tape pos)]
[(= op op-mul) (intcode-mul tape pos)]
[(= op op-exit) (first tape)]
[else (error "invalid operator")])))
;; Part 1
(displayln (intcode-eval mutated-input 0))
;; if i were less lazy i'd make a proper symbolic execution engine for this but...
(define wanted-output 19690720)
(define (brute-force i j)
(cond [(= wanted-output (intcode-eval (list-set (list-set input 1 i) 2 j) 0)) (list i j)]
[(>= i 100) (brute-force 0 (add1 j))]
[else (brute-force (add1 i) j)]))
;; Part 2
(displayln (brute-force 0 0))
;; Okay now with actual symbolic execution
(define symbolic-globals '(1 2))
(define-struct symbvar (idx))
(define-struct constr-arith (op lhs rhs dest))
(define-struct constr-oneof (vals))
(define-struct state (constrs nextvar))
(define initial-state (make-state '() 0))
(define (create-symbvar state)
(values (make-symbvar (state-nextvar state))
(make-state (state-constrs state) (add1 (state-nextvar state)))))