diff --git a/day16.rkt b/day16.rkt new file mode 100644 index 0000000..ef29682 --- /dev/null +++ b/day16.rkt @@ -0,0 +1,152 @@ +#lang racket + +(define (string->string-list str) + (map string (string->list str))) + +;(define input "D2FE28") +;(define input "38006F45291200") +;(define input "EE00D40C823060") +;(define input "8A004A801A8002F478") +;(define input "620080001611562C8802118E34") +;(define input "C0015000016115A2E0802F182340") +;(define input "A0016C880162017C3686B18A3D4780") + +;(define input "C200B40A82") ; 1 + 2 +;(define input "04005AC33890") ; 6 * 9 +;(define input "880086C3E88112") ; min 7 8 9 +;(define input "CE00C43D881120") ; max 7 8 9 +;(define input "D8005AC2A8F0") ; 5 < 15 +;(define input "F600BC2D8F") ; 5 > 15 +;(define input "9C005AC2F8F0") ; 5 = 15 +;(define input "9C0141080250320F1802104A08") ; 1 + 3 = 2 * 2 + +(define input (first (file->lines "day16.txt"))) + +(define bins (list (list "0" "0000") + (list "1" "0001") + (list "2" "0010") + (list "3" "0011") + (list "4" "0100") + (list "5" "0101") + (list "6" "0110") + (list "7" "0111") + (list "8" "1000") + (list "9" "1001") + (list "A" "1010") + (list "B" "1011") + (list "C" "1100") + (list "D" "1101") + (list "E" "1110") + (list "F" "1111"))) + +(define (all-but-last lst) + (take lst (- (length lst) 1))) + +(define (h2b hex-str) ; todo make this suck less + (let* ([hex-list (string->string-list hex-str)] + [binary-list (map (λ (x) (second (assoc x bins))) hex-list)]) + (apply string-append binary-list))) + +(define (b2d bin-str) + (string->number bin-str 2)) + +(define versions (make-hash)) + +(define (parse-literal str) + (let* ([res (read-literal str)] + [len (string-length res)] + [rest (substring str (+ (/ len 4) len))] + [dec (b2d res)]) + ;(printf "parse-literal. returning: ~s~n" (list dec rest)) + (list dec rest))) + +(define (read-literal str) + ;(printf "read-literal ~s~n" str) + (let loop ([group str]) + (let* ([first (substring group 0 1)] + [next-four (substring group 1 5)] + [rest (substring group 5)]) + (if (equal? first "0") + next-four + (string-append next-four (loop rest)))))) + +(define (length-id-0 str) + (let* ([len (b2d (substring str 0 15))] + [inner (substring str 15 (+ 15 len))] + [rest (substring str (+ 15 len))] + ;[_ (printf "length-id-0 str: ~s len: ~s inner: ~s rest: ~s~n" str len inner rest)] + [res (parse-multiple inner)] + [res-value (all-but-last res)]) + (list res-value rest))) + +(define (parse-multiple str) + ;(printf "parse-multpile ~s~n" str) + (let loop ([group str]) + (let* ([res (parse group)] + [data (first res)] + [rest (second res)]) + ;(printf "parse-multiple loop res: ~s data: ~s rest: ~s~n" res data rest) + (if (= 0 (string-length rest)) + (list data rest) + (cons data (loop rest)))))) + +(define (length-id-1 str) + (let* ([num (b2d (substring str 0 11))] + [rest (substring str 11)] + ;[_ (printf "length-id-1. str: ~s num: ~s rest: ~s~n" str num rest)] + [res (parse-n rest num)]) + ;(printf "length-id-1 done. res: ~s~n" res) + res)) + +(define (parse-n str num) + ;(printf "parse-n ~s ~s~n" str num) + (let loop ([group str] + [n num]) + ;(printf "parse-n loop ~s ~s~n" group n) + (let* ([res (parse group)] + [data (first res)] + [rest (second res)]) + ;(printf "parse-n loop res: ~s data: ~s rest: ~s n: ~s~n" res data rest n) + (if (= 1 n) + (list data rest) + (cons data (loop rest (sub1 n))))))) + +(define (parse-operator str) + (let* ([length-type-id (substring str 0 1)]) + ;(printf "parse-operator ~s. length-type-id: ~s~n" str length-type-id) + (if (equal? length-type-id "0") + (length-id-0 (substring str 1)) + (length-id-1 (substring str 1))))) + +(define (gt x y) (if (> x y) 1 0)) +(define (lt x y) (if (< x y) 1 0)) +(define (eq x y) (if (equal? x y) 1 0)) + +(define (parse str) + ;(printf "parse ~s~n" str) + (let* ([version (substring str 0 3)] + [dec-version (b2d version)] + [type-id (substring str 3 6)] + [body (substring str 6)] + [op (cond [(equal? type-id "100") first] + [(equal? type-id "000") (λ (x) (apply + x))] + [(equal? type-id "001") (λ (x) (apply * x))] + [(equal? type-id "010") (λ (x) (apply min x))] + [(equal? type-id "011") (λ (x) (apply max x))] + [(equal? type-id "101") (λ (x) (gt (first x) (second x)))] + [(equal? type-id "110") (λ (x) (lt (first x) (second x)))] + [(equal? type-id "111") (λ (x) (eq (first x) (second x)))])] + [res-list ((if (equal? type-id "100") parse-literal parse-operator) body)] + [res (flatten (all-but-last res-list))] + [post-op (op res)] + [rest (last res-list)]) + ;(printf "bottom of parse. res: ~s rest: ~s post-op: ~s~n" res rest post-op) + (hash-set! versions 'count (+ dec-version (hash-ref! versions 'count 0))) + (list post-op rest))) + +(define go + (let* ([str (h2b input)]) + (first (parse str)))) + +go +versions \ No newline at end of file diff --git a/day16.txt b/day16.txt new file mode 100644 index 0000000..c108eef --- /dev/null +++ b/day16.txt @@ -0,0 +1 @@ +A052E04CFD9DC0249694F0A11EA2044E200E9266766AB004A525F86FFCDF4B25DFC401A20043A11C61838600FC678D51B8C0198910EA1200010B3EEA40246C974EF003331006619C26844200D414859049402D9CDA64BDEF3C4E623331FBCCA3E4DFBBFC79E4004DE96FC3B1EC6DE4298D5A1C8F98E45266745B382040191D0034539682F4E5A0B527FEB018029277C88E0039937D8ACCC6256092004165D36586CC013A008625A2D7394A5B1DE16C0E3004A8035200043220C5B838200EC4B8E315A6CEE6F3C3B9FFB8100994200CC59837108401989D056280803F1EA3C41130047003530004323DC3C860200EC4182F1CA7E452C01744A0A4FF6BBAE6A533BFCD1967A26E20124BE1920A4A6A613315511007A4A32BE9AE6B5CAD19E56BA1430053803341007E24C168A6200D46384318A6AAC8401907003EF2F7D70265EFAE04CCAB3801727C9EC94802AF92F493A8012D9EABB48BA3805D1B65756559231917B93A4B4B46009C91F600481254AF67A845BA56610400414E3090055525E849BE8010397439746400BC255EE5362136F72B4A4A7B721004A510A7370CCB37C2BA0010D3038600BE802937A429BD20C90CCC564EC40144E80213E2B3E2F3D9D6DB0803F2B005A731DC6C524A16B5F1C1D98EE006339009AB401AB0803108A12C2A00043A134228AB2DBDA00801EC061B080180057A88016404DA201206A00638014E0049801EC0309800AC20025B20080C600710058A60070003080006A4F566244012C4B204A83CB234C2244120080E6562446669025CD4802DA9A45F004658527FFEC720906008C996700397319DD7710596674004BE6A161283B09C802B0D00463AC9563C2B969F0E080182972E982F9718200D2E637DB16600341292D6D8A7F496800FD490BCDC68B33976A872E008C5F9DFD566490A14