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

AoC 2023 - Day 06

2023/lang-elixir/06.livemd

AoC 2023 - Day 06

Mix.install([
  {:kino, "~> 0.11.3"}
])

Section

input_e1 =
  "day06-e1.txt"
  |> Kino.FS.file_path()
  |> File.read!()
  |> String.trim()

input =
  "day06.txt"
  |> Kino.FS.file_path()
  |> File.read!()
  |> String.trim()

[input_e1, input]
defmodule Solution do
  def part_1(input) do
    input
    |> parse()
    |> Enum.map(fn {time, dist} ->
      calc(time, dist)
    end)
    |> Enum.product()
  end

  def part_1_math(input) do
    input
    |> parse()
    |> Enum.map(fn {time, dist} ->
      math(time, dist)
    end)
    |> Enum.product()
  end

  def part_2(input) do
    ["Time:" <> times, "Distance:" <> distances] = String.split(input, "\n")

    time = times |> String.replace(" ", "") |> String.to_integer()
    dist = distances |> String.replace(" ", "") |> String.to_integer()

    calc(time, dist)
  end

  def part_2_math(input) do
    ["Time:" <> times, "Distance:" <> distances] = String.split(input, "\n")

    time = times |> String.replace(" ", "") |> String.to_integer()
    dist = distances |> String.replace(" ", "") |> String.to_integer()

    math(time, dist)
  end

  def calc(time, dist) do
    even = if rem(time, 2) == 0, do: 1, else: 0

    (time - 1)..div(time, 2)
    |> Enum.map(&amp;(&amp;1 * (time - &amp;1)))
    |> MapSet.new()
    |> MapSet.filter(&amp;(&amp;1 > dist))
    |> MapSet.size()
    |> Kernel.*(2)
    |> Kernel.-(even)
  end

  def math(time, dist) do
    sqrt = :math.sqrt(time * time - 4 * dist)
    x1 = (time - sqrt) / 2
    x2 = (time + sqrt) / 2

    abs(floor(x2) - ceil(x1)) + 1
  end

  defp parse(input) do
    ["Time:" <> times, "Distance:" <> distances] = String.split(input, "\n")

    Enum.zip(
      times |> String.split(" ", trim: true) |> Enum.map(&amp;String.to_integer/1),
      distances |> String.split(" ", trim: true) |> Enum.map(&amp;String.to_integer/1)
    )
  end
end
Solution.math(7, 9)
Solution.part_1(input)
Solution.part_1_math(input)
Solution.part_2(input)
Solution.part_2_math(input)
rem(7, 2)