You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
aoc-racket/2016/day23/lang.rkt

83 lines
2.3 KiB
Racket

8 years ago
#lang br/quicklang ;; http://adventofcode.com/2016/day/23
(provide read-syntax
(rename-out [mb #%module-begin])
cpy inc dec jnz tgl)
(define (read-syntax path port)
(strip-bindings
#`(module mod "lang.rkt"
#,@(for/list ([str (in-lines port)]
#:when (not (zero? (string-length str))))
(format-datum '(~a) str)))))
(define-macro (mb INST ...)
#'(#%module-begin
(report 'INST) ...
(define insts (vector INST ...))
(define regs (make-hash '((a . 0)(b . 0)(c . 0)(d . 0))))
(println (solve insts regs))
(hash-set! regs 'c 1)
(println (solve insts regs))))
(define current-toggles (make-parameter empty))
(define current-ptr (make-parameter #f))
(define (toggled?) (member (current-ptr) (current-toggles)))
(define (solve insts regs)
(let loop ([ptr 0])
(current-ptr ptr)
(if (>= ptr (vector-length insts))
regs
(loop (+ ptr (let ([move ((vector-ref insts ptr) regs)])
(if (void? move) 1 move)))))))
(define-macro (make-tgl-base X)
#'(λ(regs)
(current-toggles
((if (member X (current-toggles))
remove
cons) X (current-toggles)))))
(define-macro (tgl X)
#'(λ(regs)
((if (toggled?)
(make-inc-base X)
(make-tgl-base X)) regs)))
(define-macro (make-cpy-base X Y)
#'(λ(regs)
(define val (if (number? 'X) 'X (hash-ref regs 'X)))
(hash-set! regs 'Y val)))
(define-macro (cpy X Y)
#'(λ(regs)
((if (toggled?)
(make-jnz-base X Y)
(make-cpy-base X Y)) regs)))
(define-macro (make-dec-base X) #'(λ(regs) (hash-update! regs 'X sub1)))
(define-macro (make-inc-base X) #'(λ(regs) (hash-update! regs 'X add1)))
(define-macro (inc X) #'(λ(regs)
((if (toggled?)
(make-dec-base X)
(make-inc-base X)) regs)))
(define-macro (dec X) #'(λ(regs)
((if (toggled?)
(make-inc-base X)
(make-dec-base X)) regs)))
(define-macro (make-jnz-base X Y)
#'(λ(regs)
(when (not (zero? (if (number? 'X) 'X (hash-ref regs 'X))))
Y)))
(define-macro (jnz X Y)
#'(λ(regs)
((if (toggled?)
(make-copy-base X Y)
(make-jnz-base X Y)) regs)))