AOC 2023 - Day 06
Mix.install([
{:kino_aoc, "~> 0.1"}
])
AOC Helper
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2023", "6", System.fetch_env!("LB_AOC_SESSION"))
Part 1
Code
defmodule PartOne do
def parse_rounds(input) do
[
"Time:" <> times,
"Distance:" <> distances
] = String.split(input, "\n")
times =
times
|> String.trim()
|> String.split(" ")
|> Enum.reject(&(&1 == ""))
|> Enum.map(&String.to_integer/1)
distances =
distances
|> String.trim()
|> String.split(" ")
|> Enum.reject(&(&1 == ""))
|> Enum.map(&String.to_integer/1)
times
|> Enum.with_index()
|> Enum.map(fn {time, index} ->
{time, Enum.at(distances, index)}
end)
end
def test_round({time, distance}) do
0..time
|> Enum.to_list()
|> Enum.filter(fn hold_ms ->
speed_mmps = hold_ms
remaining_ms = time - hold_ms
speed_mmps * remaining_ms > distance
end)
|> Enum.count()
end
def solve(input) do
IO.puts("--- Part One ---")
IO.puts("Result: #{run(input)}")
end
def run(input) do
input
|> parse_rounds()
|> Enum.map(&test_round/1)
|> Enum.reduce(1, &(&1 * &2))
end
end
Test
ExUnit.start(autorun: false)
defmodule PartOneTest do
use ExUnit.Case, async: true
import PartOne
@input "Time: 7 15 30
Distance: 9 40 200"
@expected 288
test "part one" do
actual = run(@input)
assert actual == @expected
end
end
ExUnit.run()
Solution
PartOne.solve(puzzle_input)
Part 2
Code
defmodule PartTwo do
def parse_round(input) do
[
"Time:" <> times,
"Distance:" <> distances
] = String.split(input, "\n")
time =
times
|> String.trim()
|> String.split(" ")
|> Enum.reject(&(&1 == ""))
|> Enum.join()
|> String.to_integer()
distance =
distances
|> String.trim()
|> String.split(" ")
|> Enum.reject(&(&1 == ""))
|> Enum.join()
|> String.to_integer()
{time, distance}
end
def test_round({time, distance}) do
0..time
|> Enum.to_list()
|> Enum.filter(fn hold_ms ->
speed_mmps = hold_ms
remaining_ms = time - hold_ms
speed_mmps * remaining_ms > distance
end)
|> Enum.count()
end
def solve(input) do
IO.puts("--- Part Two ---")
IO.puts("Result: #{run(input)}")
end
def run(input) do
input
|> parse_round()
|> test_round()
end
end
Test
ExUnit.start(autorun: false)
defmodule PartTwoTest do
use ExUnit.Case, async: true
import PartTwo
@input "Time: 7 15 30
Distance: 9 40 200"
@expected 71503
test "part two" do
actual = run(@input)
assert actual == @expected
end
end
ExUnit.run()
Solution
PartTwo.solve(puzzle_input)