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
1d6fdd25a8
commit
11d5af98db
1 changed files with 59 additions and 51 deletions
|
|
@ -62,7 +62,7 @@ defmodule AdventCode2024.Solutions.Day04 do
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
@doc """
|
||||
|
|
@ -85,68 +85,76 @@ defmodule AdventCode2024.Solutions.Day04 do
|
|||
def solve_part2(_input_file) do
|
||||
end
|
||||
|
||||
def count_x_mas(grid) when is_list(grid) do
|
||||
# Convert string rows to character grid
|
||||
char_grid = Enum.map(grid, &String.graphemes/1)
|
||||
rows = length(char_grid)
|
||||
cols = length(Enum.at(char_grid, 0))
|
||||
def count_x_mas(grid) do
|
||||
processed_grid = Enum.map(grid, &String.graphemes/1)
|
||||
|
||||
# Check each possible center position
|
||||
for row <- 1..(rows - 2),
|
||||
col <- 1..(cols - 2),
|
||||
reduce: 0 do
|
||||
acc ->
|
||||
if is_x_mas_pattern?(char_grid, {row, col}) do
|
||||
acc + 1
|
||||
processed_grid
|
||||
|> Enum.with_index()
|
||||
|> Enum.reduce(0, fn {row, row_idx}, acc ->
|
||||
row
|
||||
|> Enum.with_index()
|
||||
|> Enum.reduce(acc, fn {cell, col_idx}, acc_inner ->
|
||||
if cell == "A" do # Start from the center A
|
||||
acc_inner + check_x_patterns(processed_grid, {row_idx, col_idx})
|
||||
else
|
||||
acc
|
||||
acc_inner
|
||||
end
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
defp is_x_mas_pattern?(grid, {row, col}) do
|
||||
# Get the center character first
|
||||
center = get_char(grid, row, col)
|
||||
if center != "A", do: false,
|
||||
else: check_diagonals(grid, row, col)
|
||||
end
|
||||
|
||||
defp check_diagonals(grid, row, col) do
|
||||
# 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
|
||||
defp check_x_patterns(grid, {row, col}) do
|
||||
# Check both 1-step and 2-step patterns
|
||||
[1, 2]
|
||||
|> Enum.reduce(0, fn step, acc ->
|
||||
if check_x_pattern(grid, {row, col}, step) do
|
||||
acc + 1
|
||||
else
|
||||
acc
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp get_diagonal_chars(grid, row, col, {dr, dc}) do
|
||||
[
|
||||
get_char(grid, row - dr, col - dc),
|
||||
get_char(grid, row, col),
|
||||
get_char(grid, row + dr, col + dc)
|
||||
]
|
||||
defp check_x_pattern(grid, {row, col}, step) do
|
||||
# Check if we can form an X pattern with MAS on both diagonals
|
||||
check_diagonal(grid, {row, col}, {-step, -step}, {step, step}) and # top-left to bottom-right
|
||||
check_diagonal(grid, {row, col}, {-step, step}, {step, -step}) # top-right to bottom-left
|
||||
end
|
||||
|
||||
defp get_char(grid, row, col) do
|
||||
if within_bounds?(grid, row, col) do
|
||||
Enum.at(Enum.at(grid, row), col)
|
||||
end
|
||||
defp check_diagonal(grid, {center_row, center_col}, {top_dr, top_dc}, {bottom_dr, bottom_dc}) do
|
||||
# Check top part and bottom part
|
||||
top_row = center_row + top_dr
|
||||
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
|
||||
|
||||
defp is_mas?(first, last) do
|
||||
first == "M" and last == "S"
|
||||
@doc """
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue