Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Day 18: Like a GIF For Your Yard

day_18_like_a_gif_for_your_yard.livemd

Day 18: Like a GIF For Your Yard

Section

defmodule P1 do
  def parse(str) do
    str
    |> String.split("\n", trim: true)
    |> Enum.map(&String.graphemes/1)
    |> Enum.map(
      &Enum.map(&1, fn
        "." -> false
        "#" -> true
      end)
    )
  end

  def update(grid) do
    grid
    |> Enum.with_index()
    |> Enum.map(fn {row, i} ->
      row
      |> Enum.with_index()
      |> Enum.map(fn {cell, j} ->
        on_neighbors = count_on_neighbors(grid, i, j)

        case cell do
          true -> on_neighbors in 2..3
          false -> on_neighbors == 3
        end
      end)
    end)
  end

  def update_n_times(grid, 0), do: grid

  def update_n_times(grid, n) when n > 0 do
    grid
    |> update()
    |> update_n_times(n - 1)
  end

  def count_on_neighbors(grid, x, y) do
    for i <- max(x - 1, 0)..min(x + 1, length(grid) - 1),
        j <- max(y - 1, 0)..min(y + 1, length(hd(grid)) - 1),
        {i, j} != {x, y},
        reduce: 0 do
      acc -> acc + if Enum.at(grid, i) |> Enum.at(j), do: 1, else: 0
    end
  end

  def to_string(grid) do
    grid
    |> Enum.map(fn row ->
      row
      |> Enum.map(fn cell ->
        if cell, do: "#", else: "."
      end)
      |> Enum.join("")
    end)
    |> Enum.join("\n")
    |> IO.puts()
  end

  def count(grid) do
    grid
    |> Enum.flat_map(&amp; &amp;1)
    |> Enum.count(&amp; &amp;1)
  end

  def set_corners_true(grid) do
    grid
    |> List.update_at(0, fn row ->
      List.update_at(List.update_at(row, 0, fn _ -> true end), -1, fn _ -> true end)
    end)
    |> List.update_at(-1, fn row ->
      List.update_at(List.update_at(row, 0, fn _ -> true end), -1, fn _ -> true end)
    end)
  end

  def update_n_times2(grid, 0), do: grid

  def update_n_times2(grid, n) when n > 0 do
    grid
    |> update()
    |> set_corners_true()
    |> update_n_times2(n - 1)
  end
end

"/Users/eli/Desktop/input.txt"
|> File.read!()
|> P1.parse()
|> P1.update_n_times(100)
|> P1.count()
1061
"/Users/eli/Desktop/input.txt"
|> File.read!()
|> P1.parse()
|> P1.update_n_times2(100)
|> P1.count()
1006