mirror of
https://github.com/rjNemo/ai_advent_code_2024
synced 2026-06-06 02:26:44 +00:00
fix: test are passing for part 2
This commit is contained in:
parent
6132f3d3d2
commit
143b8c0742
1 changed files with 59 additions and 51 deletions
|
|
@ -62,7 +62,7 @@ defmodule AdventCode2024.Solutions.Day04 do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp within_bounds?(grid, row, col) do
|
defp within_bounds?(grid, row, col) do
|
||||||
row >= 0 && row < length(grid) && col >= 0 && col < length(Enum.at(grid, 0))
|
row >= 0 and row < length(grid) and col >= 0 and col < length(Enum.at(grid, 0))
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
@ -85,68 +85,76 @@ defmodule AdventCode2024.Solutions.Day04 do
|
||||||
def solve_part2(_input_file) do
|
def solve_part2(_input_file) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def count_x_mas(grid) when is_list(grid) do
|
def count_x_mas(grid) do
|
||||||
# Convert string rows to character grid
|
processed_grid = Enum.map(grid, &String.graphemes/1)
|
||||||
char_grid = Enum.map(grid, &String.graphemes/1)
|
|
||||||
rows = length(char_grid)
|
|
||||||
cols = length(Enum.at(char_grid, 0))
|
|
||||||
|
|
||||||
# Check each possible center position
|
processed_grid
|
||||||
for row <- 1..(rows - 2),
|
|> Enum.with_index()
|
||||||
col <- 1..(cols - 2),
|
|> Enum.reduce(0, fn {row, row_idx}, acc ->
|
||||||
reduce: 0 do
|
row
|
||||||
acc ->
|
|> Enum.with_index()
|
||||||
if is_x_mas_pattern?(char_grid, {row, col}) do
|
|> Enum.reduce(acc, fn {cell, col_idx}, acc_inner ->
|
||||||
acc + 1
|
if cell == "A" do # Start from the center A
|
||||||
|
acc_inner + check_x_patterns(processed_grid, {row_idx, col_idx})
|
||||||
else
|
else
|
||||||
acc
|
acc_inner
|
||||||
end
|
end
|
||||||
end
|
end)
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp is_x_mas_pattern?(grid, {row, col}) do
|
defp check_x_patterns(grid, {row, col}) do
|
||||||
# Get the center character first
|
# Check both 1-step and 2-step patterns
|
||||||
center = get_char(grid, row, col)
|
[1, 2]
|
||||||
if center != "A", do: false,
|
|> Enum.reduce(0, fn step, acc ->
|
||||||
else: check_diagonals(grid, row, col)
|
if check_x_pattern(grid, {row, col}, step) do
|
||||||
end
|
acc + 1
|
||||||
|
else
|
||||||
defp check_diagonals(grid, row, col) do
|
acc
|
||||||
# Define the four diagonal directions from center
|
|
||||||
diagonals = [
|
|
||||||
[{-1, -1}, {1, 1}], # top-left to bottom-right
|
|
||||||
[{-1, 1}, {1, -1}], # top-right to bottom-left
|
|
||||||
]
|
|
||||||
|
|
||||||
# For each diagonal pair, check if either forms a valid MAS pattern
|
|
||||||
Enum.any?(diagonals, fn [d1, d2] ->
|
|
||||||
chars1 = get_diagonal_chars(grid, row, col, d1)
|
|
||||||
chars2 = get_diagonal_chars(grid, row, col, d2)
|
|
||||||
|
|
||||||
case {chars1, chars2} do
|
|
||||||
{[c1, "A", c3], [c4, "A", c6]} when not is_nil(c1) and not is_nil(c3) and not is_nil(c4) and not is_nil(c6) ->
|
|
||||||
(is_mas?(c1, c3) and is_mas?(c4, c6)) or
|
|
||||||
(is_mas?(c3, c1) and is_mas?(c6, c4))
|
|
||||||
_ -> false
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_diagonal_chars(grid, row, col, {dr, dc}) do
|
defp check_x_pattern(grid, {row, col}, step) do
|
||||||
[
|
# Check if we can form an X pattern with MAS on both diagonals
|
||||||
get_char(grid, row - dr, col - dc),
|
check_diagonal(grid, {row, col}, {-step, -step}, {step, step}) and # top-left to bottom-right
|
||||||
get_char(grid, row, col),
|
check_diagonal(grid, {row, col}, {-step, step}, {step, -step}) # top-right to bottom-left
|
||||||
get_char(grid, row + dr, col + dc)
|
|
||||||
]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_char(grid, row, col) do
|
defp check_diagonal(grid, {center_row, center_col}, {top_dr, top_dc}, {bottom_dr, bottom_dc}) do
|
||||||
if within_bounds?(grid, row, col) do
|
# Check top part and bottom part
|
||||||
Enum.at(Enum.at(grid, row), col)
|
top_row = center_row + top_dr
|
||||||
end
|
top_col = center_col + top_dc
|
||||||
|
bottom_row = center_row + bottom_dr
|
||||||
|
bottom_col = center_col + bottom_dc
|
||||||
|
|
||||||
|
within_bounds?(grid, top_row, top_col) and
|
||||||
|
within_bounds?(grid, bottom_row, bottom_col) and
|
||||||
|
(
|
||||||
|
# Check normal orientation (M at top, S at bottom)
|
||||||
|
(Enum.at(Enum.at(grid, top_row), top_col) == "M" and
|
||||||
|
Enum.at(Enum.at(grid, bottom_row), bottom_col) == "S") or
|
||||||
|
# Check upside down orientation (S at top, M at bottom)
|
||||||
|
(Enum.at(Enum.at(grid, top_row), top_col) == "S" and
|
||||||
|
Enum.at(Enum.at(grid, bottom_row), bottom_col) == "M")
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp is_mas?(first, last) do
|
@doc """
|
||||||
first == "M" and last == "S"
|
Reads a grid from a file and counts the occurrences of a word using `count_word/2`.
|
||||||
|
|
||||||
|
## Parameters
|
||||||
|
- file_path: The path to the file containing the grid.
|
||||||
|
- word: The word to be searched for.
|
||||||
|
|
||||||
|
## Returns
|
||||||
|
- The number of times the word is found in the grid.
|
||||||
|
"""
|
||||||
|
def count_word_from_file(file_path, word) do
|
||||||
|
file_path
|
||||||
|
|> File.stream!()
|
||||||
|
|> Enum.map(&String.trim/1)
|
||||||
|
|> Enum.map(&String.graphemes/1)
|
||||||
|
|> count_word_occurrences(word)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue