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

Day 07

2024/day_07.livemd

Day 07

Mix.install([:kino_aoc])

Kino.configure(inspect: [charlists: :as_lists])

Input

{:ok, puzzle_input} =
  KinoAOC.download_puzzle("2024", "7", System.fetch_env!("LB_ADVENT_OF_CODE_SESSION"))
parsed =
  puzzle_input
  |> String.split("\n")
  |> Enum.map(fn x -> 
    [total, nums] = String.split(x, ":")
    nums = String.split(nums, " ", trim: true) |> Enum.map(&String.to_integer/1)
    {String.to_integer(total), nums}
  end)

Part 1

defmodule Part1 do
  def create_op_combos(len) do 
    Enum.reduce(1..(len - 1), [[]], fn _, acc -> 
      for combination <- acc, operator <- ["+", "*"] do
        combination ++ [operator]
      end  
    end)
  end
end

Enum.filter(parsed, fn {total, [head | tail] = ints} -> 
  combos = ints
  |> length()
  |> Part1.create_op_combos()

  Enum.any?(combos, fn combo -> 
    total === elem(Enum.reduce(tail, {head, combo}, fn num, {total, [op | rest]} -> 
      case op do
        "+" -> {total + num, rest}
        "*" -> {total * num, rest}
      end  
    end), 0)
  end)
end)
|> Enum.map(&amp;elem(&amp;1, 0))
|> Enum.sum()

Part 2

defmodule Part2 do
  def create_op_combos(len) do 
    Enum.reduce(1..(len - 1), [[]], fn _, acc -> 
      for combination <- acc, operator <- ["+", "*", "||"] do
        combination ++ [operator]
      end  
    end)
  end
end

Task.async_stream(parsed, fn {total, [head | tail] = ints} -> 
  combos = ints
  |> length()
  |> Part2.create_op_combos()

  if Enum.any?(combos, fn combo -> 
    total === elem(Enum.reduce(tail, {head, combo}, fn num, {total, [op | rest]} -> 
      case op do
        "+" -> {total + num, rest}
        "*" -> {total * num, rest}
        "||" -> {String.to_integer("#{total}#{num}"), rest}
      end  
    end), 0)
  end), do: total, else: 0
end, ordered: false, timeout: :infinity)
|> Enum.map(&amp;elem(&amp;1, 1))
|> Enum.sum()