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

maennchen
Ok, that was a rough one today. I haven’t found a way to improve the algorithm further. Part 1 runs in .5 seconds, Part 2 in ~ 5 minutes...
New
stevensonmt
Reasonably pleased with my solution. The bitstring packet problems are so well suited to Erlang/Elixir it’s almost not fair. defmodule D...
New
jkwchui
Monkeys fitted squarely as GenServers in my head. My initial problem was using cast instead of call; I imagine impolite monkeys slinging...
New
sb8244
Note: This topic is to talk about Day 10 of the Advent of Code 2019 . There is a private leaderboard for elixirforum members. You can jo...
New
rugyoga
part 1 https://github.com/rugyoga/aoc2021/blob/main/day7.exs part 2 https://github.com/rugyoga/aoc2021/blob/main/day7b.exs
New
adamu
Nobody’s doing Advent of Code this year? :grinning_face_with_smiling_eyes: I might do the first week or so. For Day 1, first I solved i...
New
rvnash
Anyone have a solution to Part 2 today? Part 1 was straight forward, but I can’t figure out a programatic way to do part 2. I understand ...
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
Aetherus
This topic is about Day 16 of the Advent of Code 2020 . Thanks to @egze, we have a private leaderboard: https://adventofcode.com/2020/l...
New
christhekeele
Thought I’d kick today’s thread off! Parsing Enum rocks, so most of my code was actually in parsing input. ▶ Preprocessing input Part 1...
New

Other popular topics Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41539 114
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30877 112
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
gausby
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
1207 39297 209
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31142 143
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement