arnaucube
arnaucube/goMarkovPublic Self-hosted repository
goMarkov/markov.go
markov.goRaw
  1package main
  2
  3import (
  4	"fmt"
  5	"math/rand"
  6	"strconv"
  7	"strings"
  8)
  9
 10type Markov struct{}
 11
 12type State struct {
 13	Word       string
 14	Count      int
 15	Prob       float64
 16	NextStates []State
 17}
 18
 19var markov Markov
 20
 21func addWordToStates(states []State, word string) ([]State, int) {
 22	iState := -1
 23	for i := 0; i < len(states); i++ {
 24		if states[i].Word == word {
 25			iState = i
 26		}
 27	}
 28	if iState >= 0 {
 29		states[iState].Count++
 30	} else {
 31		var tempState State
 32		tempState.Word = word
 33		tempState.Count = 1
 34
 35		states = append(states, tempState)
 36		iState = len(states) - 1
 37
 38	}
 39	return states, iState
 40}
 41
 42func calcMarkovStates(words []string) []State {
 43	var states []State
 44	//count words
 45	for i := 0; i < len(words)-1; i++ {
 46		var iState int
 47		states, iState = addWordToStates(states, words[i])
 48		if iState < len(words) {
 49			states[iState].NextStates, _ = addWordToStates(states[iState].NextStates, words[i+1])
 50		}
 51	}
 52
 53	//count prob
 54	for i := 0; i < len(states); i++ {
 55		states[i].Prob = (float64(states[i].Count) / float64(len(words)) * 100)
 56		for j := 0; j < len(states[i].NextStates); j++ {
 57			states[i].NextStates[j].Prob = (float64(states[i].NextStates[j].Count) / float64(len(words)) * 100)
 58		}
 59	}
 60	fmt.Println("total words computed: " + strconv.Itoa(len(words)))
 61	//fmt.Println(states)
 62	return states
 63}
 64
 65func textToWords(text string) []string {
 66	s := strings.Split(text, " ")
 67	words := s
 68	return words
 69}
 70
 71func (markov Markov) train(text string) []State {
 72
 73	words := textToWords(text)
 74	states := calcMarkovStates(words)
 75	//fmt.Println(states)
 76
 77	return states
 78}
 79
 80func getNextMarkovState(states []State, word string) string {
 81	iState := -1
 82	for i := 0; i < len(states); i++ {
 83		if states[i].Word == word {
 84			iState = i
 85		}
 86	}
 87	if iState < 0 {
 88		return "word no exist on the memory"
 89	}
 90	var next State
 91	next = states[iState].NextStates[0]
 92	next.Prob = rand.Float64() * states[iState].Prob
 93	for i := 0; i < len(states[iState].NextStates); i++ {
 94		if (rand.Float64()*states[iState].NextStates[i].Prob) > next.Prob && states[iState-1].Word != states[iState].NextStates[i].Word {
 95			next = states[iState].NextStates[i]
 96		}
 97	}
 98	return next.Word
 99}
100func (markov Markov) generateText(states []State, initWord string, count int) string {
101	var generatedText []string
102	word := initWord
103	generatedText = append(generatedText, word)
104	for i := 0; i < count; i++ {
105		word = getNextMarkovState(states, word)
106		generatedText = append(generatedText, word)
107	}
108	generatedText = append(generatedText, ".")
109	text := strings.Join(generatedText, " ")
110	return text
111}