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 21
eldridge.cam
1 month ago
ff7de259
b337f7e1
+111
2 changed files
expand all
collapse all
unified
split
2021
21
p1.tri
p2.tri
+35
2021/21/p1.tri
···
1
1
+
import "trilogy:debug" use dbg
2
2
+
import "trilogy:io" use readline
3
3
+
import "trilogy:parsec" use parse, prefixed_by, string, integer
4
4
+
5
5
+
proc main!() {
6
6
+
let mut p1_position = (parse (prefixed_by (string "Player 1 starting position: ") integer) readline!()) - 1
7
7
+
let mut p2_position = (parse (prefixed_by (string "Player 2 starting position: ") integer) readline!()) - 1
8
8
+
let mut p1_score = 0
9
9
+
let mut p2_score = 0
10
10
+
let mut turn = true
11
11
+
let mut rolls = 0
12
12
+
let mut die = 1
13
13
+
let roll = do() {
14
14
+
let output = die
15
15
+
die += 1
16
16
+
rolls += 1
17
17
+
if (die > 100) {
18
18
+
die = 1
19
19
+
}
20
20
+
return output
21
21
+
}
22
22
+
while p1_score < 1000 && p2_score < 1000 {
23
23
+
let distance = roll!() + roll!() + roll!()
24
24
+
if turn {
25
25
+
p1_position = (p1_position + distance) % 10
26
26
+
p1_score += p1_position + 1
27
27
+
} else {
28
28
+
p2_position = (p2_position + distance) % 10
29
29
+
p2_score += p2_position + 1
30
30
+
}
31
31
+
turn = !turn
32
32
+
}
33
33
+
dbg!(rolls * if p1_score >= 1000 { p2_score } else { p1_score })
34
34
+
exit 0
35
35
+
}
+76
2021/21/p2.tri
···
1
1
+
import "trilogy:debug" use dbg
2
2
+
import "trilogy:io" use readline
3
3
+
import "trilogy:parsec" use parse, prefixed_by, string, integer
4
4
+
import "trilogy:array" use push, pop
5
5
+
import "trilogy:compare" use max, min, asc
6
6
+
import "trilogy:heap" use heap
7
7
+
8
8
+
proc dirac!(cb) {
9
9
+
with cb!() {
10
10
+
when 'roll {
11
11
+
resume 1
12
12
+
resume 2
13
13
+
resume 3
14
14
+
cancel unit
15
15
+
}
16
16
+
}
17
17
+
}
18
18
+
19
19
+
proc roll!() {
20
20
+
yield 'roll
21
21
+
}
22
22
+
23
23
+
func next_player (x:y:_:_:_) = min x y
24
24
+
25
25
+
func cmp (ax:ay:_:_:_) (bx:by:_:_:_) = {
26
26
+
let amin = min ax ay
27
27
+
let amax = max ax ay
28
28
+
let bmin = min bx by
29
29
+
let bmax = max bx by
30
30
+
if amin == bmin then amax <= bmax else amin <= bmin
31
31
+
}
32
32
+
33
33
+
func asc_eq f a b = f a <= f b
34
34
+
35
35
+
proc main!() {
36
36
+
let p1_start = (parse (prefixed_by (string "Player 1 starting position: ") integer) readline!()) - 1
37
37
+
let p2_start = (parse (prefixed_by (string "Player 2 starting position: ") integer) readline!()) - 1
38
38
+
39
39
+
let states = {| 0:0:p1_start:p2_start:true => 1 |}
40
40
+
let min_heap = heap cmp
41
41
+
let queue = [0:0:p1_start:p2_start:true]
42
42
+
43
43
+
let mut p1_wins = 0
44
44
+
let mut p2_wins = 0
45
45
+
while queue != [] {
46
46
+
let key = min_heap::pop!(queue)
47
47
+
let dups = states.key
48
48
+
using dirac
49
49
+
let distance = roll!() + roll!() + roll!()
50
50
+
let mut p1_score:mut p2_score:mut p1_position:mut p2_position:turn = key
51
51
+
if turn {
52
52
+
p1_position = (p1_position + distance) % 10
53
53
+
p1_score += p1_position + 1
54
54
+
if p1_score >= 21 {
55
55
+
p1_wins += dups
56
56
+
return unit
57
57
+
}
58
58
+
} else {
59
59
+
p2_position = (p2_position + distance) % 10
60
60
+
p2_score += p2_position + 1
61
61
+
if p2_score >= 21 {
62
62
+
p2_wins += dups
63
63
+
return unit
64
64
+
}
65
65
+
}
66
66
+
let new_key = p1_score:p2_score:p1_position:p2_position:!turn
67
67
+
with { states.new_key = dups + states.new_key } {
68
68
+
when 'mia {
69
69
+
min_heap::push!(queue, new_key)
70
70
+
become 0
71
71
+
}
72
72
+
}
73
73
+
}
74
74
+
dbg!(max p1_wins p2_wins)
75
75
+
exit 0
76
76
+
}