+74
day4/day4.gleam
+74
day4/day4.gleam
···
1
+
import gleam/bool
2
+
import gleam/dict
3
+
import gleam/int
4
+
import gleam/io
5
+
import gleam/list
6
+
import gleam/string
7
+
import simplifile
8
+
9
+
pub fn main() {
10
+
let assert Ok(raw_input) = simplifile.read("src/day4/input.txt")
11
+
12
+
let input =
13
+
raw_input
14
+
|> string.trim
15
+
|> string.split("\n")
16
+
|> list.index_map(fn(x, i) {
17
+
string.to_graphemes(x)
18
+
|> list.index_map(fn(y, ii) { #(#(ii, i), y) })
19
+
})
20
+
|> list.flatten
21
+
|> dict.from_list
22
+
23
+
let part1 =
24
+
dict.fold(input, 0, fn(acc, k, v) {
25
+
use <- bool.guard(v == ".", acc)
26
+
let n =
27
+
list.flat_map([-1, 0, 1], fn(x) {
28
+
list.map([-1, 0, 1], fn(y) { #(k.0 + x, k.1 + y) })
29
+
})
30
+
|> list.filter(fn(x) { x != k })
31
+
|> list.fold(0, fn(acc2, k2) {
32
+
case dict.get(input, k2) {
33
+
Ok("@") -> acc2 + 1
34
+
_ -> acc2
35
+
}
36
+
})
37
+
case n < 4 {
38
+
True -> acc + 1
39
+
False -> acc
40
+
}
41
+
})
42
+
43
+
io.println("Part 1: " <> int.to_string(part1))
44
+
45
+
let part2 = do_remove(input, 0)
46
+
47
+
io.println("Part 2: " <> int.to_string(part2))
48
+
}
49
+
50
+
fn do_remove(rolls: dict.Dict(#(Int, Int), String), count: Int) -> Int {
51
+
let #(c, r) =
52
+
dict.fold(rolls, #(0, []), fn(acc, k, v) {
53
+
use <- bool.guard(v == ".", acc)
54
+
let n =
55
+
list.flat_map([-1, 0, 1], fn(x) {
56
+
list.map([-1, 0, 1], fn(y) { #(k.0 + x, k.1 + y) })
57
+
})
58
+
|> list.filter(fn(x) { x != k })
59
+
|> list.fold(0, fn(acc2, k2) {
60
+
case dict.get(rolls, k2) {
61
+
Ok("@") -> acc2 + 1
62
+
_ -> acc2
63
+
}
64
+
})
65
+
case n < 4 {
66
+
True -> #(acc.0 + 1, [#(k, "."), ..acc.1])
67
+
False -> #(acc.0, [#(k, v), ..acc.1])
68
+
}
69
+
})
70
+
case c == 0 {
71
+
True -> count
72
+
False -> do_remove(dict.from_list(r), count + c)
73
+
}
74
+
}