2023 day 6
This commit is contained in:
parent
027ed5aeb6
commit
07125c75ce
1 changed files with 74 additions and 0 deletions
74
lib/2023_day6.ex
Normal file
74
lib/2023_day6.ex
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
defmodule Mix.Tasks.Day6 do
|
||||||
|
use Mix.Task
|
||||||
|
|
||||||
|
def parse(input, :part1) do
|
||||||
|
input
|
||||||
|
|> Enum.map(fn s ->
|
||||||
|
String.split(s, " ")
|
||||||
|
|> Enum.reject(fn s -> s === "" or s === "Time:" or s === "Distance:" end)
|
||||||
|
end)
|
||||||
|
|> Enum.map(fn i ->
|
||||||
|
i
|
||||||
|
|> Enum.map(fn s ->
|
||||||
|
s |> String.trim() |> String.to_integer()
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def parse(input, :part2) do
|
||||||
|
input
|
||||||
|
|> Enum.map(fn s ->
|
||||||
|
String.split(s, " ")
|
||||||
|
|> Enum.reject(fn s -> s === "" or s === "Time:" or s === "Distance:" end)
|
||||||
|
end)
|
||||||
|
|> Enum.map(fn u ->
|
||||||
|
u
|
||||||
|
|> Enum.join("")
|
||||||
|
|> String.trim()
|
||||||
|
|> String.to_integer()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def distance_traveled_in_n_seconds(seconds, duration) do
|
||||||
|
seconds * (duration - seconds)
|
||||||
|
end
|
||||||
|
|
||||||
|
def polynomial_roots(a, b, c) do
|
||||||
|
[
|
||||||
|
(-b + :math.sqrt(b ** 2 - 4 * a * c)) / (2 * a),
|
||||||
|
(-b - :math.sqrt(b ** 2 - 4 * a * c)) / (2 * a)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def solve([time, distance], p) when p === :part2 do
|
||||||
|
# number of negative integer solutions to the polynomial
|
||||||
|
# x^2 - tx + d < 0
|
||||||
|
# where x is time spent holding button, t is the duration of the race (seconds), and d is the distance to beat
|
||||||
|
roots = polynomial_roots(1, -time, distance)
|
||||||
|
max = roots |> Enum.max()
|
||||||
|
min = roots |> Enum.min()
|
||||||
|
floor(max) - floor(min)
|
||||||
|
end
|
||||||
|
|
||||||
|
def solve([times, distances], p) when p === :part1 do
|
||||||
|
for {time, index} <- times |> Enum.with_index(),
|
||||||
|
seconds <- 1..(time - 1),
|
||||||
|
distance_traveled_in_n_seconds(seconds, time) > distances |> Enum.at(index),
|
||||||
|
reduce: %{} do
|
||||||
|
acc ->
|
||||||
|
acc |> Map.update(time, [seconds], fn u -> [seconds | u] end)
|
||||||
|
end
|
||||||
|
|> Map.values()
|
||||||
|
|> Enum.reduce(
|
||||||
|
1,
|
||||||
|
fn a, acc ->
|
||||||
|
acc * (a |> Enum.count())
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def run(args) do
|
||||||
|
part = if args |> Enum.at(0) == "1", do: :part1, else: :part2
|
||||||
|
IO.stream() |> parse(part) |> solve(part) |> IO.puts()
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Reference in a new issue