Advent of Code solutions
at main 55 lines 1.9 kB view raw
1import "trilogy:io" use readall 2import "trilogy:debug" use dbg 3import "trilogy:core" use length 4import "trilogy:parsec" use parse, hex_integer, repeat, apply, any, many_1, followed_by, eof 5import "trilogy:bits" as bits 6import "trilogy:string" use chomp 7import "trilogy:compare" use min, max 8import "trilogy:array" use reduce 9 10func from_binary [] = 0 11func from_binary [..rest, true] = (from_binary rest * 2) + 1 12func from_binary [..rest, false] = from_binary rest * 2 13 14proc literal!() { 15 let is_continued = apply any 16 let seg = apply <| repeat 4 any 17 if !is_continued { return seg } 18 let rest = apply literal 19 return [..seg, ..rest] 20} 21 22proc operator!() { 23 let length_type = apply any 24 if length_type == false { 25 let sublength = from_binary <| apply <| repeat 15 any 26 let content_bits = bits::from_array <| apply <| repeat sublength any 27 return parse (followed_by eof <| many_1 packet) content_bits 28 } else { 29 let subpacket_count = from_binary <| apply <| repeat 11 any 30 return apply <| repeat subpacket_count packet 31 } 32} 33 34proc packet!() { 35 let version = from_binary <| apply <| repeat 3 any 36 let type_id = from_binary <| apply <| repeat 3 any 37 return match type_id { 38 case 0 then reduce (+) <| apply operator 39 case 1 then reduce (*) <| apply operator 40 case 2 then reduce min <| apply operator 41 case 3 then reduce max <| apply operator 42 case 4 then from_binary <| apply literal 43 case 5 then match apply operator { case [a, b] if a > b then 1 else 0 } 44 case 6 then match apply operator { case [a, b] if a < b then 1 else 0 } 45 case 7 then match apply operator { case [a, b] if a == b then 1 else 0 } 46 } 47} 48 49proc main!() { 50 let hex_string = chomp readall!() 51 let binary_input = bits::from <| parse hex_integer hex_string 52 let real_len = length hex_string * 4 53 let real_bits = binary_input <<~ (length binary_input - real_len) 54 dbg!(parse packet real_bits) 55}