#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)))))