Skip to content

Instantly share code, notes, and snippets.

@egze
Last active December 28, 2018 14:03
Show Gist options
  • Save egze/33106941f47a7e84ab6fc18deb98a8fe to your computer and use it in GitHub Desktop.
Save egze/33106941f47a7e84ab6fc18deb98a8fe to your computer and use it in GitHub Desktop.
day8
defmodule Day8 do
defmodule Node do
defstruct children_count: 0, metadata_count: 0, metadata: [], children: []
def parse_header(numbers) do
{[children_count, metadata_count], numbers} = Enum.split(numbers, 2)
node = %Node{children_count: children_count, metadata_count: metadata_count}
{node, numbers}
end
def parse_children({%Node{children_count: 0} = node, numbers}) do
{node, numbers}
end
def parse_children({node, numbers}) do
{numbers, children} =
Enum.reduce((1..node.children_count), {numbers, []}, fn _x, {numbers, children} ->
{child, numbers} = Node.tree(numbers)
{numbers, children ++ [child]}
end)
{%Node{node | children: children}, numbers}
end
def parse_metadata({%Node{metadata_count: metadata_count} = node, numbers}) do
{metadata, numbers} = Enum.split(numbers, metadata_count)
{%Node{node | metadata: metadata}, numbers}
end
def tree(numbers) do
numbers
|> parse_header
|> parse_children
|> parse_metadata
end
def sum_metadata(%Node{children: children, metadata: metadata}) do
Enum.reduce(children, Enum.sum(metadata), fn node, sum ->
sum + Node.sum_metadata(node)
end)
end
def value(%Node{children: [], metadata: metadata}) do
Enum.sum(metadata)
end
def value(nil) do
0
end
def value(%Node{children: children, metadata: metadata}) do
Enum.reduce(metadata, 0, fn i, sum ->
sum + Node.value(Enum.at(children, i - 1))
end)
end
end
@doc """
Parses line to list of integers
iex> Day8.parse("2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2")
[2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2]
"""
def numbers(line) do
line
|> String.split
|> Enum.map(&String.to_integer/1)
end
def part1 do
{node, _} =
File.read!("input.txt")
|> numbers()
|> Node.tree()
Node.sum_metadata(node)
end
def part2 do
{node, _} =
File.read!("input.txt")
|> numbers()
|> Node.tree()
Node.value(node)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment