kwando
Advent of Code 2022 - Day 9
Took a while, but another use case for “move vectors” today and pattern matching. ![]()
The trick was to first generate a list of position for the head with the help of the instructions.
Then you you use that list to move the tail, and repeat that process for as many knots there are… a perfect job for Enum.scan ![]()
Quite happy with this solution.
Most Liked
milli
I forgot to mention I was refactoring mainly for beauty
It looks like we’ll get to enjoy enough of 10k optimizing in Day 11, though ![]()
Arzar
It was really fun coding this ̶s̶n̶a̶k̶e̶ rope-thing simulator (code below is part 2)
defmodule Day9 do
def move_head({x, y}, "L"), do: {x - 1, y}
def move_head({x, y}, "R"), do: {x + 1, y}
def move_head({x, y}, "U"), do: {x, y + 1}
def move_head({x, y}, "D"), do: {x, y - 1}
def move_toward(prev, current) do
if prev - current > 0, do: current + 1, else: current - 1
end
def move_knot({x_prev, y_prev}, {x, y}) do
cond do
abs(x_prev - x) <= 1 and abs(y_prev - y) <= 1 -> {x, y} # adjacent
x == x_prev -> {x, move_toward(y_prev, y)} # same line
y == y_prev -> {move_toward(x_prev, x), y} # same column
true -> {move_toward(x_prev, x), move_toward(y_prev, y)} # not touching
end
end
def start() do
moves = File.stream!("input09")
|> Stream.map(&String.trim/1)
|> Enum.map(&String.split/1)
|> Enum.flat_map(fn [dir, step] -> for _ <-1..String.to_integer(step), do: dir end)
knots = for _ <- 1..9, do: {0, 0}
{_, _, tail_history} = Enum.reduce(moves , {{0, 0}, knots, []}, fn dir, {head, knots, tail_history} ->
head = move_head(head, dir)
{knots, tail} = Enum.map_reduce(knots, head, fn knot, prev_knot ->
knot = move_knot(prev_knot, knot)
{knot, knot}
end)
{head, knots, [tail | tail_history]}
end)
tail_history |> Enum.uniq |> Enum.count
end
end
milli
After a lot of refactoring I’m solving both parts using the same function and I’m happy with my code ![]()
defp move([dir | rest], [head | knots], tail_path) do
new_head = move_head(dir, head)
new_rope = Enum.scan([new_head | knots], fn tail, head -> follow(head, tail) end)
move(rest, new_rope, MapSet.put(tail_path, Enum.at(new_rope, -1)))
end
adamu
You’re not supposed to share the problem text or input according to the AoC ToS. Although that’s probably a lost cause by now ![]()
Enjoyed this one. Part 2 took me by surprise, but it was fun. I managed to reuse the functions from part 1, just updated motion function to keep track of the intermediary knots in a list, with map_reduce to simultaneously enumerate the knots + track the previous one.
defp step_head({x, y}, "R"), do: {x + 1, y}
defp step_head({x, y}, "L"), do: {x - 1, y}
defp step_head({x, y}, "U"), do: {x, y + 1}
defp step_head({x, y}, "D"), do: {x, y - 1}
defp step_tail({hx, hy}, {tx, ty}) when abs(hx - tx) <= 1 and abs(hy - ty) <= 1, do: {tx, ty}
defp step_tail({tx, hy}, {tx, ty}) when hy - ty > 0, do: {tx, ty + 1}
defp step_tail({tx, hy}, {tx, ty}) when hy - ty < 0, do: {tx, ty - 1}
defp step_tail({hx, ty}, {tx, ty}) when hx - tx > 0, do: {tx + 1, ty}
defp step_tail({hx, ty}, {tx, ty}) when hx - tx < 0, do: {tx - 1, ty}
defp step_tail({hx, hy}, {tx, ty}) do
dx = if hx - tx > 0, do: 1, else: -1
dy = if hy - ty > 0, do: 1, else: -1
{tx + dx, ty + dy}
end
kwando
Oh, didnt know that. Gonna stop adding that to my livebooks
thanks for the heads up!







