Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Day 7

2021/elixir_livebook/day07.livemd

Day 7

Helpers

Mix.install([
  {:vega_lite, "~> 0.1.2"},
  {:kino, "~> 0.3.1"}
])

alias VegaLite, as: Vl
defmodule Helpers do
  def data() do
    "data/day07.txt"
    |> File.read!()
    |> String.trim()
    |> String.split(",")
    |> Enum.map(&String.to_integer/1)
  end

  def cost(ls, pos) do
    ls
    |> Enum.reduce(0, &(abs(&1 - pos) + &2))
  end

  def incr_cost(ls, pos) do
    ls
    |> Enum.reduce(0, fn l, tc ->
      dist = abs(l - pos)
      div(dist * (dist + 1), 2) + tc
    end)
  end
end

Part 1

import Helpers

locs = data()
{min_loc, max_loc} = Enum.min_max(locs)

costs =
  for loc <- min_loc..max_loc do
    cost(locs, loc)
  end

costs |> Enum.min() |> IO.inspect()

Vl.new(title: "Constant cost per distance moved", width: 400, height: 400)
|> Vl.data_from_series(location: min_loc..max_loc, cost: costs)
|> Vl.mark(:line)
|> Vl.encode_field(:x, "location", type: :quantitative)
|> Vl.encode_field(:y, "cost", type: :quantitative)

Part 2

import Helpers

locs = data()
{min_loc, max_loc} = Enum.min_max(locs)

incr_costs =
  for loc <- min_loc..max_loc do
    incr_cost(locs, loc)
  end

incr_costs |> Enum.min() |> IO.inspect()

Vl.new(title: "Increasing cost based on distance moved", width: 400, height: 400)
|> Vl.data_from_series(location: min_loc..max_loc, cost: incr_costs)
|> Vl.mark(:line)
|> Vl.encode_field(:x, "location", type: :quantitative)
|> Vl.encode_field(:y, "cost", type: :quantitative)