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.
41 lines
1.4 KiB
Racket
41 lines
1.4 KiB
Racket
#lang reader "../aoc-lang.rkt"
|
|
(provide (rename-out [#%mb #%module-begin]))
|
|
|
|
(define current-stars (make-parameter #f))
|
|
(define current-target-len (make-parameter #f))
|
|
|
|
(define-macro (#%mb (STARS) (NAME . TOKS) ...)
|
|
#`(#%module-begin
|
|
(current-stars 'STARS)
|
|
(current-target-len (length '(NAME ...)))
|
|
(handle NAME . TOKS) ...))
|
|
|
|
(define (weights= . xs) (apply =* (map wt xs)))
|
|
|
|
(define (unique-weight x xs)
|
|
(= 1 (length (filter values (map (curry weights= x) xs)))))
|
|
|
|
(define (unbalanced-subsym subsyms)
|
|
(findf (curryr unique-weight subsyms) subsyms))
|
|
|
|
(define (balanced-subsym subsyms)
|
|
(findf (negate (curryr unique-weight subsyms)) subsyms))
|
|
|
|
(struct prog (sym wt) #:transparent)
|
|
|
|
(define/caching (wt sym)
|
|
(apply + (map prog-wt (flatten (sym)))))
|
|
|
|
(define-macro-cases handle
|
|
[(M SYM (NUM) -> . SUBSYMS)
|
|
#'(begin (define/caching (SYM [target-weight #f])
|
|
(define subsyms (list . SUBSYMS))
|
|
(if target-weight
|
|
(if (apply weights= subsyms)
|
|
(displayln (format "~a is bad: needs to be ~a" 'SYM (- NUM (- (wt SYM) target-weight))))
|
|
((unbalanced-subsym subsyms) (wt (balanced-subsym subsyms))))
|
|
(cons (prog 'SYM NUM) (map app subsyms))))
|
|
(module+ main
|
|
(when (= (current-target-len) (length (flatten (SYM))))
|
|
(if (eq? (current-stars) '★) 'SYM (SYM 'find-bad-weight)))))]
|
|
[(M SYM (NUM)) #'(M SYM (NUM) ->)]) |