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

Advent of Code 2015 Day 18 Part 1

2015_day18_part1.livemd

Advent of Code 2015 Day 18 Part 1

Mix.install([
  {:kino_aoc, "~> 0.1"},
  {:nx, "~> 0.9.2"}
])

Get Inputs

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2015", "18", System.fetch_env!("LB_SESSION"))

My answer

lights =
  """
  .#.#.#
  ...##.
  #....#
  ..#...
  #.#..#
  ####..
  """
  |> String.trim()
  |> String.split("\n")
  |> Enum.map(fn row ->
    row
    |> String.codepoints()
    |> Enum.map(fn light -> if light == "#", do: 1, else: 0 end)
  end)
  |> Nx.tensor()
pad_tensor = Nx.pad(lights, 0, [{1, 1, 0}, {1, 1, 0}])
around_on =
  pad_tensor
  |> Nx.window_sum({3, 3})
  |> Nx.subtract(lights)
current_on_next_on =
  Nx.multiply(
    lights,
    Nx.multiply(Nx.greater_equal(around_on, 2), Nx.less_equal(around_on, 3))
  )
current_off_next_on =
  Nx.multiply(
    Nx.equal(lights, 0),
    Nx.equal(around_on, 3)
  )
next_on = Nx.add(current_on_next_on, current_off_next_on)
lights =
  puzzle_input
  |> String.split("\n")
  |> Enum.map(fn row ->
    row
    |> String.codepoints()
    |> Enum.map(fn light -> if light == "#", do: 1, else: 0 end)
  end)
  |> Nx.tensor()
1..100
|> Enum.reduce(lights, fn _, acc_lights ->
  around_on =
    acc_lights
    |> Nx.pad(0, [{1, 1, 0}, {1, 1, 0}])
    |> Nx.window_sum({3, 3})
    |> Nx.subtract(acc_lights)

  current_on_next_on =
    Nx.multiply(
      acc_lights,
      Nx.multiply(Nx.greater_equal(around_on, 2), Nx.less_equal(around_on, 3))
    )

  current_off_next_on =
    Nx.multiply(
      Nx.equal(acc_lights, 0),
      Nx.equal(around_on, 3)
    )

  Nx.add(current_on_next_on, current_off_next_on)
end)
|> Nx.sum()