62 lines
1.8 KiB
Racket
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)))))
|
|
|