From cf21b4cecc64ca7081cbce22ed16db3c1588f2b7 Mon Sep 17 00:00:00 2001 From: Caleb Webber Date: Wed, 4 Dec 2024 01:10:13 -0500 Subject: [PATCH] aoc 2024 day 4 --- elixir/livebook/2024/day4.livemd | 83 ++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 elixir/livebook/2024/day4.livemd diff --git a/elixir/livebook/2024/day4.livemd b/elixir/livebook/2024/day4.livemd new file mode 100644 index 0000000..5fb3f26 --- /dev/null +++ b/elixir/livebook/2024/day4.livemd @@ -0,0 +1,83 @@ +# AOC 2024 Day 4 + +## Section + +```elixir +input = """ +MMMSXXMASM +MSAMXMSMSA +AMXSXMAAMM +MSAMASMSMX +XMASAMXAMM +XXAMMXXAMA +SMSMSASXSS +SAXAMASAAA +MAMMMXMMMM +MXMXAXMASX +""" +``` + +```elixir +lines = input |> String.trim() |> String.split("\n") +``` + +```elixir +g = Grid2D.new( + lines |> Enum.at(0) |> String.trim() |> String.graphemes() |> Enum.count(), + lines |> Enum.count +) +``` + +```elixir +input = input |> String.replace("\n", "") +``` + +```elixir +find_word = fn + _, w, pl, w, _, _ -> pl + input, word, [pos | _] = poslist, curr, dir, f -> + + ["", <> <> _] = String.split(word, curr) + coord = Grid2D.index_to_coord(g, pos) + next = Grid2D.add(coord, dir) + + if Grid2D.in_grid?(next, g) and (next_letter == String.at(input, index)) do + index = Grid2D.coord_to_index(g, next) + f.(input, word, index, [index | poslist], curr <> next_letter, dir, f) + else + nil + end +end +``` + +```elixir +for [{idx, _}] <- Regex.scan(~r/X/, input, return: :index), + i <- -1..1//1, + j <- -1..1//1, + j != 0 or i != 0 do + find_word.(input, "XMAS", [idx], "X", {i, j}, find_word) +end |> Enum.reject(&(&1 == nil)) |> Enum.count() +``` + +```elixir +is_xmas? = + fn grid, coord-> + corners = [{1,1}, {1,-1}, {-1, -1}, {-1, 1}] |> Enum.map(&Grid2D.add(coord, &1)) + has_corners? = Enum.all?( + corners, + fn p -> Grid2D.in_grid?(p, g) end + ) + corner_letters = (corners |> Enum.map(fn c -> String.at(grid, Grid2D.coord_to_index(g, c)) end)) + is_mas? = fn -> corner_letters |> Enum.chunk_every(2, 1, :discard) |> Enum.any?(fn i -> i == ["S", "S"] or i == ["M", "M"] end) end + has_m? = fn -> (corner_letters |> Enum.count(&(&1 == "M"))) == 2 end + has_s? = fn -> (corner_letters |> Enum.count(&(&1 == "S"))) == 2 end + has_corners? and has_m?.() and has_s?.() and is_mas?.() + end +``` + +```elixir +for [{i, _}] <- Regex.scan(~r/A/, input, return: :index), + coord = Grid2D.index_to_coord(g, i) do + { coord, is_xmas?.(input, coord)} +end |> Enum.count(fn {_, t} -> t end) +```