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