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

Day2

2023/elixir/day2.livemd

Day2

Mix.install([
  {:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
])

Get Input

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

Task1

defmodule Day2 do
  @max %{red: 12, green: 13, blue: 14}

  def parse(row) do
    ["Game " <> num, games] = String.split(row, ":", trim: true)

    gg =
      games
      |> String.split(";", trim: true)
      |> Enum.map(fn round ->
        round
        |> String.split(",", trim: true)
        |> Enum.map(fn game ->
          [num, color] = String.split(game)
          {String.to_atom(color), String.to_integer(num)}
        end)
        |> Map.new()
      end)

    {String.to_integer(num), gg}
  end

  def task1({num, games}) do
    (Enum.all?(games, &amp;valid?/1) &amp;&amp; num) || 0
  end

  def valid?(game) do
    Access.get(game, :red, 0) <= @max[:red] &amp;&amp;
      Access.get(game, :green, 0) <= @max[:green] &amp;&amp;
      Access.get(game, :blue, 0) <= @max[:blue]
  end

  def task2({_num, games}) do
    games
    |> Enum.reduce(%{red: 0, green: 0, blue: 0}, fn g, acc ->
      rm = max(Access.get(g, :red, 0), acc[:red])
      gm = max(Access.get(g, :green, 0), acc[:green])
      bm = max(Access.get(g, :blue, 0), acc[:blue])

      %{red: rm, green: gm, blue: bm}
    end)
    |> Map.values()
    |> Enum.reduce(&amp;Kernel.*/2)
  end
end

data
|> String.split("\n", trim: true)
|> Enum.map(&amp;Day2.parse/1)
|> Enum.map(&amp;Day2.task1/1)
|> Enum.sum()

Task2

dt = """
Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green
"""

data
|> String.split("\n", trim: true)
|> Enum.map(&amp;Day2.parse/1)
|> Enum.map(&amp;Day2.task2/1)
|> Enum.sum()