65 lines
1.4 KiB
Gleam
65 lines
1.4 KiB
Gleam
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) }
|
|
}
|