64 lines
2.2 KiB
Racket
64 lines
2.2 KiB
Racket
#lang racket/base
|
|
|
|
(require racket/random
|
|
racket/list
|
|
racket/match
|
|
graph
|
|
"../intcode.rkt")
|
|
|
|
(module+ test
|
|
(require rackunit))
|
|
|
|
(define (possible-directions grid pos)
|
|
(define unexplored-directions
|
|
(for/list ([step '(-1 -i 1 +i)]
|
|
#:unless (hash-has-key? grid (+ pos step)))
|
|
step))
|
|
(if (empty? unexplored-directions)
|
|
(for/list ([step '(-1 -i 1 +i)]
|
|
#:unless (eq? 'wall (hash-ref grid (+ pos step) 'floor)))
|
|
step)
|
|
unexplored-directions))
|
|
|
|
(define (shortest-distances grid source)
|
|
(define g (unweighted-graph/undirected
|
|
(for*/list ([(pos tile) (in-hash grid)]
|
|
#:unless (eq? 'wall tile)
|
|
[step '(-1 -i 1 +i)]
|
|
#:unless (eq? 'wall (hash-ref grid (+ pos step) 'wall)))
|
|
(list pos (+ pos step)))))
|
|
(define-values (distances predecessors) (dijkstra g source))
|
|
distances)
|
|
|
|
(define (part12 program)
|
|
(define grid (make-hash '((0 'floor))))
|
|
(let loop ([vm (execute (start-machine program '()))]
|
|
[pos 0]
|
|
[i 0])
|
|
(define direction (random-ref (possible-directions grid pos)))
|
|
(define direction-code (match direction
|
|
[+i 1]
|
|
[-i 2]
|
|
[-1 3]
|
|
[1 4]))
|
|
(define new-vm (execute (struct-copy machine vm [inputs (list direction-code)])))
|
|
(define next-pos (+ pos direction))
|
|
(unless (> i 100000)
|
|
(match (car (machine-outputs new-vm))
|
|
[0 (hash-set! grid next-pos 'wall)
|
|
(loop new-vm pos (add1 i))]
|
|
[1 (hash-set! grid next-pos 'floor)
|
|
(loop new-vm next-pos (add1 i))]
|
|
[2 (hash-set! grid next-pos 'oxygen)
|
|
(loop new-vm next-pos (add1 i))])))
|
|
(define oxygen (for/first ([(pos tile) (in-hash grid)]
|
|
#:when (eq? 'oxygen tile))
|
|
pos))
|
|
(define distances (shortest-distances grid oxygen))
|
|
(values (hash-ref distances 0)
|
|
(apply max (hash-values distances))))
|
|
|
|
(module+ test
|
|
(define-values (p1 p2) (part12 (parse-file "input")))
|
|
(check-equal? p1 296)
|
|
(check-equal? p2 302))
|