Skip to content

Instantly share code, notes, and snippets.

@ynonp
Created December 10, 2020 18:17
Show Gist options
  • Save ynonp/0fb4dea3fe13cfa914c4dddae2e1d97f to your computer and use it in GitHub Desktop.
Save ynonp/0fb4dea3fe13cfa914c4dddae2e1d97f to your computer and use it in GitHub Desktop.
defmodule Day10 do
def read_input do
File.read!("input/day10.txt")
|> String.split("\n", trim: true)
|> Enum.map(&String.to_integer/1)
|> Enum.sort
end
def create_graph(lines) do
nodes = [0] ++ lines ++ [Enum.max(lines) + 3]
for i <- nodes, j <- nodes, i < j, j - i <= 3 do
%{ i => [j] }
end
|> Enum.reduce(&(Map.merge(&1, &2, fn _k, v1, v2 -> v1 ++ v2 end)))
end
def create_graph2(lines) do
nodes = [0] ++ lines ++ [Enum.max(lines) + 3]
for i <- nodes, j <- nodes, i < j, j - i <= 3 do
%{ j => [i] }
end
|> Enum.reduce(&(Map.merge(&1, &2, fn _k, v1, v2 -> v1 ++ v2 end)))
end
def find_paths(graph, start, visited \\ MapSet.new) do
next_nodes = Map.get(graph, start, nil)
if next_nodes do
# Stream.flat_map(next_nodes, &(find_paths(graph, &1, MapSet.put(visited, &1))))
selected_node = Enum.min(next_nodes)
find_paths(graph, selected_node, MapSet.put(visited, selected_node))
else
visited
end
end
def count_paths(graph, source, dest) do
case Map.get(graph, source, []) do
[] ->
if source == dest, do: 1, else: 0
nodes ->
nodes
|> Enum.map(&(count_paths(graph, &1, dest)))
|> Enum.sum
end
end
def count_paths(lines) do
graph = create_graph2(lines)
source = Enum.max(Map.keys(graph))
destination = Map.values(graph)
|> Enum.flat_map(fn x -> x end)
|> Enum.min
count_paths(graph, source, destination)
end
def find_differences(path) do
path
|> Enum.flat_map_reduce(0, fn x, acc ->
{ [x - acc], x }
end)
end
def part1 do
%{1 => ones, 3 => threes} = read_input()
|> create_graph
|> find_paths(0)
|> IO.inspect(charlists: :as_lists)
|> MapSet.to_list
|> Enum.sort
|> find_differences
|> Kernel.elem(0)
|> Enum.frequencies
|> IO.inspect(charlists: :as_lists)
IO.inspect(ones * threes)
end
def part2 do
differences = read_input()
|> find_differences
|> Kernel.elem(0)
data = read_input()
Enum.zip(differences, data)
|> Enum.chunk_while([], fn
{ 1, el }, acc -> { :cont, acc ++ [el] }
{ 3, el }, acc -> { :cont, acc, [el] }
end, fn acc -> { :cont, acc, [] } end)
|> Enum.map(&count_paths/1)
|> Enum.reduce(fn acc, val -> acc * val end)
|> IO.inspect(charlists: :as_lists)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment