Advertisement
Guest User

Untitled

a guest
Dec 16th, 2021
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 2.90 KB | None | 0 0
  1. #lang racket
  2. (require bitsyntax)
  3.  
  4. (define raw-in (car (port->lines (open-input-file "day16.txt") #:close? #t))) ;only 1 line this time
  5. (define (hexstring->blist hs)
  6.   (integer->bit-string (string->number hs 16) (* 4 (string-length hs)) #t))
  7. (define (parse tape)
  8.   (define (parse-packet b)
  9.     (bit-string-case b
  10.                      ([(v :: bits 3) (= 4 :: bits 3) (rest :: binary)] ;literal
  11.                       (match-define (list next len val) (parse-literal rest))
  12.                       `((,v literal ,val) ,(+ 6 (* 5 len)) ,next))
  13.                      ([(v :: bits 3) (op :: bits 3) (= 0 :: bits 1) (l :: bits 15) (rest :: binary)] ; type 0 operator
  14.                       (match-define (list ps next len) (parse-operator0 rest l))
  15.                       `((,v operator ,op ,ps) ,(+ 22 len) ,next))
  16.                      ([(v :: bits 3) (op :: bits 3) (= 1 :: bits 1) (l :: bits 11) (rest :: binary)] ; type 1 operator
  17.                       (match-define (list ps next len) (parse-operator1 rest l))
  18.                       `((,v operator ,op ,ps) ,(+ 18 len) ,next))))
  19.   (define (parse-literal b)
  20.     (bit-string-case b
  21.                      ([(= 1 :: bits 1) (v :: bits 4) (rest :: binary)]
  22.                       (begin
  23.                         (match-define (list next len val) (parse-literal rest))
  24.                         (list next (+ 1 len) (+ (* (expt 16 len) v) val))))
  25.                      ([(= 0 :: bits 1) (v :: bits 4) (rest :: binary)] (list rest 1 v))))
  26.   (define (parse-n-bits n b [lsf 0])
  27.     (cond
  28.       [(<= n lsf) b]
  29.       [else (match-define (list-rest packet (list len next)) (parse-packet b))
  30.             (cons packet (parse-n-bits n next (+ lsf len)))]))
  31.  
  32.   (define (parse-n-packets n b [lsf 0])
  33.     (cond
  34.       [(= n 0) (λ () (list b lsf))]
  35.       [else (match-define (list-rest packet (list len next)) (parse-packet b))
  36.             (cons packet (parse-n-packets (sub1 n) next (+ lsf len)))]))
  37.    
  38.   (define (parse-operator0 b len)
  39.     (match-define (list-rest ps ... next) (parse-n-bits len b))
  40.     (list ps next len))
  41.  
  42.   (define (parse-operator1 b len)
  43.     (match-define (list-rest ps ... thnk) (parse-n-packets len b))
  44.     (match-define (list next lsf) (thnk))
  45.     (list ps next lsf))
  46.  
  47.   (car (parse-packet tape)))
  48.  
  49. (define (part1 in)
  50.   (version-sum (parse (hexstring->blist in))))
  51.  
  52. (define (version-sum pl)
  53.   (cond
  54.     [(eq? (cadr pl) 'literal) (car pl)]
  55.     [else (+ (car pl) (apply + (map version-sum (cadddr pl))))]))
  56.  
  57. (define (eval-ps pl)
  58.   (define flist `((0 ,+) (1 ,*) (2 ,min) (3 ,max)
  59.                          (5 ,(λ (x y) (if (> x y) 1 0)))
  60.                          (6 ,(λ (x y) (if (< x y) 1 0)))
  61.                          (7 ,(λ (x y) (if (= x y) 1 0)))))
  62.     (cond
  63.       [(eq? (cadr pl) 'literal) (caddr pl)]
  64.       [else (apply (cadr (assoc (caddr pl) flist)) (map eval-ps (cadddr pl)))]))
  65.  
  66. (define (part2 in)
  67.   (eval-ps (parse (hexstring->blist in))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement