+18
-2
2025/3/gleam/src/main.gleam
+18
-2
2025/3/gleam/src/main.gleam
···
7
8
pub fn do(input, digits) {
9
input
10
|> list.fold(0, fn(acc, bank) {
11
let #(n, _) =
12
list.range(digits - 1, 0)
13
|> list.fold(#(0, bank), fn(acc, i) {
14
let #(number, bank) = acc
15
16
-
let #(max, loc) =
17
bank
18
|> list.reverse
19
|> list.drop(i)
20
|> list.reverse
21
|> list.index_map(fn(n, i) { #(n, i) })
22
|> list.max(fn(a, b) { int.compare(a.0, b.0) })
23
-
|> result.unwrap(#(0, 0))
24
25
#(number * 10 + max, list.drop(bank, loc + 1))
26
})
27
acc + n
28
})
29
}
···
36
|> string.trim
37
|> string.split("\n")
38
|> list.map(fn(bank) {
39
string.to_graphemes(bank)
40
|> list.map(fn(s) { int.parse(s) |> result.unwrap(0) })
41
})
···
7
8
pub fn do(input, digits) {
9
input
10
+
// ok so here we're just iterating through all the battery banks in the input
11
|> list.fold(0, fn(acc, bank) {
12
let #(n, _) =
13
+
// and here we're going and doing it the amount of times necessary. it's backwards for obvious reasons, we start from the end and this let's us not have like duplicated logic where we're doing digits - i constantly
14
list.range(digits - 1, 0)
15
+
// didn't want to create a type for it so yeah #(the digit we're at, the remaining part of the bank)
16
|> list.fold(#(0, bank), fn(acc, i) {
17
+
// annoying gleam stuff i wish i could destructure it from the function
18
let #(number, bank) = acc
19
20
+
// that's the part that matters, and the one i took forever in and ended up splitting in multiple variables when i didn't need to
21
+
// but like it's very simple
22
+
// gleam doesn't let you drop from the end of lists, so we reverse the list, drop the digits we cannot use because they will necessarily be used latter in the number. the last i is the minimum because like we need at the very least finish the number yk
23
+
// and then the really annoying part, we turn it into an index map, so we can get the location of the number to later drop that part off for the next digit
24
+
// and then we get the highest number
25
+
// and done here
26
+
// little assert because failing is better than the silent failing of unwrap
27
+
let assert Ok(#(max, loc)) =
28
bank
29
|> list.reverse
30
|> list.drop(i)
31
|> list.reverse
32
|> list.index_map(fn(n, i) { #(n, i) })
33
|> list.max(fn(a, b) { int.compare(a.0, b.0) })
34
35
+
// and then we send it off to the next digit
36
+
// i wasn't using this number trick when i was doing it, i was literally just finding a power of 10 and multiplying it but like the power thing in gleam sucks it's like float only. i now learned this trick from *someone* and will be using it. don't know how i didn't figure out myself. oh wait i do it's because i'm stupid
37
+
// but yeah it just multiplies the number by ten so like 4 becomes 40 and then we add our like 3 to it 43 and then 43 to 430 and the 5 you get the gist of it. again don't know how i didn't see it myself
38
+
// and then we drop the parts of the list that can't be used for the subsequent numbers. like off by one evil thing in here to not include the number we just used too
39
#(number * 10 + max, list.drop(bank, loc + 1))
40
})
41
+
// and then like every advent of code we add it to the acc
42
acc + n
43
})
44
}
···
51
|> string.trim
52
|> string.split("\n")
53
|> list.map(fn(bank) {
54
+
// just get all the battery banks, separate them by character and turn each character in a member of a list
55
string.to_graphemes(bank)
56
|> list.map(fn(s) { int.parse(s) |> result.unwrap(0) })
57
})