Advent of Code solutions

clean up and fully implement 2025 solutions in trilogy, however slow and memory inefficient the resulting programs may be

+85 -32
+9 -13
2025/1/p1.tri
··· 1 1 import "trilogy:debug" use dbg 2 - import "trilogy:io" use readline 2 + import "trilogy:io" use readlines 3 3 import "trilogy:parsec" use parse, char_of, integer, apply 4 + import "trilogy:iterator" as it 4 5 5 6 proc rotation!() { 6 7 let dir = apply <| char_of "LR" ··· 8 9 return if dir == 'R' then amt else -amt 9 10 } 10 11 11 - func rotate amt pos = (pos + amt) % 100 12 + func rotate pos amt = (pos + amt) % 100 12 13 13 14 proc main!() { 14 - let mut zeros = 0 15 - let mut pos = 50 16 - while true { 17 - pos rotate= with parse rotation readline!() 18 - when 'eof cancel break unit 19 - else yield 20 - if pos == 0 { 21 - zeros += 1 22 - } 23 - } 24 - dbg!(zeros) 15 + let answer = readlines 16 + |> it::map (parse rotation) 17 + |> it::scanl rotate 50 18 + |> it::filter ((==) 0) 19 + |> it::count 20 + dbg!(answer) 25 21 }
+16 -19
2025/1/p2.tri
··· 1 1 import "trilogy:debug" use dbg 2 - import "trilogy:io" use readline 2 + import "trilogy:io" use readlines 3 3 import "trilogy:number" use abs 4 4 import "trilogy:parsec" use parse, char_of, integer, apply 5 + import "trilogy:iterator" as it 5 6 6 7 proc rotation!() { 7 8 let dir = apply <| char_of "LR" ··· 10 11 } 11 12 12 13 func rotate pos amt = 13 - if abs amt > 100 14 - then yield 'full(abs amt // 100); rotate (amt % 100) pos 15 - else pos + amt 14 + let full = abs amt // 100, 15 + let rotated = pos + amt % 100, 16 + let crossed = rotated < 0 || rotated > 99, 17 + yield 'rotations(full + if crossed then 1 else 0); 18 + (rotated + 100) % 100 16 19 17 20 proc main!() { 18 - let mut zeros = 0 19 - let mut pos = 50 20 - while true { 21 - pos = with rotate pos <| parse rotation readline!() 22 - when 'eof cancel break unit 23 - when 'full(n) then { 24 - zeros += n 25 - become unit 26 - } 27 - else yield 28 - if pos < 0 || pos > 99 { 29 - zeros += 1 30 - pos = (pos + 100) % 100 21 + let mut answer = 0 22 + with readlines 23 + |> it::map (parse rotation) 24 + |> it::foldl rotate 50 25 + when 'rotations(n) then { 26 + answer += n 27 + become unit 31 28 } 32 - } 33 - dbg!(zeros) 29 + else yield 30 + dbg!(answer) 34 31 }
+28
2025/2/p1.tri
··· 1 + import "trilogy:debug" use dbg 2 + import "trilogy:io" use readline 3 + import "trilogy:core" use to_string 4 + import "trilogy:parsec" use apply, parse, sep_by, integer, char 5 + import "trilogy:string" use length, take, skip 6 + import "trilogy:iterator" as it 7 + 8 + proc range!() { 9 + let low = apply integer 10 + apply <| char '-' 11 + let high = apply integer 12 + return low:high 13 + } 14 + 15 + func is_invalid str = 16 + length str % 2 == 0 17 + && take (length str // 2) str == skip (length str // 2) str 18 + 19 + proc main!() { 20 + let ranges = parse (sep_by (char ',') range) readline!() 21 + let mut total = 0 22 + for low:high in ranges { 23 + total += it::range low high 24 + |> it::filter (is_invalid << to_string) 25 + |> it::sum 26 + } 27 + dbg!(total) 28 + }
+32
2025/2/p2.tri
··· 1 + import "trilogy:debug" use dbg 2 + import "trilogy:io" use readline 3 + import "trilogy:core" use to_string, to_array 4 + import "trilogy:parsec" use apply, parse, sep_by, integer, char 5 + import "trilogy:array" use length, take, chunks 6 + import "trilogy:iterator" as it 7 + 8 + proc range!() { 9 + let low = apply integer 10 + apply <| char '-' 11 + let high = apply integer 12 + return low:high 13 + } 14 + 15 + func is_invalid arr = 16 + it::range 1 (length arr // 2) 17 + |> it::any (fn n. 18 + it::all ((==) (take n arr)) 19 + <| it::from 20 + <| chunks n arr 21 + ) 22 + 23 + proc main!() { 24 + let ranges = parse (sep_by (char ',') range) readline!() 25 + let mut total = 0 26 + for low:high in ranges { 27 + total += it::range low high 28 + |> it::filter (is_invalid << to_array << to_string) 29 + |> it::sum 30 + } 31 + dbg!(total) 32 + }