Skip to content

Instantly share code, notes, and snippets.

@kipcole9
Last active March 29, 2022 00:23
Show Gist options
  • Save kipcole9/7ba7012a906d5a6d8592fc6574e82448 to your computer and use it in GitHub Desktop.
Save kipcole9/7ba7012a906d5a6d8592fc6574e82448 to your computer and use it in GitHub Desktop.
Distance graph builder
defmodule Distance do
@moduledoc """
Ensure that you have the following in your mix.exs
file:
def deps do
{:libgraph, "~> 0.13"}
end
"""
@string "Sun 57909227 Mercury
Earth 384400 Moon
Sun 149598262 Earth
Sun Moon
Deimos Moon
Deimos
Deimos Phobos
Moon
LROrbiter"
@doc """
Parse a string into a list of tuples
where each tuple is of the form
{from, to, weight: distance}
"""
def parse(string \\ @string) when is_binary(string) do
string
|> String.split("\n")
|> Enum.map(&String.trim/1)
|> Enum.map(&String.split/1)
|> Enum.map(&do_parse/1)
end
@doc """
Return only those tuples that
have a distance
"""
def with_distance(distances) do
Enum.filter(distances, &has_distance?/1)
end
@doc """
Return only those tuples that
have no distance
"""
def with_no_distance(distances) do
Enum.reject(distances, &has_distance?/1)
end
@doc """
Build a graph of the distances using
the [libgraph](https://hex.pm/packages/libgraph) library.
"""
def build_graph(distances) do
graph = Graph.new()
edges = with_distance(distances)
Graph.add_edges(graph, edges)
end
@doc """
Return the distance from one body
to all its connected bodies.
"""
def distances_from(graph, body) do
Graph.out_edges(graph, body)
end
defp do_parse([from, distance, to]) do
{from, to, weight: String.to_integer(distance)}
end
defp do_parse([from, to]) do
{from, to, weight: nil}
end
defp do_parse([from]) do
{from, nil, weight: nil}
end
defp has_distance?({_from, _to, weight: weight}) do
!is_nil(weight)
end
end
@kipcole9
Copy link
Author

Note that this module requires the libgraph library to be configured in your mix.exs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment