Powered by AppSignal & Oban Pro

Advent of Code 2023 Day 14 Part 1

2023_day14_part1.livemd

Advent of Code 2023 Day 14 Part 1

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

Get Inputs

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

My answer

map =
  """
  O....#....
  O.OO#....#
  .....##...
  OO.#O....O
  .O.....O#.
  O.#..O.#.#
  ..O..#O..O
  .......O..
  #....###..
  #OO..#....
  """
  |> String.trim()
  |> String.split("\n")
  |> Enum.map(fn row ->
    String.codepoints(row)
  end)
turned_map =
  map
  |> Enum.zip()
  |> Enum.map(fn col ->
    Tuple.to_list(col)
  end)
  |> Enum.reverse()
defmodule Rock do
  def turn(map) do
    map
    |> Enum.zip()
    |> Enum.map(fn col ->
      Tuple.to_list(col)
    end)
    |> Enum.reverse()
  end

  def slide(map) do
    Enum.map(map, fn row ->
      slide(row, length(row) - 1)
    end)
  end
  
  def slide(row, 0), do: row
  def slide(row, current_index) do
    current_block = Enum.at(row, current_index)
    next_block = Enum.at(row, current_index - 1)

    case {current_block, next_block} do
      {"O", "."} ->
        row
        |> List.update_at(current_index, fn _ -> "." end)
        |> List.update_at(current_index - 1, fn _ -> "O" end)
        |> slide(length(row) - 1)
      _ ->
        slide(row, current_index - 1)
    end
  end

  def sum_load(map) do
    map
    |> Enum.map(fn row ->
      row
      |> Enum.reverse()
      |> Enum.with_index(1)
      |> Enum.map(fn {mark, index} ->
        case mark do
          "O" -> index
          _ -> 0
        end
      end)
      |> Enum.sum()
    end)
    |> Enum.sum()
  end
end
map
|> Rock.turn()
|> Rock.slide()
map
|> Rock.turn()
|> Rock.slide()
|> Rock.sum_load()
map =
  puzzle_input
  |> String.split("\n")
  |> Enum.map(fn row ->
    String.codepoints(row)
  end)
map
|> Rock.turn()
|> Rock.slide()
|> Rock.sum_load()