DEV Community

Caleb Weeks
Caleb Weeks

Posted on • Originally published at sethcalebweeks.com

 

Advent of Code Day 8

Links

Highlights

  • Avert your eyes! This is not code that I am proud of, but it got the job done... I remember seeing some Numberphile or other YouTube video about this problem, but couldn't find it. I'm sure there is some useful math trick to make this easier. I have lots of wet and inefficient code with hard-coded values.
  • The only "trick" I used here was representing the grid as a map with tuples of the positions as keys. It is cool that you can use any data type as a key in Elixir. This is the first time I have ever made use of keys that weren't strings or atoms.
defmodule Day08 do
  use AOC

  def get_grid() do
    input(8)
    |> String.split("\n")
    |> Enum.with_index
    |> Enum.reduce(%{}, fn {row, row_num}, map ->
      row
      |> String.codepoints
      |> Enum.with_index
      |> Map.new(fn {height, col_num} -> {{row_num, col_num}, String.to_integer(height)} end)
      |> Map.merge(map)
    end)
  end


  def part1 do
    grid = get_grid()
    grid
    |> Enum.map(fn {{row_num, col_num}, height} ->
      if (row_num == 0 || row_num == 98 || col_num == 0 || col_num == 98) do
        true
      else
        Enum.any?([
          (for col_num <- 0..(col_num-1), do: Map.get(grid, {row_num, col_num}) < height) |> Enum.all?,
          (for col_num <- (col_num+1)..98, do: Map.get(grid, {row_num, col_num}) < height) |> Enum.all?,
          (for row_num <- 0..(row_num-1), do: Map.get(grid, {row_num, col_num}) < height) |> Enum.all?,
          (for row_num <- (row_num+1)..98, do: Map.get(grid, {row_num, col_num}) < height) |> Enum.all?,
        ])
      end
    end)
    |> Enum.count(&Function.identity/1)
  end

  def part2 do
    grid = get_grid()
    grid
    |> Enum.map(fn {{row_num, col_num}, height} ->
      if (row_num == 0 || row_num == 98 || col_num == 0 || col_num == 98) do
        0
      else
        [
          (for col_num <- (col_num-1)..0, do: Map.get(grid, {row_num, col_num})),
          (for col_num <- (col_num+1)..98, do: Map.get(grid, {row_num, col_num})),
          (for row_num <- (row_num-1)..0, do: Map.get(grid, {row_num, col_num})),
          (for row_num <- (row_num+1)..98, do: Map.get(grid, {row_num, col_num})),
        ]
        |> Enum.reduce(1, fn direction, product ->
          visible = direction
          |> Enum.take_while(fn tree -> tree < height end)
          |> (fn blocked -> min(length(blocked) + 1, length(direction)) end).()
          (visible) * product
        end)
      end
    end)
    |> Enum.max
  end

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.