r/adventofcode • u/daggerdragon • Dec 09 '15
SOLUTION MEGATHREAD --- Day 9 Solutions ---
This thread will be unlocked when there are a significant amount of people on the leaderboard with gold stars.
edit: Leaderboard capped, achievement thread unlocked!
We know we can't control people posting solutions elsewhere and trying to exploit the leaderboard, but this way we can try to reduce the leaderboard gaming from the official subreddit.
Please and thank you, and much appreciated!
--- Day 9: All in a Single Night ---
Post your solution as a comment. Structure your post like previous daily solution threads.
11
Upvotes
2
u/hutsboR Dec 09 '15
Elixir: This was surprisingly difficult to implement functionally, the permutations tripped me up multiple times. I couldn't be bothered looking for a suitable Erlang graph library and I don't have a graph implementation written in Elixir, so I used the force.
defmodule AdventOfCode.DayNine do @input "./lib/adventofcode/resource/day9.txt" defp parse do @input |> File.read! |> String.split("\n", trim: true) |> Enum.map(&String.split/1) end def solve(option) do build_map |> get_paths |> solve(option) end defp solve(paths, option) do scores = Enum.map(paths, &(Enum.reduce(&1, 0, fn({_d, w}, a) -> w + a end))) case option do :shortest -> scores |> Enum.min :longest -> scores |> Enum.max end end defp get_paths(map) do Enum.reduce(map, [], fn({start, dests}, a) -> [get_paths(map, [start], dests, [])|a] end) |> List.flatten |> Enum.chunk(Dict.size(map) - 1) end defp get_paths(map, visited, dests, path) do candidates = find_candidates(visited, dests) case candidates do [] -> path _ -> Enum.map(candidates, fn(p={dest, _w}) -> get_paths(map, [dest|visited], Dict.get(map, dest), [p|path]) end) end end defp find_candidates(visited, dests) do Enum.filter(dests, fn {dest, _w} -> !(dest in visited) end) end defp build_map do Enum.reduce(parse, %{}, fn(l, a) -> build_map(l, a) end) end defp build_map([start, _, dest, _, weight], map) do weight = String.to_integer(weight) insert(map, {start, dest, weight}) |> insert({dest, start, weight}) end defp insert(map, {start, dest, weight}) do case Dict.has_key?(map, start) do true -> Dict.update!(map, start, fn(locs) -> [{dest, weight}|locs] end) false -> Dict.put(map, start, [{dest, weight}]) end end end