my solutions to advent of code
aoc
advent-of-code
1import gleam/bit_array
2import gleam/int
3import gleam/io
4import gleam/list
5import gleam/result
6import gleam/string
7import simplifile as file
8
9fn get_place(x, y, map, size) {
10 case
11 case x, y {
12 _, -1 | -1, _ -> <<>>
13 s, _ | _, s if s == size -> <<>>
14
15 _, _ -> bit_array.slice(map, y * size + x, 1) |> result.unwrap(<<>>)
16 }
17 {
18 <<"@">> -> 1
19 _ -> 0
20 }
21}
22
23fn part_1(map, size) {
24 list.range(0, bit_array.byte_size(map) - 1)
25 |> list.fold(0, fn(acc, pos) {
26 let x = pos % size
27 let y = pos / size
28
29 let roll = get_place(x, y, map, size)
30
31 let neighbours =
32 get_place(x - 1, y - 1, map, size)
33 + get_place(x, y - 1, map, size)
34 + get_place(x + 1, y - 1, map, size)
35 + get_place(x - 1, y, map, size)
36 + get_place(x + 1, y, map, size)
37 + get_place(x - 1, y + 1, map, size)
38 + get_place(x, y + 1, map, size)
39 + get_place(x + 1, y + 1, map, size)
40
41 case roll, neighbours < 4 {
42 1, True -> acc + 1
43 _, _ -> acc
44 }
45 })
46}
47
48fn part_2(map, size, rolls) {
49 let #(rolls, new_map) =
50 list.range(0, bit_array.byte_size(map) - 1)
51 |> list.fold(#(rolls, <<>>), fn(acc, pos) {
52 let #(total, new_map) = acc
53 let x = pos % size
54 let y = pos / size
55
56 let roll = get_place(x, y, map, size)
57
58 let neighbours =
59 get_place(x - 1, y - 1, map, size)
60 + get_place(x, y - 1, map, size)
61 + get_place(x + 1, y - 1, map, size)
62 + get_place(x - 1, y, map, size)
63 + get_place(x + 1, y, map, size)
64 + get_place(x - 1, y + 1, map, size)
65 + get_place(x, y + 1, map, size)
66 + get_place(x + 1, y + 1, map, size)
67
68 case roll, neighbours < 4 {
69 1, True -> #(total + 1, bit_array.append(new_map, <<".">>))
70 1, _ -> #(total, bit_array.append(new_map, <<"@">>))
71 _, _ -> #(total, bit_array.append(new_map, <<".">>))
72 }
73 })
74
75 case map == new_map {
76 True -> rolls
77 False -> part_2(new_map, size, rolls)
78 }
79}
80
81pub fn main() {
82 let assert Ok(input) = file.read(from: "../input.txt")
83 as "Input file not found"
84 let input =
85 input |> string.trim |> string.split("\n") |> list.map(fn(v) { <<v:utf8>> })
86 let size = list.length(input)
87 let input = input |> list.fold(<<>>, fn(acc, l) { bit_array.append(acc, l) })
88 // @ and .
89
90 part_1(input, size)
91 |> int.to_string
92 |> io.println
93 part_2(input, size, 0)
94 |> int.to_string
95 |> io.println
96}