Mix.install([
{:finch, "~> 0.12.0"}
])
Finch.start_link(name: MyFinch)
download_fun = fn
{:status, 200}, acc -> acc
{:headers, _}, acc -> acc
{:data, data}, acc -> acc <> data
end
input_stream_fun = fn url ->
{:ok, data} = Finch.build(:get, url) |> Finch.stream(MyFinch, "", download_fun)
String.splitter(data, "\n", trim: true)
end
What do you get if you multiply your final horizontal position by your final depth?
For example,
forward 5
down 5
forward 8
up 3
down 8
forward 2
After following these instructions, you would have a horizontal position of 15 and a depth of 10. (Multiplying these together produces 150.)
# This is a list of commands, changing horizontal and vertical position.
# First, parse each line to get the command, then map each command
# to a position, and then reduce to both positions.
input_url =
"https://gist.githubusercontent.com/goofansu/64d236d2a3904ad2338b7e7f1d36ebfd/raw/cad0df94526099fd9cd8199e481b90e9d40369ed/gistfile1.txt"
reducer = fn
["forward", units], acc -> update_in(acc[:horizontal], &(&1 + units))
["down", units], acc -> update_in(acc[:depth], &(&1 + units))
["up", units], acc -> update_in(acc[:depth], &(&1 - units))
end
input_stream_fun.(input_url)
|> Stream.map(fn line ->
line
|> String.split(" ")
|> List.update_at(1, &String.to_integer/1)
end)
|> Enum.reduce(Map.new(horizontal: 0, depth: 0), reducer)
|> Map.values()
|> Enum.product()
What do you get if you multiply your final horizontal position by your final depth?
The commands also mean something entirely different than you first thought:
- down X increases your aim by X units.
- up X decreases your aim by X units.
- forward X does two things:
- It increases your horizontal position by X units.
- It increases your depth by your aim multiplied by X.
Now, the above example does something different:
- forward 5 adds 5 to your horizontal position, a total of 5. Because your aim is 0, your depth does not change.
- down 5 adds 5 to your aim, resulting in a value of 5.
- forward 8 adds 8 to your horizontal position, a total of 13. Because your aim is 5, your depth increases by 8*5=40.
- up 3 decreases your aim by 3, resulting in a value of 2.
- down 8 adds 8 to your aim, resulting in a value of 10.
- forward 2 adds 2 to your horizontal position, a total of 15. Because your aim is 10, your depth increases by 2*10=20 to a total of 60.
After following these new instructions, you would have a horizontal position of 15 and a depth of 60. (Multiplying these produces 900.)
reducer = fn
["forward", units], acc ->
acc = update_in(acc[:horizontal], &(&1 + units))
update_in(acc[:depth], &(&1 + acc[:aim] * units))
["down", units], acc ->
update_in(acc[:aim], &(&1 + units))
["up", units], acc ->
update_in(acc[:aim], &(&1 - units))
end
input_stream_fun.(input_url)
|> Stream.map(fn line ->
line
|> String.split(" ")
|> List.update_at(1, &String.to_integer/1)
end)
|> Enum.reduce(Map.new(horizontal: 0, depth: 0, aim: 0), reducer)
|> Map.take([:horizontal, :depth])
|> Map.values()
|> Enum.product()