Powered by AppSignal & Oban Pro

AOC 2023 - Day 2

2023/day2.livemd

AOC 2023 - Day 2

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

Input

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

Code

defmodule Day2Part1 do
  def parse_cube_data(cube_data) do
    [number, color] = String.split(cube_data)
    {color, String.to_integer(number)}
  end

  def parse_game(line) do
    ["Game " <> game_id, rounds_string] = String.split(line, ": ")

    game_data =
      rounds_string
      |> String.split("; ")
      |> Enum.map(fn round ->
        # Parse the number of cubes seen in each round
        String.split(round, ",")
        |> Enum.map(fn cube_data -> parse_cube_data(cube_data) end)
        |> Enum.reduce(%{"red" => 0, "green" => 0, "blue" => 0}, fn {color, number}, acc ->
          if acc[color] < number, do: Map.put(acc, color, number), else: acc
        end)
      end)
      |> Enum.reduce(%{"red" => 0, "green" => 0, "blue" => 0}, fn round_data, acc ->
        # Store the highest seen amount of cubes for each color in a game
        largest_red = Enum.max([round_data["red"], acc["red"]])
        largest_green = Enum.max([round_data["green"], acc["green"]])
        largest_blue = Enum.max([round_data["blue"], acc["blue"]])

        %{"red" => largest_red, "green" => largest_green, "blue" => largest_blue}
      end)

    Map.put(game_data, "id", String.to_integer(game_id))
  end
end

Part 1 - Solution

puzzle_input
|> String.split("\n")
|> Enum.filter(fn line -> String.length(line) > 0 end)
|> Enum.map(&amp;Day2Part1.parse_game/1)
|> Enum.filter(fn game_data ->
  # Max 12 red cubes, 13 green cubes, and 14 blue cubes.
  game_data["red"] <= 12 and game_data["green"] <= 13 and game_data["blue"] <= 14
end)
|> Enum.reduce(0, fn game_data, acc ->
  game_data["id"] + acc
end)

Part 2 - Solution

puzzle_input
|> String.split("\n")
|> Enum.filter(fn line -> String.length(line) > 0 end)
|> Enum.map(&amp;Day2Part1.parse_game/1)
|> Enum.reduce(0, fn game_data, acc ->
  game_data["red"] * game_data["green"] * game_data["blue"] + acc
end)