Advent of Code 2024/8
Mix.install([
{:kino, "~> 0.18"}
])
Section
input = Kino.Input.textarea("input")
defmodule AoC2025_1 do
defp step(state, {instruction, value}) do
case instruction do
"L" -> step_left(state, value)
"R" -> step_right(state, value)
end
end
defp state_at_zero({0, 0}), do: {0, 1}
defp state_at_zero({pos, points}), do: {pos, points}
defp state_crossing_zero(0), do: 0
defp state_crossing_zero(_), do: 1
def step_left(state, value) do
pos = state - rem(value, 100)
zero_points = div(value, 100)
cond do
pos == 0 -> {pos, zero_points + 1}
pos < 0 -> {100 + pos, zero_points + state_crossing_zero(state)}
true -> {pos, zero_points}
end
end
def step_right(state, value) do
pos = state + rem(value, 100)
zero_points = div(value, 100)
cond do
pos == 0 -> {pos, zero_points + 1}
pos > 99 -> {pos - 100, zero_points + state_crossing_zero(state)}
true -> {pos, zero_points}
end
end
def parse(input) do
Kino.Input.read(input)
|> String.split("\n", trim: true)
|> Enum.map(fn op -> {String.at(op, 0), String.to_integer(String.slice(op, 1..-1//1))} end)
end
def part_1(input) do
input
|> parse
|> Enum.map_reduce(50, fn {instruction, value}, acc ->
{pos, _} = step(acc, {instruction, value})
{pos, pos}
end)
|> elem(0)
|> dbg()
|> Enum.count(fn el -> el == 0 end)
end
def part_2(input) do
input
|> parse
|> Enum.map_reduce(50, fn {instruction, value}, acc ->
{pos, zero_points} = step(acc, {instruction, value})
{{pos, zero_points, instruction, value}, pos}
end)
|> elem(0)
|> dbg()
|> Enum.sum_by(fn el -> elem(el, 1) end)
end
end
AoC2025_1.part_1(input)
AoC2025_1.part_2(input)