Day 3: Lobby
Mix.install([{:kino, "~> 0.11.3"}])
Day 3
sample_input = Kino.Input.textarea("Paste Sample Input")
real_input = Kino.Input.textarea("Paste Real Input")
defmodule Part1 do
def solve(input) do
input
|> Kino.Input.read()
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
line |> String.graphemes() |> Enum.map(&String.to_integer/1) |> max_joltage()
end)
|> Enum.sum()
end
def max_joltage(bank, best_cells \\ {0, 0, 0})
def max_joltage([next_cell | rest], {prev_joltage, cell1, cell2} = current) do
best_first_cell = max(cell1, cell2)
potential_joltage = joltage({best_first_cell, next_cell})
if potential_joltage > prev_joltage do
max_joltage(rest, {potential_joltage, best_first_cell, next_cell})
else
max_joltage(rest, current)
end
end
def max_joltage([], {joltage, _, _}), do: joltage
def joltage({cell1, cell2}), do: cell1 * 10 + cell2
end
Part1.solve(sample_input)
Part1.solve(real_input)
defmodule Part2 do
@active_cell_count 12
def solve(input) do
input
|> Kino.Input.read()
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
line |> String.graphemes() |> Enum.map(&String.to_integer/1) |> max_joltage()
end)
|> Enum.sum()
end
#
# Loop through the available cells, keeping track of our current best collection
# of enabled cells, and deciding at each stage how / whether to incorporate the
# next battery for max joltage
#
defp max_joltage(bank, best_cells \\ [])
defp max_joltage([next_cell | rest], best_cells) when length(best_cells) < @active_cell_count,
do: max_joltage(rest, best_cells ++ [next_cell])
defp max_joltage([next_cell | rest], best_cells) do
all_cells = best_cells ++ [next_cell]
max_joltage(rest, maximize_joltage(all_cells))
end
defp max_joltage([], best_cells), do: Integer.undigits(best_cells)
#
# Given a list of possibly enabled cells with one more than we're allowed
# discover the best possible combination of enabled cells at this stage
#
# The idea is that, if at any point in the list we have an increasing
# jump from one enabled battery to the next, we can increase our total joltage
# by swapping the first (lower) battery out and shifting the rest to the left
#
defp maximize_joltage(all_cells, accum \\ [])
defp maximize_joltage([first, second | rest], accum) do
if second > first do
accum ++ [second | rest]
else
maximize_joltage([second | rest], accum ++ [first])
end
end
defp maximize_joltage([_last], accum), do: accum
end
Part2.solve(sample_input)
Part2.solve(real_input)