65 lines
1.6 KiB
Racket
65 lines
1.6 KiB
Racket
#lang racket
|
|
|
|
(require threading
|
|
rebellion/base/comparator
|
|
rebellion/collection/list
|
|
rebellion/streaming/transducer
|
|
rebellion/streaming/reducer)
|
|
|
|
(define read-pairs
|
|
(lambda~> file->string
|
|
(string-split _ "\n\n")
|
|
(map (lambda (s) (string-split s "\n")) _)
|
|
(map (lambda (l) (map parse-packet l)) _)))
|
|
|
|
(define read-all
|
|
(lambda~> file->string
|
|
string-split
|
|
(map parse-packet _)))
|
|
|
|
(define parse-packet
|
|
(lambda~> (string-replace _ "," " ")
|
|
(with-input-from-string _ read)))
|
|
|
|
(define (packet-compare a b)
|
|
(match (list a b)
|
|
[(list x y) #:when (and (integer? x) (integer? y))
|
|
(cond
|
|
[(< x y) lesser]
|
|
[(> x y) greater]
|
|
[else equivalent])]
|
|
[(list '() '()) equivalent]
|
|
[(list '() _) lesser]
|
|
[(list _ '()) greater]
|
|
[(list (list* x xs) (list* y ys))
|
|
(let ([compxy (packet-compare x y)])
|
|
(if (eq? compxy equivalent)
|
|
(packet-compare xs ys)
|
|
compxy))]
|
|
[(list x y) #:when (and (integer? x) (list? y))
|
|
(packet-compare (list x) y)]
|
|
[(list x y) #:when (and (list? x) (integer? y))
|
|
(packet-compare x (list y))]))
|
|
|
|
(define packet<=>
|
|
(make-comparator packet-compare #:name 'packet<=>))
|
|
|
|
(define (part1 in)
|
|
(for/sum ([pair in]
|
|
[i (in-naturals)]
|
|
#:when (eq? lesser (apply packet-compare pair)))
|
|
(+ 1 i)))
|
|
|
|
(define (part2 in)
|
|
(for/product ([el (transduce (list* '((2)) '((6)) in)
|
|
(sorting packet<=>)
|
|
#:into into-list)]
|
|
[i (in-naturals)]
|
|
#:when (or (equal? el '((2)))
|
|
(equal? el '((6)))))
|
|
(+ 1 i)))
|
|
|
|
(module+ main
|
|
(displayln (part1 (read-pairs "input")))
|
|
(displayln (part2 (read-all "input"))))
|
|
|