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.
68 lines
2.0 KiB
Racket
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))
|
|
|
|
|