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
marginally faster but still too slow
eldridge.cam
3 months ago
83b0310d
6012f47f
+40
-30
1 changed file
expand all
collapse all
unified
split
2025
10
p2.tri
+40
-30
2025/10/p2.tri
···
1
1
import "trilogy:io" use readlines
2
2
import "trilogy:debug" use dbg
3
3
-
import "trilogy:core" use to_array, length
4
4
-
import "trilogy:bits" as bits
5
5
-
import "trilogy:set" use contains, union, collect, difference
6
6
-
import "trilogy:compare" use min
3
3
+
import "trilogy:compare" use min, max, asc
7
4
import "trilogy:parsec" use parse, apply, between, many_1, char_of, char, integer, sep_by_1
8
8
-
import "trilogy:array" use map, fold, filter, reverse
5
5
+
import "trilogy:array" use map, fold, filter, reverse, sort_by, reduce, all, flatten
9
6
import "trilogy:iterator" as it
7
7
+
import "trilogy:set" as set use contains
10
8
11
9
proc machine!() {
12
10
let _target = apply
···
19
17
<| between (char '(') (char ')')
20
18
<| sep_by_1 (char ',') integer
21
19
apply <| char ' '
22
22
-
let joltage = fold (fn acc n. n:acc) unit
23
23
-
<| reverse
24
24
-
<| apply
20
20
+
let joltage = apply
25
21
<| between (char '{') (char '}')
26
22
<| sep_by_1 (char ',') integer
27
23
return joltage:buttons
28
24
}
29
25
30
30
-
func update_state n:rest 0 = n + 1 : rest
31
31
-
func update_state n:rest i = n : update_state rest (i - 1)
26
26
+
func limit_within target button = reduce min <| map ((.) target) button
32
27
33
33
-
func press_button state [] = state
34
34
-
func press_button state [n, ..rest] = press_button (update_state state n) rest
28
28
+
func sub_at 0 n [m, ..arr] = [m - n, ..arr]
29
29
+
func sub_at i n [m, ..arr] = [m, ..sub_at (i - 1) n arr]
35
30
36
36
-
func below unit unit = true
37
37
-
func below a:ra b:rb = if b <= a then below ra rb else false
31
31
+
func apply_button _ [] target = target
32
32
+
func apply_button n [i, ..rest] target = apply_button n rest <| sub_at i n <| target
38
33
39
39
-
func zero unit = unit
40
40
-
func zero _ : rest = 0 : zero rest
34
34
+
func covers target coverage =
35
35
+
it::from target
36
36
+
|> it::enumerate
37
37
+
|> it::all (fn i:v. v == 0 || contains i coverage)
38
38
+
39
39
+
proc solvable!(remaining, target, all_buttons and [button, ..buttons]) {
40
40
+
if remaining < reduce max target || !(covers target <| set::collect <| it::from <| flatten all_buttons) {
41
41
+
return false
42
42
+
}
43
43
+
let limit = min remaining <| limit_within target button
44
44
+
return it::range limit 0
45
45
+
|> it::any (fn times.
46
46
+
let new_target = apply_button times button target,
47
47
+
if all ((==) 0) new_target
48
48
+
then true
49
49
+
else buttons != [] && solvable!(remaining - times, new_target, prioritize new_target buttons)
50
50
+
)
51
51
+
}
52
52
+
53
53
+
func range_size target buttons button =
54
54
+
let others = set::collect <| it::from <| flatten <| filter ((!=) button) buttons,
55
55
+
let upper = limit_within target button,
56
56
+
let lower = if covers target others then 0 else upper,
57
57
+
upper - lower
58
58
+
59
59
+
func prioritize target buttons =
60
60
+
sort_by (asc <| range_size target buttons) buttons
41
61
42
62
proc solve!(target:buttons) {
43
43
-
let mut visited = [| zero target |]
44
44
-
let mut states = [| zero target |]
45
45
-
let mut i = 0
46
46
-
while !(contains target states) {
47
47
-
dbg!(i)
48
48
-
let new_states = states
49
49
-
|> it::from
50
50
-
|> it::flat_map (fn state. it::from <| map (press_button state) buttons)
51
51
-
|> it::filter (below target)
52
52
-
|> collect
53
53
-
states = difference new_states visited
54
54
-
visited union= new_states
63
63
+
let mut i = reduce max target
64
64
+
let buttons_ordered = prioritize target buttons
65
65
+
while !solvable!(i, target, buttons_ordered) {
55
66
i += 1
67
67
+
dbg!('try(i))
56
68
}
57
69
return i
58
70
}
···
60
72
proc main!() {
61
73
readlines
62
74
|> it::map (parse machine)
63
63
-
|> it::map dbg
64
75
|> it::map solve
65
65
-
|> it::map dbg
66
76
|> it::fold (+) 0
67
77
|> dbg
68
78
}