tangled
alpha
login
or
join now
regnault.dev
/
gleam-aoc-2025
1
fork
atom
this repo has no description
1
fork
atom
overview
issues
pulls
pipelines
Day 8
regnault.dev
2 months ago
69fe58bc
9a24da7e
+131
2 changed files
expand all
collapse all
unified
split
src
aoc.gleam
days
day8.gleam
+2
src/aoc.gleam
···
7
7
import days/day5
8
8
import days/day6
9
9
import days/day7
10
10
+
import days/day8
10
11
import gleam/erlang
11
12
import gleam/int
12
13
import gleam/io
···
33
34
5 -> day5.start()
34
35
6 -> day6.start()
35
36
7 -> day7.start()
37
37
+
8 -> day8.start()
36
38
_ -> io.println("Tried to run day " <> int.to_string(day))
37
39
}
38
40
birl.now()
+129
src/days/day8.gleam
···
1
1
+
import gleam/float
2
2
+
import gleam/int
3
3
+
import gleam/io
4
4
+
import gleam/list
5
5
+
import gleam/order
6
6
+
import gleam/result
7
7
+
import gleam/set
8
8
+
import gleam/string
9
9
+
import gleam_community/maths
10
10
+
import simplifile
11
11
+
12
12
+
pub fn start() -> Nil {
13
13
+
let assert Ok(content) = simplifile.read("inputs/day8.txt")
14
14
+
let data = parse(content)
15
15
+
16
16
+
let _ = io.debug(part1(data))
17
17
+
let _ = io.debug(part2(data))
18
18
+
19
19
+
Nil
20
20
+
}
21
21
+
22
22
+
type Coord {
23
23
+
Coord(x: Float, y: Float, z: Float)
24
24
+
}
25
25
+
26
26
+
fn parse(data: String) {
27
27
+
string.split(data, "\n")
28
28
+
|> list.map(fn(x) {
29
29
+
let assert [x, y, z] =
30
30
+
string.split(x, ",")
31
31
+
|> list.map(fn(x) { int.parse(x) |> result.unwrap(0) |> int.to_float })
32
32
+
Coord(x, y, z)
33
33
+
})
34
34
+
}
35
35
+
36
36
+
fn distance(c1: Coord, c2: Coord) -> Float {
37
37
+
let to_root =
38
38
+
{
39
39
+
float.power(c1.x -. c2.x, 2.0)
40
40
+
|> result.unwrap(0.0)
41
41
+
}
42
42
+
+. {
43
43
+
float.power(c1.y -. c2.y, 2.0)
44
44
+
|> result.unwrap(0.0)
45
45
+
}
46
46
+
+. {
47
47
+
float.power(c1.z -. c2.z, 2.0)
48
48
+
|> result.unwrap(0.0)
49
49
+
}
50
50
+
51
51
+
float.square_root(to_root) |> result.unwrap(9_999_999_999_999_999_999.0)
52
52
+
}
53
53
+
54
54
+
fn part1(data: List(Coord)) {
55
55
+
let circuits = list.map(data, fn(x) { set.from_list([x]) })
56
56
+
list.index_map(data, fn(first, idx) {
57
57
+
list.drop(data, idx + 1)
58
58
+
|> list.map(fn(second) {
59
59
+
let d = distance(first, second)
60
60
+
#(first, second, d)
61
61
+
})
62
62
+
})
63
63
+
|> list.flatten
64
64
+
|> list.sort(fn(c1, c2) {
65
65
+
case c1.2 <. c2.2 {
66
66
+
True -> order.Lt
67
67
+
_ ->
68
68
+
case c1.2 == c2.2 {
69
69
+
True -> order.Eq
70
70
+
_ -> order.Gt
71
71
+
}
72
72
+
}
73
73
+
})
74
74
+
|> list.take(1000)
75
75
+
|> list.fold(circuits, fn(acc, coords) {
76
76
+
let #(c1, c2, _) = coords
77
77
+
let assert Ok(s1) = list.find(acc, set.contains(_, c1))
78
78
+
let assert Ok(s2) = list.find(acc, set.contains(_, c2))
79
79
+
let acc =
80
80
+
list.filter(acc, fn(x) { !{ set.contains(x, c1) || set.contains(x, c2) } })
81
81
+
82
82
+
[set.union(s1, s2), ..acc]
83
83
+
})
84
84
+
|> list.map(set.size)
85
85
+
|> list.sort(int.compare)
86
86
+
|> list.reverse
87
87
+
|> list.take(3)
88
88
+
|> list.fold(1, int.multiply)
89
89
+
}
90
90
+
91
91
+
fn part2(data) {
92
92
+
let circuits = list.map(data, fn(x) { set.from_list([x]) })
93
93
+
list.index_map(data, fn(first, idx) {
94
94
+
list.drop(data, idx + 1)
95
95
+
|> list.map(fn(second) {
96
96
+
let d = distance(first, second)
97
97
+
#(first, second, d)
98
98
+
})
99
99
+
})
100
100
+
|> list.flatten
101
101
+
|> list.sort(fn(c1, c2) {
102
102
+
case c1.2 <. c2.2 {
103
103
+
True -> order.Lt
104
104
+
_ ->
105
105
+
case c1.2 == c2.2 {
106
106
+
True -> order.Eq
107
107
+
_ -> order.Gt
108
108
+
}
109
109
+
}
110
110
+
})
111
111
+
|> list.fold_until(circuits, fn(acc, coords) {
112
112
+
let #(c1, c2, _) = coords
113
113
+
let assert Ok(s1) = list.find(acc, set.contains(_, c1))
114
114
+
let assert Ok(s2) = list.find(acc, set.contains(_, c2))
115
115
+
let acc =
116
116
+
list.filter(acc, fn(x) { !{ set.contains(x, c1) || set.contains(x, c2) } })
117
117
+
118
118
+
let new = [set.union(s1, s2), ..acc]
119
119
+
case list.length(new) {
120
120
+
1 -> list.Stop([set.new() |> set.insert(c1) |> set.insert(c2)])
121
121
+
_ -> list.Continue(new)
122
122
+
}
123
123
+
})
124
124
+
|> list.first
125
125
+
|> result.unwrap(set.new())
126
126
+
|> set.to_list()
127
127
+
|> list.fold(1.0, fn(acc, x) { acc *. x.x })
128
128
+
|> float.round
129
129
+
}