65 lines
1.6 KiB
Elixir
65 lines
1.6 KiB
Elixir
|
input = IO.gets("input?")
|
||
|
|> String.trim
|
||
|
|> String.split(" ")
|
||
|
|> Enum.map(fn part ->
|
||
|
String.to_integer part
|
||
|
end)
|
||
|
|
||
|
defmodule Day1_2 do
|
||
|
def pass(input, state) do
|
||
|
|
||
|
# pass through the entire list with reduce
|
||
|
# so we have some kind of state in acc
|
||
|
result = Enum.reduce(input, state, fn part, acc ->
|
||
|
case acc do
|
||
|
|
||
|
# if we already found it, we don't need
|
||
|
# to keep iterating
|
||
|
{:ok, res} ->
|
||
|
{:ok, res}
|
||
|
|
||
|
# acc grows like this:
|
||
|
# [0]
|
||
|
# [0 + first_change | 0]
|
||
|
|
||
|
# [0 + first_change + second_change |
|
||
|
# [0 + first_change | 0]], etc
|
||
|
[current | _rest] ->
|
||
|
# the head of the list is the current
|
||
|
# frequency of the device that we'll
|
||
|
# apply the change to (part)
|
||
|
new_freq = current + part
|
||
|
|
||
|
# then we search in the OLD list
|
||
|
# if we are a member of it
|
||
|
#
|
||
|
# if we are, then we are actually the first
|
||
|
# repeated frequency in the list.
|
||
|
became_member = Enum.member?(acc, new_freq)
|
||
|
|
||
|
if became_member do
|
||
|
# this should make the reduce()
|
||
|
# call stop creating new frequencies
|
||
|
# and just returning what it found
|
||
|
{:ok, new_freq}
|
||
|
else
|
||
|
# if we didn't find, we add the new frequency
|
||
|
# to the list, and keep going.
|
||
|
[new_freq | acc]
|
||
|
end
|
||
|
end
|
||
|
end)
|
||
|
|
||
|
case result do
|
||
|
{:ok, res} -> res
|
||
|
|
||
|
# if
|
||
|
_ -> pass(input, result)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
res = Day1_2.pass(input, [0])
|
||
|
|
||
|
IO.puts "total res: #{inspect res}"
|