Advent of Code solutions

2021 day 17 done

+74 -10
+21 -10
2021/17/p1.tri
··· 3 3 import "trilogy:parsec" use apply, parse, sep_by, string, integer 4 4 import "trilogy:array" use collect 5 5 import "trilogy:iterator" as it 6 - import "trilogy:tuple" use left, right 6 + import "trilogy:tuple" use right 7 7 import "trilogy:number" use is_integer 8 8 import "trilogy:compare" use max 9 9 ··· 24 24 rest!() 25 25 } 26 26 27 + func x_at 0 _ = 0 28 + func x_at _ 0 = 0 29 + func x_at t h = h + x_at (t - 1) (h - 1) 30 + 27 31 func in_range low high n = low <= n && n <= high 28 32 29 33 proc main!() { 30 - let target and (x_min:x_max):(y_min:y_max) = parse input readall!() 31 - it::range 1 x_max 32 - |> it::flat_map (it::map ((+) 1 << left) << it::filter (in_range x_min x_max << right) << it::enumerate << h_vel x_max 0) 33 - |> it::flat_map (fn t. 34 - it::range y_min y_max 35 - |> it::map (fn y. (y + (t * (t - 1) / 2)) / t) 36 - |> it::filter is_integer 37 - |> it::map dbg 34 + let (x_min:x_max):(y_min:y_max) = parse input readall!() 35 + 36 + let h_candidates = it::range 1 x_max 37 + |> it::filter (it::any (in_range x_min x_max) << h_vel x_max 0) 38 + |> collect 39 + 40 + let v_max = it::range y_min y_max 41 + |> it::flat_map (fn y. 42 + it::range 1 1_000 # time 43 + |> it::map (fn t. t:(y + (t * (t - 1) / 2)) / t) # t:y velocity to hit target 44 + |> it::filter (right >> is_integer) # integer velocities only 45 + |> it::filter (fn _:v. v > 0) # also let's do upwards only 46 + |> it::flat_map (fn t:v. it::from h_candidates |> it::map (fn h. t:v:h)) 47 + |> it::filter (fn t:v:h. in_range x_min x_max <| x_at t h) 48 + |> it::map (fn _:v:_. v) 38 49 ) 39 50 |> it::reduce max 40 - |> dbg 51 + dbg!(v_max * (v_max + 1) / 2) 41 52 }
+53
2021/17/p2.tri
··· 1 + import "trilogy:debug" use dbg 2 + import "trilogy:io" use readall 3 + import "trilogy:core" use length 4 + import "trilogy:parsec" use apply, parse, sep_by, string, integer 5 + import "trilogy:array" use collect 6 + import "trilogy:set" as set 7 + import "trilogy:iterator" as it 8 + import "trilogy:tuple" use right 9 + import "trilogy:number" use is_integer 10 + 11 + proc input!() { 12 + apply <| string "target area: x=" 13 + let [x_min, x_max] = apply <| sep_by (string "..") integer 14 + apply <| string ", y=" 15 + let [y_min, y_max] = apply <| sep_by (string "..") integer 16 + return (x_min:x_max):(y_min:y_max) 17 + } 18 + 19 + func h_vel lim _ 0 = do() unit 20 + func h_vel lim pos vel = do() { 21 + let next_pos = pos + vel 22 + if next_pos > lim { return unit } 23 + yield 'next(next_pos) 24 + let rest = h_vel lim next_pos (vel - 1) 25 + rest!() 26 + } 27 + 28 + func x_at 0 _ = 0 29 + func x_at _ 0 = 0 30 + func x_at t h = h + x_at (t - 1) (h - 1) 31 + 32 + func in_range low high n = low <= n && n <= high 33 + 34 + proc main!() { 35 + let (x_min:x_max):(y_min:y_max) = parse input readall!() 36 + 37 + let h_candidates = it::range 1 x_max 38 + |> it::filter (it::any (in_range x_min x_max) << h_vel x_max 0) 39 + |> collect 40 + 41 + it::range y_min y_max 42 + |> it::flat_map (fn y. 43 + it::range 1 1_000 # time 44 + |> it::map (fn t. t:(y + (t * (t - 1) / 2)) / t) # t:y velocity to hit target 45 + |> it::filter (right >> is_integer) # integer velocities only 46 + |> it::flat_map (fn t:v. it::from h_candidates |> it::map (fn h. t:v:h)) 47 + |> it::filter (fn t:v:h. in_range x_min x_max <| x_at t h) 48 + |> it::map (fn _:v:h. v:h) 49 + ) 50 + |> set::collect 51 + |> length 52 + |> dbg 53 + }