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

AoC 2023 - Day 4

2023/day04.livemd

AoC 2023 - Day 4

Mix.install([:kino])

Setup

input = Kino.Input.textarea("enter your input")

Common

defmodule AoC2023.Day4 do
end

Part 1

input
|> Kino.Input.read()
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
  regex = ~r/Card\s*(\d*):\s(.*)\s\|\s(.*)$/
  [[_, id, winners_num_str, number_str]] = Regex.scan(regex, line)

  winners_num =
    winners_num_str
    |> String.split(" ", trim: true)
    |> Enum.map(fn num ->
      {number, ""} = Integer.parse(num)
      number
    end)

  numbers =
    number_str
    |> String.split(" ", trim: true)
    |> Enum.map(fn num ->
      {number, ""} = Integer.parse(num)
      number
    end)

  count =
    winners_num
    |> Enum.reduce(0, fn num, acc ->
      case Enum.member?(numbers, num) do
        true ->
          case acc == 0 do
            true -> 1
            _ -> acc * 2
          end

        _ ->
          acc
      end
    end)

  {id, count}
end)
|> Enum.map(fn {_, value} ->
  value
end)
|> Enum.sum()

Part 2

list =
  input
  |> Kino.Input.read()
  |> String.split("\n", trim: true)
  |> Enum.map(fn line ->
    regex = ~r/Card\s*(\d*):\s(.*)\s\|\s(.*)$/
    [[_, _id, winners_num_str, number_str]] = Regex.scan(regex, line)

    winners_num =
      winners_num_str
      |> String.split(" ", trim: true)
      |> Enum.map(fn num ->
        {number, ""} = Integer.parse(num)
        number
      end)

    numbers =
      number_str
      |> String.split(" ", trim: true)
      |> Enum.map(fn num ->
        {number, ""} = Integer.parse(num)
        number
      end)

    count =
      winners_num
      |> Enum.reduce(0, fn num, acc ->
        case Enum.member?(numbers, num) do
          true -> acc + 1
          _ -> acc
        end
      end)

    count
  end)

list_length = length(list)

cards_with_score =
  list
  |> Enum.with_index(1)
  |> Map.new(fn {won, i} -> {i, won} end)

counts = cards_with_score |> Map.new(fn {i, _} -> {i, 1} end)

final_counts =
  for i <- 1..map_size(cards_with_score), reduce: counts do
    counts ->
      won = cards_with_score[i]

      for j <- (i + 1)..(i + won)//1, j <= map_size(counts), reduce: counts do
        counts -> %{counts | j => counts[j] + counts[i]}
      end
  end

final_counts
|> Map.values()
|> Enum.sum()