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/2017/d7/main.rkt

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) ->)])