bjorng
Erlang Core Team
Most Liked
BartOtten
Looking at your code I see which rabbit hole you experienced. I experienced the same and just dropped all code and started from scratch.
You made it, which is the most important ![]()
3
woojiahao
Today looked more intimidating than it actually was. General strategy is to bruteforce all directions. We can minimize bruteforce area by only searching when “X” (for part 1) or “A” (for part 2):
defmodule AOC.Y2024.Day4 do
@moduledoc false
use AOC.Solution
@dirs [
{-1, 0},
{1, 0},
{0, -1},
{0, 1},
{-1, -1},
{-1, 1},
{1, -1},
{1, 1}
]
@impl true
def load_data() do
Data.load_day_as_grid(2024, 4)
end
@impl true
def part_one({grid, _, _}) do
grid
|> Enum.filter(fn {_, v} -> v == "X" end)
|> General.map_sum(fn {coord, _} -> count_xmas(grid, coord) end)
end
@impl true
def part_two({grid, _, _}) do
grid
|> Enum.filter(fn {_, v} -> v == "A" end)
|> Enum.count(fn {coord, _} -> has_x_mas(grid, coord) end)
end
defp has_x_mas(grid, {r, c}) do
[tl, tr, bl, br] =
@dirs
|> Enum.slice(4..-1//1)
|> Enum.map(fn {dr, dc} -> {r + dr, c + dc} end)
|> Enum.map(fn coord -> Map.get(grid, coord, ".") end)
([tl, br] == ["M", "S"] or [tl, br] == ["S", "M"]) and
([tr, bl] == ["M", "S"] or [tr, bl] == ["S", "M"])
end
defp count_xmas(grid, {r, c}) do
for {dr, dc} <- @dirs do
0..3
|> Enum.map(fn j -> {r + dr * j, c + dc * j} end)
|> Enum.map_join(fn coord -> Map.get(grid, coord, ".") end)
end
|> Enum.count(fn v -> v == "XMAS" end)
end
end
2
Aetherus
I feel part 2 is actually easier.
defmodule AoC2024.Day04 do
def part_1(grid) do
directions =
for di <- -1..1,
dj <- -1..1,
di != 0 or dj != 0,
do: {di, dj}
directions
|> Enum.map(fn {di, dj} ->
Enum.count(Map.keys(grid), fn coord ->
coord
|> Stream.iterate(fn {i, j} -> {i + di, j + dj} end)
|> Stream.take(4)
|> Enum.map(&grid[&1])
|> Kernel.==(~c"XMAS")
end)
end)
|> Enum.sum()
end
def part_2(grid) do
Enum.count(grid, fn
{{i, j}, ?A} ->
[grid[{i - 1, j - 1}], grid[{i + 1, j + 1}]] in [~c"MS", ~c"SM"] and
[grid[{i - 1, j + 1}], grid[{i + 1, j - 1}]] in [~c"MS", ~c"SM"]
_ ->
false
end)
end
end
where grid is built like this:
charlists = puzzle_input |> String.split() |> Enum.map(&String.to_charlist/1)
grid =
for {row, i} <- Enum.with_index(charlists),
{char, j} <- Enum.with_index(row),
into: %{},
do: {{i, j}, char}
2
sevenseacat
Author of Ash Framework
Oh I really like the idea of having helpers in the grid for moving in different directions! Much less magic -1 and 1 everywhere ![]()
2
lkuty
#!/usr/bin/env elixir
# Aoc 2024. day 4.
defmodule Part1 do
@spec xmas(map(), non_neg_integer(), non_neg_integer()) :: non_neg_integer()
def xmas(m, r, c) do
b2i(unquote(:"xmas↑")(m, r, c)) +
b2i(unquote(:"xmas↗")(m, r, c)) +
b2i(unquote(:"xmas→")(m, r, c)) +
b2i(unquote(:"xmas↘")(m, r, c)) +
b2i(unquote(:"xmas↓")(m, r, c)) +
b2i(unquote(:"xmas↙")(m, r, c)) +
b2i(unquote(:"xmas←")(m, r, c)) +
b2i(unquote(:"xmas↖")(m, r, c))
end
defp unquote(:"xmas↑")(m, r, c),
do: m[{r,c}] == "X" && m[{r-1,c}] == "M" && m[{r-2,c}] == "A" && m[{r-3,c}] == "S"
defp unquote(:"xmas↗")(m, r, c),
do: m[{r,c}] == "X" && m[{r-1,c+1}] == "M" && m[{r-2,c+2}] == "A" && m[{r-3,c+3}] == "S"
defp unquote(:"xmas→")(m, r, c),
do: m[{r,c}] == "X" && m[{r,c+1}] == "M" && m[{r,c+2}] == "A" && m[{r,c+3}] == "S"
defp unquote(:"xmas↘")(m, r, c),
do: m[{r,c}] == "X" && m[{r+1,c+1}] == "M" && m[{r+2,c+2}] == "A" && m[{r+3,c+3}] == "S"
defp unquote(:"xmas↓")(m, r, c),
do: m[{r,c}] == "X" && m[{r+1,c}] == "M" && m[{r+2,c}] == "A" && m[{r+3,c}] == "S"
defp unquote(:"xmas↙")(m, r, c),
do: m[{r,c}] == "X" && m[{r+1,c-1}] == "M" && m[{r+2,c-2}] == "A" && m[{r+3,c-3}] == "S"
defp unquote(:"xmas←")(m, r, c),
do: m[{r,c}] == "X" && m[{r,c-1}] == "M" && m[{r,c-2}] == "A" && m[{r,c-3}] == "S"
defp unquote(:"xmas↖")(m, r, c),
do: m[{r,c}] == "X" && m[{r-1,c-1}] == "M" && m[{r-2,c-2}] == "A" && m[{r-3,c-3}] == "S"
def b2i(true), do: 1
def b2i(false), do: 0
end
map = File.stream!("../day04.txt")
|> Stream.with_index()
|> Enum.reduce(%{}, fn {line, row}, map ->
line
|> String.trim_trailing()
|> String.codepoints()
|> Enum.with_index()
|> Enum.reduce(map, fn {c, col}, map -> Map.put(map, {row, col}, c) end)
end)
# part 1
Enum.reduce(map, 0, fn {{r,c},_char}, n -> n+Part1.xmas(map, r, c) end)
|> IO.inspect(label: "part 1")
defmodule Part2 do
@spec xmas(map(), non_neg_integer(), non_neg_integer()) :: boolean()
def xmas(m, r, c) do
unquote(:"xmas↗↙")(m, r, c) && unquote(:"xmas↖↘")(m, r, c)
end
defp unquote(:"xmas↗↙")(m, r, c),
do: m[{r,c}] == "A" && ((m[{r+1,c-1}] == "M" && m[{r-1,c+1}] == "S") || (m[{r+1,c-1}] == "S" && m[{r-1,c+1}] == "M"))
defp unquote(:"xmas↖↘")(m, r, c),
do: m[{r,c}] == "A" && ((m[{r+1,c+1}] == "M" && m[{r-1,c-1}] == "S") || (m[{r+1,c+1}] == "S" && m[{r-1,c-1}] == "M"))
end
# part 2
Enum.reduce(map, 0, fn {{r,c},_char}, n -> n+Part1.b2i(Part2.xmas(map, r, c)) end)
|> IO.inspect(label: "part 2")
2
Popular in Challenges
This topic is about Day 9 of the Advent of Code 2020 .
Thanks to @egze, we have a private leaderboard:
https://adventofcode.com/2020/le...
New
Took me a minute to remember my binary math :smile: :grimacing:…
import Bitwise
__DIR__
|> Path.join("puzzle.txt")
|> File.stream...
New
Everything went smoothly today.
Nothing to change to solve part 2 because I already used memoization for part 1 (it looked like an AoC e...
New
This topic is about Day 16 of the Advent of Code 2021.
We have a private leaderboard (shared with users of Erlang Forums):
https://adve...
New
New
Anyone else think the prompt for this challenge is contradictory?
The rules for comparing packets include
If both values are lists, c...
New
Monkeys fitted squarely as GenServers in my head. My initial problem was using cast instead of call; I imagine impolite monkeys slinging...
New
This topic is about Day 16 of the Advent of Code 2020 .
Thanks to @egze, we have a private leaderboard:
https://adventofcode.com/2020/l...
New
Note: This topic is to talk about Day 4 of the Advent of Code 2019.
There is a private leaderboard for elixirforum members. You can join...
New
Don’t know why the regex ~r/[\W && [^\.]]/x does not work in Elixir. It works pretty well in Ruby.
Anyway, here is my solution:
New
Other popular topics
can someone please explain to me how Enum.reduce works with maps
New
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this:
...
New
As a follow up to my earlier question:
I have the code compiling and running but not getting a successful login from the rest server. ...
New
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
What is most correct way to open, read and parse JSON file with poison?
For example if we have example.json file in root of some projec...
New
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
Hi guys, i’m new in the Elixir world, and i have to say, that i love it!
i’m having some problem to understand anonymous functions with ...
New
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
Hi everyone,
One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
by Lance Halvorsen
Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
New







