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/typed/day23.rkt

68 lines
2.0 KiB
Racket

#lang typed/racket
(require typed/rackunit
(for-syntax racket/file racket/string sugar/debug))
(provide (all-defined-out))
(require/typed racket/base
(hash-set*! (-> (HashTable Symbol Integer) Symbol Integer Symbol Integer Void)))
(define-syntax (convert-input-to-instruction-functions stx)
(syntax-case stx ()
[(_)
(let* ([input-strings (file->lines "../day23-input.txt")]
[inst-strings (map (λ(str) (format "(λ(_) (inst ~a))" (string-replace str "," ""))) input-strings)] ;;bg; removed thunk*
[inst-datums (map (compose1 read open-input-string) inst-strings)])
(datum->syntax stx `(define instructions : (Listof (-> Integer Integer)) (list ,@inst-datums))))]))
(: registers (HashTable Symbol Integer))
(define registers (make-hash '((a . 0)(b . 0))))
(define default-offset 1)
(define-syntax-rule (define-reg-updater id thunk)
(define (id (reg : Symbol)) : Integer
(hash-update! registers reg thunk)
default-offset))
(define-reg-updater tpl (λ([val : Integer]) (* 3 val)))
(define-reg-updater inc (λ([val : Integer]) (add1 val)))
(define-reg-updater hlf (λ([val : Integer]) (cast (/ val 2) Integer)))
(: jmpf (-> Symbol Integer (-> Integer Any) Integer))
(define (jmpf reg num pred)
(if (pred (hash-ref registers reg (λ () -1))) num 1))
(define-syntax (inst stx)
(syntax-case stx (jmp jio jie)
[(_ jio reg num)
#'(jmpf 'reg num (curry = 1))]
[(_ jie reg num)
#'(jmpf 'reg num even?)]
[(_ jmp num)
#'num]
[(_ op reg)
#'(op 'reg)]))
(convert-input-to-instruction-functions)
(: q1 (-> Integer))
(define (q1)
(let eval-instruction : Integer ([idx 0])
(if (>= idx (length instructions))
(hash-ref registers 'b)
(let* ([inst (list-ref instructions idx)]
[jump-offset (inst -1)] ;;bg
[next-idx (+ jump-offset idx)])
(eval-instruction next-idx)))))
(: q2 (-> Integer))
(define (q2)
(hash-set*! registers 'a 1 'b 0)
(q1))
(module+ test
(check-equal? (q1) 184)
(check-equal? (q2) 231))