kwando

kwando

Advent of Code 2022 - Day 9

Took a while, but another use case for “move vectors” today and pattern matching. :slight_smile:

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 :slight_smile:

Quite happy with this solution.

https://github.com/kwando/AoC2022/blob/main/09/day09.livemd

Most Liked

milli

milli

I forgot to mention I was refactoring mainly for beauty :wink: It looks like we’ll get to enjoy enough of 10k optimizing in Day 11, though :smile:

Arzar

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

milli

After a lot of refactoring I’m solving both parts using the same function and I’m happy with my code :slight_smile:

  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

Full solution on GitHub

Where Next?

Popular in Challenges Top

QuinnWilton
Note: This topic is to talk about Day 7 of the Advent of Code 2019 . There is a private leaderboard for elixirforum members. You can joi...
New
bjorng
This topic is about Day 15 of the Advent of Code 2021. We have a private leaderboard (shared with users of Erlang Forums): https://adve...
New
bjorng
Here is my solution: https://github.com/bjorng/advent-of-code-2021/blob/77bdef7a51b428b58ffb4ab76f540901e636f841/day12/lib/day12.ex
New
Aetherus
This topic is about Day 5 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/le...
New
bjorng
Here is my solution for day 1 of Advent of Code: defmodule Day01 do def part1(input) do all = parse(input) {first, second} = E...
New
liamcmitchell
A frustrating one for me. I spent a long time trying to understand why some combinations resulted in fewer presses and struggled to keep ...
New
connorlay
Note by the Moderators: This topic is for general discussion about the Advent of Code 2018. To prevent people from being spoiled about s...
New
bjorng
Note: This topic is to talk about Day 6 of the Advent of Code 2019. There is a private leaderboard for elixirforum members. You can join...
New
bjorng
Note: This topic is to talk about Day 23 of the Advent of Code. For general discussion about the Advent of Code 2018 and links to topics...
New
christhekeele
Setting this down for the night, as after a quick naive solve for quick part 1 I realize that part 2 is by design computationally expensi...
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 42920 311
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
AngeloChecked
What learn first? Rust or Elixir Hi Elixir community! I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

We're in Beta

About us Mission Statement