my solutions to advent of code
aoc
advent-of-code
1import gleam/dict.{type Dict}
2import gleam/int.{to_string}
3import gleam/io.{println}
4import gleam/list.{fold, map}
5import gleam/result.{unwrap}
6import gleam/string.{split, trim}
7import simplifile.{read}
8
9pub type Location {
10 Location(x: Int, y: Int)
11}
12
13pub type ActionType {
14 Toggle
15 TurnOn
16 TurnOff
17}
18
19pub type Action {
20 Action(atype: ActionType, loc1: Location, loc2: Location)
21}
22
23pub type Grid =
24 Dict(Location, Bool)
25
26pub type GridInt =
27 Dict(Location, Int)
28
29pub fn str_to_loc(str) -> Location {
30 let extract =
31 str
32 |> split(",")
33 |> map(fn(v) { int.base_parse(v, 10) |> unwrap(0) })
34 case extract {
35 [x, y] -> Location(x, y)
36 _ -> Location(0, 0)
37 }
38}
39
40pub fn do_action(grid: Grid, action: Action) {
41 list.range(action.loc1.y, action.loc2.y)
42 |> fold(grid, fn(grid, y) {
43 list.range(action.loc1.x, action.loc2.x)
44 |> fold(grid, fn(grid, x) {
45 let loc = Location(x, y)
46 let value = case action.atype {
47 Toggle -> !{ grid |> dict.get(loc) |> unwrap(False) }
48 TurnOff -> False
49 TurnOn -> True
50 }
51 case value {
52 False -> grid |> dict.delete(loc)
53 True -> grid |> dict.insert(loc, value)
54 }
55 })
56 })
57}
58
59pub fn get_grid_true_count(grid: Grid) {
60 grid
61 |> dict.fold(0, fn(cur, _, v) {
62 case v {
63 True -> cur + 1
64 False -> cur
65 }
66 })
67}
68
69pub fn do_action_int(grid: GridInt, action: Action) {
70 list.range(action.loc1.y, action.loc2.y)
71 |> fold(grid, fn(grid, y) {
72 list.range(action.loc1.x, action.loc2.x)
73 |> fold(grid, fn(grid, x) {
74 let loc = Location(x, y)
75 let cur = grid |> dict.get(loc) |> unwrap(0)
76 let value = case action.atype {
77 Toggle -> cur + 2
78 TurnOff -> int.max(0, cur - 1)
79 TurnOn -> int.max(0, cur + 1)
80 }
81 case value > 0 {
82 False -> grid |> dict.delete(loc)
83 True -> grid |> dict.insert(loc, value)
84 }
85 })
86 })
87}
88
89pub fn get_grid_total_brightness(grid: GridInt) {
90 grid
91 |> dict.fold(0, fn(cur, _, v) { cur + v })
92}
93
94pub fn main() {
95 let input =
96 read(from: "../input.txt")
97 |> unwrap("")
98 |> trim()
99 |> split("\n")
100 |> list.map(fn(v) {
101 case split(v, " ") {
102 ["toggle", loc1, _, loc2] ->
103 Action(Toggle, str_to_loc(loc1), str_to_loc(loc2))
104 ["turn", "off", loc1, _, loc2] ->
105 Action(TurnOff, str_to_loc(loc1), str_to_loc(loc2))
106 ["turn", "on", loc1, _, loc2] ->
107 Action(TurnOn, str_to_loc(loc1), str_to_loc(loc2))
108 _ -> Action(Toggle, Location(0, 0), Location(0, 0))
109 }
110 })
111
112 println(
113 input
114 |> list.fold(dict.new(), fn(grid, a) { grid |> do_action(a) })
115 |> get_grid_true_count
116 |> to_string,
117 )
118
119 println(
120 input
121 |> list.fold(dict.new(), fn(grid, a) { grid |> do_action_int(a) })
122 |> get_grid_total_brightness
123 |> to_string,
124 )
125}