DEV Community

Caleb Weeks
Caleb Weeks

Posted on • Updated on • Originally published at sethcalebweeks.com

 

Advent of Code Day 5

Links

Highlights

  • Today's problem involved pretty standard stack manipulation. I used a recursive function to move each crate one at a time for part one. Part two was more straightforward since you could move all the crates at once.
  • I didn't bother with parsing the initial state and manually entered it. The parsing of the instructions uses regex named captures with a bit of juggling to get the count to be an integer.
defmodule Day05 do
  use AOC

  @stacks %{
    "1" => ["W", "B", "G", "Z", "R", "D", "C", "V"],
    "2" => ["V", "T", "S", "B", "C", "F", "W", "G"],
    "3" => ["W", "N", "S", "B", "C"],
    "4" => ["P", "C", "V", "J", "N", "M", "G", "Q"],
    "5" => ["B", "H", "D", "F", "L", "S", "T"],
    "6" => ["N", "M", "W", "T", "V", "J"],
    "7" => ["G", "T", "S", "C", "L", "F", "P"],
    "8" => ["Z", "D", "B"],
    "9" => ["W", "Z", "N", "M"]
  }

  def move_by_1(stacks, %{"count" => 1, "from" => from, "to" => to}) do
    {item, new_from} = stacks[from] |> List.pop_at(0)
    stacks |> Map.merge(%{
      from => new_from,
      to => [item | stacks[to]]
    })
  end
  def move_by_1(stacks, %{"count" => count, "from" => from, "to" => to}) do
    {item, new_from} = stacks[from] |> List.pop_at(0)
    stacks
    |> Map.merge(%{
      from => new_from,
      to => [item | stacks[to]]
    })
    |> move_by_1(%{"count" => count - 1, "from" => from, "to" => to})
  end

  def move_by_count(stacks, %{"count" => count, "from" => from, "to" => to}) do
    {items, new_from} = stacks[from] |> Enum.split(count)
    stacks |> Map.merge(%{
      from => new_from,
      to => items ++ stacks[to]
    })
  end

  def parse_instructions(fun) do
    [_, instructions] = input(5) ~> String.split("\n\n")

    instructions
    |> String.split("\n")
    |> Enum.reduce(@stacks, fn instruction, stacks ->
      %{"count" => count, "from" => from, "to" => to} = Regex.named_captures(~r/move (?<count>.*) from (?<from>.*) to (?<to>.*)/, instruction)
      fun.(stacks,  %{"count" => String.to_integer(count), "from" => from, "to" => to})
    end)
    |> Enum.reduce("", fn {_, stack}, str -> str <> hd(stack) end)
  end

  def part1, do: parse_instructions(&move_by_1/2)

  def part2, do: parse_instructions(&move_by_count/2)

end
Enter fullscreen mode Exit fullscreen mode

Top comments (0)

An Animated Guide to Node.js Event Loop

Node.js doesn’t stop from running other operations because of Libuv, a C++ library responsible for the event loop and asynchronously handling tasks such as network requests, DNS resolution, file system operations, data encryption, etc.

What happens under the hood when Node.js works on tasks such as database queries? We will explore it by following this piece of code step by step.