Skip to content

Instantly share code, notes, and snippets.

@rekyuu
Last active August 29, 2017 09:14
Show Gist options
  • Save rekyuu/3f66fb37611a948f662c2cb6410ace7d to your computer and use it in GitHub Desktop.
Save rekyuu/3f66fb37611a948f662c2cb6410ace7d to your computer and use it in GitHub Desktop.
Elixir Markov
defmodule Markov.Dictionary do
def new do
HashDict.new
end
def parse(dictionary, source) when is_binary(source) do
parse(dictionary, String.split(source))
end
def parse(dictionary, [word1, word2 | rest]) do
value = Dict.get(dictionary, word1, [])
dictionary = Dict.put(dictionary, word1, [word2 | value])
parse(dictionary, [word2 | rest])
end
def parse(dictionary, [_single]), do: dictionary
def next(dictionary, word), do: Dict.get(dictionary, word)
end
defmodule Markov.Generator do
def generate_words(dictionary, start_word, num_words) do
generate_words(dictionary, start_word, num_words - 1, [start_word])
end
def generate_words(_dictionary, _start_word, 0, generated_words) do
Enum.reverse(generated_words) |> Enum.join(" ")
end
def generate_words(dictionary, start_word, num_words, generated_words) do
new_word = get_word(dictionary, start_word)
generate_words(dictionary, new_word, num_words - 1, [new_word | generated_words])
end
defp get_word(dictionary, start_word) do
case TelegramBot.Markov.Dictionary.next(dictionary, start_word) do
nil -> nil
list -> Enum.shuffle(list) |> hd
end
end
end
defmodule Markov do
def gen_markov(input_file, word_count \\ 0, start_word \\ nil) do
alias Markov.Dictionary
alias Markov.Generator
:random.seed(:os.timestamp)
filepath = input_file
file = File.read!(filepath)
lines = file |> String.split("\n")
words = lines |> Enum.join(" ")
markov_length =
case word_count do
0 ->
avg = round(length(words |> String.split) / length(lines))
avg + :random.uniform(avg * 3)
count -> count
end
markov_start =
case start_word do
nil -> words |> String.split |> Enum.random
literally_anything_else -> literally_anything_else
end
Dictionary.new
|> Dictionary.parse(file)
|> Generator.generate_words(markov_start, markov_length)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment