aoc2024/src/day4_p1.gleam

66 lines
1.4 KiB
Gleam
Raw Normal View History

2024-12-04 09:27:50 +00:00
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) }
}