— Day 1: Secret Entrance —
Mix.install([{:kino_aoc, "~> 0.1"}])
Part 1
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2025", "1", System.fetch_env!("LB_AOC_SESSION_COOKIE"))
{:ok,
"L3\nR49\nR11\nL18\nR41\nL49\nR40\nR38\nR8\nL8\nL14\nL45\nR38\nL46\nR45\nR37\nR24\nL43\nL45\nL44\nL2\nR22\nR8\nR50\nR49\nL25\nL36\nR44\nL23\nL22\nL9\nR17\nL37\nL44\nL32\nL22\nR26\nR32\nR13\nR20\nL23\nR35\nL7\nL35\nL28\nL47\nL6\nL1\nR38\nR17\nR12\nR88\nR92\nL89\nL41\nL76\nL81\nR63\nL92\nL69\nR55\nL42\nR39\nR70\nR64\nL31\nL63\nL37\nL68\nR68\nR62\nL24\nL38\nR9\nL5\nL4\nR9\nR91\nR93\nL34\nR10\nR31\nL2\nL98\nL48\nL2\nL72\nL78\nL93\nR93\nL5\nL38\nL84\nL4\nL69\nR44\nL78\nR34\nR24\nL1\nL37\nL135\nR44\nR639\nR19\nL53\nL617\nR17\nL4\nR4\nR1\nR179\nL80\nL707\nL46\nL29\nR56\nL74\nL17\nL983\nL98\nR98\nL59\nR65\nR94\nR13\nR16\nR79\nR57\nL65\nR2\nL502\nR40\nL63\nL37\nL81\nR41\nL176\nL78\nR531\nR523\nL76\nL124\nR8\nL8\nR37\nL28\nL43\nL58\nR75\nR254\nL737\nR14\nR29\nR59\nR98\nL83\nR85\nL67\nR65\nR23\nL95\nL80\nL43\nR95\nR45\nR55\nR65\nR43\nR57\nL65\nR62\nL62\nL89\nR82\nL93\nL44\nR44\nR82\nR5\nL20\nL67\nL39\nL61\nR248\nL69\nR614\nR76\nL69\nL73\nR73\nR75\nL9\nL66\nL74\nR62\nL50\nL94\nL66\nR96\nL727\nL71\nL371\nL515\nL90\nL946\nR94\nL31\nR83\nR23\nL67\nR44\nR65\nL565\nR56\nL990\nR223\nL489\nR12\nR75\nL56\nR69\nR52\nR21\nL23\nL71\nL12\nR78\nR55\nL25\nL805\nL25\nL725\nL420\nL35\nR49\nL14\nR44\nR5\nR8\nR11\nR32\nR32\nR3\nL69\nR32\nR902\nL1\nR1\nR43\nL62\nR319\nL61\nR52\nL191\nL72\nL95\nR67\nR73\nL91\nR706\nR12\nL56\nL59\nL685\nL83\nR83\nR15\nL60\nL56\nR1\nR46\nL79\nL77\nR10\nR86\nR846\nR568\nL76\nR76\nR45\nR55\nL19\nR67\nR81\nL129\nR54\nL16\nR46\nR81\nL62\nL61\nL942\nR57\nR43\nR6\nL18\nR795\nL786\nR21\nL923\nL405\nL75\nR98\nL32\nL778\nR497\nL86\nR71\nR94\nR56\nL95\nR53\nR9\nL91\nR25\nL536\nR72\nL72\nL88\nL732\nR28\nL8\nR577\nL829\nL76\nR76\nL48\nL22\nL678\nR679\nR21\nL34\nR63\nR88\nR207\nR76\nL59\nR79\nR70\nR1\nL74\nL24\nL190\nL89\nL56\nR42\nR25\nL81\nL93\nR893\nL43\nR64\nL606\nR70\nL17\nL60\nR533\nL21\nL74\nR337\nR72\nL75\nL24\nL85\nL62\nR94\nR753\nL657\nL43\nL119\nL57\nL695\nL29\nL23\nR2\nR483\nL51\nL74\nL637\nR33\nR67\nR68\nL21\nL523\nR576\nL56\nL44\nL73\nL73\nL54\nR54\nR946\nR24\nL24\nL194\nL27\nL72\nR88\nL95\nR64\nL28\nR7\nR32\nL13\nR38\nR48\nR401\nR84\nL89\nR59\nL26\nL55\nR78\nL330\nL295\nL48\nR28\nR56\nR89\nL47\nR32\nR17\nL81\nL21\nR575\nL69\nL6\nR88\nL88\nR227\nL67\nL590\nL15\nR37\nR19\nR999\nL85\nL45\nR546\nR74\nL26\nL74\nR6\nL776\nR70\nL41\nL76\nR66\nL49\nL23\nR399\nR67\nR17\nL95\nL23\nR58\nR748\nL48\nL65\nL35\nR35\nR65\nL30\nL70\nL47\nL953\nL94\nL56\nR268\nR82\nL30\nR21\nL12\nL42\nR543\nL80\nR62\nR18\nL11\nR31\nR21\nL7\nR12\nR10\nR21\nR384\nR59\nL45\nR95\nL250\nL18\nR711\nR7\nR97\nL97\nR4\nL4\nL80\nL66\nL54\nL69\nR545\nR95\nL8\nL63\nR64\nR36\nR29\nL63\nR25\nL5\nL34\nR48\nL65\nL35\nR94\nL29\nL67\nR2\nL79\nR96\nR74\nL91\nL37\nR40\nL3\nR96\nR4\nR349\nR51\nL9\nR99\nR10\nL461\nR65\nR81\nL17\nR37\nR95\nL53\nR53\nL55\nL45\nR93\nL19\nR50\nR14\nR93\nR18\nL949\nR204\nL89\nR70\nL503\nR18\nR37\nL37\nL46\nL94\nR8\nL45\nR96\nR74\nL496\nL62\nL40\nL24\nL71\nR69\nR213\nL647\nR391\nL30\nR59\nR19\nL24\nL8\nL36\nL870\nR74\nL108\nL90\nR158\nR60\nR47\nL677\nL55\nR653\nL16\nR18\nR15\nR85\nL78\nR978\nR74\nR26\nR26\nR74\nR97\nL44\nL1\nR48\nR66\nL66\nL63\nR868\nL34\nL71\nL81\nR181\nR26\nL16\nR60\nL70\nL25\nR99\nR227\nL42\nL42\nL33\nR50\nR94\nL859\nR431\nL313\nR64\nR69\nR80\nR69\nR31\nL10\nR10\nL94\nL1\nR440\nL45\nL66\nL952\nR14\nR439\nR65\nR22\nR31\nL219\nL68\nL39\nR91\nL18\nL87\nR8\nR92\nR14\nR60\nR94\nR3\nR916\nR68\nR62\nR70\nR19\nR66\nL85\nR5\nL604\nR64\nL6\nR52\nR95\nR78\nL84\nR2\nR98\nL94\nR194\nL71\nR310\nR844\nL62\nL42\nR13\nL1\nR615\nL6\nR438\nL38\nR142\nR66\nL2\nL58\nR66\nL89\nR75\nR54\nL54\nL88\nR735\nL32\nL15\nR553\nR476\nR95\nL572\nL29\nL23\nR11\nL54\nL57\nL87\nR42\nR30\nL85\nL773\nL19\nR538\nR54\nR580\nR61\nL6\nR65\nL1\nL179\nR84\nL39\nR24\nL38\nL59\nL40\nL75\nL71\nL506\nR6\nR29\nR4\nR861\nL788\nL12\nR46\nR75\nL820\nL1\nL60\nR60\nL51\nL58\nL91\nR80\nR47\nR42\nL6\nR87\nR379\nL80\nR51\nR49\nR41\nR96\nL81\nL5\nL78\nL27\nR905\nL39\nR49\nR890\nL85\nR485\nL82\nL481\nL362\nR95\nL14\nL71\nR253\nR24\nL17\nR18\nL63\nL96\nL60\nR56\nR73\nL73\nR497\nL16\nR63\nL44\nL454\nR421\nR81\nL664\nL12\nR28\nR69\nR31\nL805\nL33\nL46\nR84\nL281\nL5\nL553\nL12\nR76\nL520\nL565\nL650\nR374\nL76\nR12\nR141\nR59\nR96\nR91\nR27\nL23\nL91\nR5\nL26\nL20\nL613\nR61\nL33\nR26\nR16\nR84\nR76\nR52\nR878\nR43\nR10\nL847\nL758\nR43\nL20\nL47\nL10\nR80\nR75\nR25\nL84\nR84\nR88\nL838\nL250\nL505\nR40\nR9\nL33\nL63\nL553\nL87\nL88\nL41\nR21\nR443\nL435\nL58\nR86\nL75\nR74\nL97\nL38\nR80\nL91\nR511\nR204\nR96\nR167\nR33\nL69\nL46\nL85\nL88\nR88\nL945\nR91\nR54\nL774\nR458\nR857\nR506\nL47\nL40\nL478\nL82\nR46\nL46\nR51\nL51\nL50\nR50\nL74\nL26\nR12\nR88\nL72\nL883\nR55\nL936\nL911\nL53\nL76\nL92\nR966\nR69\nR60\nR973\nL19\nL49\nL464\nR310\nL882\nR3\nR62\nL25\nL34\nL102\nL27\nR27\nR788\nL788\nL90\nR95\nL5\nR605\nR9\nR81\nL95\nL74\nL626\nR67\nR33\nR75\nL44\nL44\nL87\nR30\nL14\nR32\nR52\nR37\nR204\nL69\nR27\nR52\nL38\nR24\nL37\nL71\nR2\nL5\nR63\nL789\nL75\nL15\nR82\nL98\nL24\nR30\nR56\nR442\nR88\nL17\nR31\nR10\nL18\nR31\nR60\nR41\nL24\nR87\nR13\nR5\nR16\nR83\nL28\nL76\nL58\nR58\nR66\nR27\nR28\nL49\nR28\nL17\nR57\nL260\nL80\nL64\nL308\nR72\nL5\nL40\nR29\nR12\nL25\nR45\nL" <> ...}
defmodule SecretEntrance do
@starting_pos 50
@dial_range 0..99
@dial_max Enum.max(@dial_range)
@dial_min Enum.min(@dial_range)
@dial_size Range.size(@dial_range)
def part_1(input) do
input
|> String.split()
|> Enum.map(&parse_clicks/1)
|> Enum.reduce([@starting_pos], &map_positions_1/2)
|> Enum.sum_by(&add_zero/1)
end
defp parse_clicks("L" <> clicks), do: {"L", String.to_integer(clicks)}
defp parse_clicks("R" <> clicks), do: {"R", String.to_integer(clicks)}
defp map_positions_1({dir, clicks}, [current_pos | _rest] = positions) do
clicks = rem(clicks, @dial_size)
new_position = dir |> turn_dial(current_pos, clicks) |> new_position()
[new_position | positions]
end
defp turn_dial("L", current_pos, clicks), do: current_pos - clicks
defp turn_dial("R", current_pos, clicks), do: current_pos + clicks
defp new_position(turn) when turn < @dial_min, do: @dial_size + turn
defp new_position(turn) when turn > @dial_max, do: abs(@dial_size - turn)
defp new_position(turn), do: turn
defp add_zero(0), do: 1
defp add_zero(_), do: 0
def part_2(input) do
input
|> String.split()
|> Enum.map(&parse_clicks/1)
|> Enum.reduce([@starting_pos], &map_positions_2/2)
|> Enum.sum_by(&add_zero/1)
end
defp map_positions_2({dir, clicks}, [current_pos | rest]) when clicks > @dial_max do
zeros = List.duplicate(0, div(clicks, @dial_size))
clicks = rem(clicks, @dial_size)
positions = [current_pos | zeros] ++ rest
map_positions_2({dir, clicks}, positions)
end
defp map_positions_2({dir, clicks}, [current_pos | _rest] = positions) do
clicks = rem(clicks, @dial_size)
turn = turn_dial(dir, current_pos, clicks)
new_position = new_position(turn)
if turn not in @dial_range and 0 not in [new_position, current_pos] do
[new_position, 0] ++ positions
else
[new_position | positions]
end
end
end
{:module, SecretEntrance, <<70, 79, 82, 49, 0, 0, 18, ...>>, {:map_positions_2, 2}}
test_input = "L68\nL30\nR48\nL5\nR60\nL55\nL1\nL99\nR14\nL82"
SecretEntrance.part_1(puzzle_input)
1086
Part 2
# SecretEntrance.part_2(test_input)
SecretEntrance.part_2(puzzle_input)
6268