Add 2024 Day 21 WIP - probably give up
This commit is contained in:
parent
0bc03b7157
commit
c334a98583
1 changed files with 133 additions and 0 deletions
133
2024/day21_wip.exs
Executable file
133
2024/day21_wip.exs
Executable file
|
@ -0,0 +1,133 @@
|
|||
#!/usr/bin/env elixir
|
||||
defmodule Day21 do
|
||||
@numpad %{
|
||||
"7" => {0, 0},
|
||||
"8" => {1, 0},
|
||||
"9" => {2, 0},
|
||||
"4" => {0, 1},
|
||||
"5" => {1, 1},
|
||||
"6" => {2, 1},
|
||||
"1" => {0, 2},
|
||||
"2" => {1, 2},
|
||||
"3" => {2, 2},
|
||||
"0" => {1, 3},
|
||||
"A" => {2, 3}
|
||||
}
|
||||
|
||||
@keypad %{
|
||||
"^" => {1, 0},
|
||||
"A" => {2, 0},
|
||||
"<" => {0, 1},
|
||||
"v" => {1, 1},
|
||||
">" => {2, 1}
|
||||
}
|
||||
|
||||
def part1(input) do
|
||||
Enum.map(input, &complexity/1)
|
||||
end
|
||||
|
||||
def complexity(code) do
|
||||
length =
|
||||
code
|
||||
|> derive_keys(@numpad)
|
||||
# asdfsadfsdafdfs for the robot, some derived combinations are shorter, why?
|
||||
# Maybe going left non-sequentially is expensive because of round trips to the A buttom
|
||||
# so sequentially is cheaper?
|
||||
# Need to figure out what the situation that causes a longer sequence is
|
||||
|> derive_keys(@keypad)
|
||||
|> derive_keys(@keypad)
|
||||
|> byte_size()
|
||||
|> dbg()
|
||||
|
||||
{numeric, "A"} = Integer.parse(code)
|
||||
dbg(numeric)
|
||||
|
||||
numeric * length
|
||||
end
|
||||
|
||||
def derive_keys(seq, pad) do
|
||||
String.graphemes("A" <> seq)
|
||||
|> Enum.chunk_every(2, 1, :discard)
|
||||
|> Enum.map_join("", fn [a, b] -> keys(a, b, pad) <> "A" end)
|
||||
end
|
||||
|
||||
def numpad, do: @numpad
|
||||
|
||||
def keys(a, b, pad) do
|
||||
{x1, y1} = Map.fetch!(pad, a)
|
||||
{x2, y2} = Map.fetch!(pad, b)
|
||||
dx = x2 - x1
|
||||
dy = y2 - y1
|
||||
|
||||
keys_x = keys_x(dx)
|
||||
keys_y = keys_y(dy)
|
||||
|
||||
# avoid the gap
|
||||
if dx < 0 do
|
||||
keys_y <> keys_x
|
||||
else
|
||||
keys_x <> keys_y
|
||||
end
|
||||
end
|
||||
|
||||
def keys_x(-2), do: "<<"
|
||||
def keys_x(-1), do: "<"
|
||||
def keys_x(0), do: ""
|
||||
def keys_x(1), do: ">"
|
||||
def keys_x(2), do: ">>"
|
||||
|
||||
def keys_y(-3), do: "^^^"
|
||||
def keys_y(-2), do: "^^"
|
||||
def keys_y(-1), do: "^"
|
||||
def keys_y(0), do: ""
|
||||
def keys_y(1), do: "v"
|
||||
def keys_y(2), do: "vv"
|
||||
def keys_y(3), do: "vvv"
|
||||
|
||||
def keypad, do: @keypad
|
||||
|
||||
def part2(_input) do
|
||||
:ok
|
||||
end
|
||||
|
||||
def input do
|
||||
with [input_filename] <- System.argv(),
|
||||
{:ok, input} <- File.read(input_filename) do
|
||||
String.split(input, "\n", trim: true)
|
||||
else
|
||||
_ -> :error
|
||||
end
|
||||
end
|
||||
|
||||
#######################
|
||||
# HERE BE BOILERPLATE #
|
||||
#######################
|
||||
|
||||
def run do
|
||||
case input() do
|
||||
:error -> print_usage()
|
||||
input -> run_parts_with_timer(input)
|
||||
end
|
||||
end
|
||||
|
||||
defp run_parts_with_timer(input) do
|
||||
run_with_timer(1, fn -> part1(input) end)
|
||||
run_with_timer(2, fn -> part2(input) end)
|
||||
end
|
||||
|
||||
defp run_with_timer(part, fun) do
|
||||
{time, result} = :timer.tc(fun)
|
||||
IO.puts("Part #{part} (completed in #{format_time(time)}):\n")
|
||||
IO.puts("#{inspect(result)}\n")
|
||||
end
|
||||
|
||||
defp format_time(μsec) when μsec < 1_000, do: "#{μsec}μs"
|
||||
defp format_time(μsec) when μsec < 1_000_000, do: "#{μsec / 1000}ms"
|
||||
defp format_time(μsec), do: "#{μsec / 1_000_000}s"
|
||||
|
||||
defp print_usage do
|
||||
IO.puts("Usage: elixir day21.exs input_filename")
|
||||
end
|
||||
end
|
||||
|
||||
# Day21.run()
|
Loading…
Reference in a new issue