2020/src/08.rkt

37 lines
1.2 KiB
Racket
Raw Normal View History

2020-12-08 06:29:11 +00:00
#lang racket
(require racket/set
"../lib.rkt")
(define (parse instr)
(match instr
[(regexp #rx"(.+) (.+)" (list _ op arg))
(cons (string->symbol op) (string->number arg))]))
(define input (list->vector (map parse (problem-input 8))))
2020-12-08 07:29:37 +00:00
(define (run instrs try)
(let loop ([pc 0] [acc 0] [ran (set)] [backtrack (const #f)])
(define (get-backtrack next-pc)
(if (and try (= pc try))
(const (loop next-pc acc (set-add ran pc) (const #f)))
backtrack))
2020-12-08 06:29:11 +00:00
(cond
[(>= pc (vector-length instrs)) acc]
2020-12-08 07:29:37 +00:00
[(set-member? ran pc) (if try (backtrack) acc)]
2020-12-08 06:29:11 +00:00
[else (match (vector-ref instrs pc)
2020-12-08 07:29:37 +00:00
[`(acc . ,arg) (loop (add1 pc) (+ acc arg) (set-add ran pc) backtrack)]
[`(nop . ,arg) (loop (add1 pc) acc (set-add ran pc) (get-backtrack (+ pc arg)))]
[`(jmp . ,arg) (loop (+ pc arg) acc (set-add ran pc) (get-backtrack (add1 pc)))])])))
2020-12-08 06:29:11 +00:00
(define (try-run instrs)
2020-12-08 07:29:37 +00:00
(for/or ([i (range (vector-length instrs))]
#:when (member (car (vector-ref instrs i)) '(nop jmp)))
(match-let* ([`(,op . ,arg) (vector-ref instrs i)])
(run instrs i))))
2020-12-08 06:29:11 +00:00
(define-values (part1 part2)
2020-12-08 07:29:37 +00:00
(values (run input #f) (try-run input)))
2020-12-08 06:29:11 +00:00
(show-solution part1 part2)