diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..b242499 --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +erlang 27.1.2 diff --git a/sample/day4-sample.txt b/sample/day4-sample.txt new file mode 100644 index 0000000..1f4eda2 --- /dev/null +++ b/sample/day4-sample.txt @@ -0,0 +1,10 @@ +MMMSXXMASM +MSAMXMSMSA +AMXSXMAAMM +MSAMASMSMX +XMASAMXAMM +XXAMMXXAMA +SMSMSASXSS +SAXAMASAAA +MAMMMXMMMM +MXMXAXMASX diff --git a/src/day4_p1.gleam b/src/day4_p1.gleam new file mode 100644 index 0000000..c61f5c6 --- /dev/null +++ b/src/day4_p1.gleam @@ -0,0 +1,65 @@ +import gleam/dict.{type Dict} +import gleam/int +import gleam/io +import gleam/iterator +import gleam/list.{filter, fold, index_map, map} +import gleam/string +import stdin.{stdin} + +const word_size = 4 + +const directions = [#(1, 0), #(1, -1), #(1, 1), #(0, 1)] + +pub fn main() { + stdin() |> read_input |> find_xmas |> io.debug +} + +fn find_xmas(xmas_map: Dict(#(Int, Int), String)) -> Int { + xmas_map + |> dict.filter(fn(_, char) { char == "X" || char == "S" }) + |> dict.keys + |> map(fn(coord) { + directions + |> list.count(fn(dir) { + case + xmas_map + |> dict.take(traverse(coord, dir)) + |> dict.values + { + ["X", "M", "A", "S"] -> True + ["S", "A", "M", "X"] -> True + _ -> False + } + }) + }) + |> fold(0, int.add) +} + +fn traverse(start: #(Int, Int), direction: #(Int, Int)) { + let #(s_x, s_y) = start + + direction + |> list.repeat(word_size) + |> list.index_map(fn(dir, idx) { + let #(x, y) = dir + #(s_x + x * idx, s_y + y * idx) + }) +} + +fn read_input(it: iterator.Iterator(String)) -> Dict(#(Int, Int), String) { + it + |> iterator.to_list + |> map(string.trim) + |> filter(not(string.is_empty)) + |> index_map(fn(str, col) { + str + |> string.to_graphemes + |> index_map(fn(char, row) { #(#(row, col), char) }) + }) + |> list.flatten + |> dict.from_list +} + +fn not(a: fn(a) -> Bool) { + fn(param: a) -> Bool { !a(param) } +} diff --git a/src/day4_p2.gleam b/src/day4_p2.gleam new file mode 100644 index 0000000..6aa3e8f --- /dev/null +++ b/src/day4_p2.gleam @@ -0,0 +1,54 @@ +import gleam/dict.{type Dict} +import gleam/io +import gleam/iterator +import gleam/list.{count, filter, index_map, map} +import gleam/string +import stdin.{stdin} + +pub fn main() { + stdin() |> read_input |> find_xmas |> io.debug +} + +fn find_xmas(xmas_map: Dict(#(Int, Int), String)) -> Int { + xmas_map + |> dict.filter(fn(_, char) { char == "A" }) + |> dict.keys + |> count(fn(coord) { + coord + |> traverse + |> list.all(fn(keys) { + case + xmas_map + |> dict.take(keys) + |> dict.values + { + ["M", "S"] -> True + ["S", "M"] -> True + _ -> False + } + }) + }) +} + +fn traverse(start: #(Int, Int)) { + let #(x, y) = start + [[#(x - 1, y - 1), #(x + 1, y + 1)], [#(x - 1, y + 1), #(x + 1, y - 1)]] +} + +fn read_input(it: iterator.Iterator(String)) -> Dict(#(Int, Int), String) { + it + |> iterator.to_list + |> map(string.trim) + |> filter(not(string.is_empty)) + |> index_map(fn(str, col) { + str + |> string.to_graphemes + |> index_map(fn(char, row) { #(#(row, col), char) }) + }) + |> list.flatten + |> dict.from_list +} + +fn not(a: fn(a) -> Bool) { + fn(param: a) -> Bool { !a(param) } +}