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

Day 7

day7.livemd

Day 7

Setup

input =
  System.fetch_env!("LB_AOC_DIR")
  |> Path.join("data/day7.txt")
  |> File.read!()

nil
nil

Solve

defmodule Day7 do
  import Kernel, except: [+: 2, *: 2]
  defdelegate left + right, to: Elixir.Kernel
  defdelegate left * right, to: Elixir.Kernel

  defp parse(input) do
    for line <- String.split(input, "\n"), line != "" do
      [left, right] = String.split(line, ":")
      {String.to_integer(left), String.split(right) |> Enum.map(&amp;String.to_integer/1)}
    end
  end

  defp permutations(amount, operators) do
    for _i <- 1..amount,
        reduce: [[]] do
      acc ->
        for item <- operators,
            list <- acc,
            do: list ++ [item]
    end
  end

  defp num_solvable(equations, operators) do
    for {result, operands} <- equations, reduce: 0 do
      sum ->
        perms = permutations(length(operands) - 1, operators)

        if(
          Enum.any?(perms, fn
            perm ->
              [start | operands] = operands

              result ==
                List.foldl(operands, {start, perm}, fn
                  _operand, {acc, []} ->
                    acc

                  operand, {acc, [current | rest]} ->
                    {apply(__MODULE__, current, [acc, operand]), rest}
                end)
                |> elem(0)
          end)
        ) do
          sum + result
        else
          sum
        end
    end
  end

  @doc ~S"""
  iex> Day7.part1("190: 10 19\n3267: 81 40 27\n83: 17 5\n156: 15 6\n7290: 6 8 6 15\n161011: 16 10 13\n192: 17 8 14\n21037: 9 7 18 13\n292: 11 6 16 20\n")
  3749
  """
  def part1(input) do
    equations = parse(input)

    num_solvable(equations, [:*, :+])
  end

  def concat_ints(a, b), do: (Integer.to_string(a) <> Integer.to_string(b)) |> String.to_integer()

  @doc ~S"""
  iex> Day7.part2("190: 10 19\n3267: 81 40 27\n83: 17 5\n156: 15 6\n7290: 6 8 6 15\n161011: 16 10 13\n192: 17 8 14\n21037: 9 7 18 13\n292: 11 6 16 20\n")
  11387
  """
  def part2(input) do
    equations = parse(input)

    num_solvable(equations, [:*, :+, :concat_ints])
  end
end
{:module, Day7, <<70, 79, 82, 49, 0, 0, 19, ...>>, {:part2, 1}}