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 let split_v = split(v, " ")
102 case split_v {
103 ["toggle", loc1, _, loc2] ->
104 Action(Toggle, str_to_loc(loc1), str_to_loc(loc2))
105 ["turn", "off", loc1, _, loc2] ->
106 Action(TurnOff, str_to_loc(loc1), str_to_loc(loc2))
107 ["turn", "on", loc1, _, loc2] ->
108 Action(TurnOn, str_to_loc(loc1), str_to_loc(loc2))
109 _ -> Action(Toggle, Location(0, 0), Location(0, 0))
110 }
111 })
112
113 println(
114 input
115 |> list.fold(dict.new(), fn(grid, a) { grid |> do_action(a) })
116 |> get_grid_true_count
117 |> to_string,
118 )
119
120 println(
121 input
122 |> list.fold(dict.new(), fn(grid, a) { grid |> do_action_int(a) })
123 |> get_grid_total_brightness
124 |> to_string,
125 )
126}