AoC 2022 Day 1 Visualization
Section
Mix.install([
{:explorer, "~> 0.4.0"},
{:vega_lite, "~> 0.1.6"},
{:kino_vega_lite, "~> 0.1.6"}
])
# needed to use Explorer.DataFrame.arrange/2 macro
require Explorer.DataFrame
alias Explorer.DataFrame, as: DF
alias VegaLite, as: Vl
calories_per_elf =
File.read!("./input.txt")
|> String.split("\n\n", trim: true)
|> Stream.with_index()
|> Enum.group_by(fn {_, i} -> "Elf #{i}" end, fn {s, _} ->
String.split(s, "\n", trim: true)
|> Enum.map(&String.to_integer/1)
end)
|> Enum.reduce(%{names: [], calories: []}, fn {k, [v]}, %{names: n, calories: c} = acc ->
%{acc | names: [k | n], calories: [Enum.sum(v) | c]}
end)
sorted_elves =
calories_per_elf
|> DF.new()
|> DF.arrange(desc: calories)
sorted_elves
|> Kino.DataTable.new()
top_50 =
sorted_elves
|> DF.head(50)
Vl.new(title: "Calories Carried by Elf (top 50)", width: 600, height: 400)
|> Vl.data_from_values(top_50)
|> Vl.mark(:bar, corner_radius_end: 50)
|> Vl.encode_field(:x, "names", sort: "-y", type: :nominal)
|> Vl.encode_field(:y, "calories", type: :quantitative)
|> Vl.encode_field(:color, "names", sort: "-y", scale: %{scheme: "tableau20"})