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 printLoading(n int, total int) {
 22	var bar []string
 23	tantPerFourty := int((float64(n) / float64(total)) * 40)
 24	tantPerCent := int((float64(n) / float64(total)) * 100)
 25	for i := 0; i < tantPerFourty; i++ {
 26		bar = append(bar, "█")
 27	}
 28	progressBar := strings.Join(bar, "")
 29	fmt.Printf("\r " + progressBar + " - " + strconv.Itoa(tantPerCent) + "%")
 30}
 31
 32func addWordToStates(states []State, word string) ([]State, int) {
 33	iState := -1
 34	for i := 0; i < len(states); i++ {
 35		if states[i].Word == word {
 36			iState = i
 37		}
 38	}
 39	if iState >= 0 {
 40		states[iState].Count++
 41	} else {
 42		var tempState State
 43		tempState.Word = word
 44		tempState.Count = 1
 45
 46		states = append(states, tempState)
 47		iState = len(states) - 1
 48
 49	}
 50	return states, iState
 51}
 52
 53func calcMarkovStates(words []string) []State {
 54	var states []State
 55	//count words
 56	for i := 0; i < len(words)-1; i++ {
 57		var iState int
 58		states, iState = addWordToStates(states, words[i])
 59		if iState < len(words) {
 60			states[iState].NextStates, _ = addWordToStates(states[iState].NextStates, words[i+1])
 61		}
 62
 63		printLoading(i, len(words))
 64	}
 65
 66	//count prob
 67	for i := 0; i < len(states); i++ {
 68		states[i].Prob = (float64(states[i].Count) / float64(len(words)) * 100)
 69		for j := 0; j < len(states[i].NextStates); j++ {
 70			states[i].NextStates[j].Prob = (float64(states[i].NextStates[j].Count) / float64(len(words)) * 100)
 71		}
 72	}
 73	fmt.Println("total words computed: " + strconv.Itoa(len(words)))
 74	//fmt.Println(states)
 75	return states
 76}
 77
 78func textToWords(text string) []string {
 79	s := strings.Split(text, " ")
 80	words := s
 81	return words
 82}
 83
 84func (markov Markov) train(text string) []State {
 85
 86	words := textToWords(text)
 87	states := calcMarkovStates(words)
 88	//fmt.Println(states)
 89
 90	return states
 91}
 92
 93func getNextMarkovState(states []State, word string) string {
 94	iState := -1
 95	for i := 0; i < len(states); i++ {
 96		if states[i].Word == word {
 97			iState = i
 98		}
 99	}
100	if iState < 0 {
101		return "word no exist on the memory"
102	}
103	var next State
104	next = states[iState].NextStates[0]
105	next.Prob = rand.Float64() * states[iState].Prob
106	for i := 0; i < len(states[iState].NextStates); i++ {
107		if (rand.Float64()*states[iState].NextStates[i].Prob) > next.Prob && states[iState-1].Word != states[iState].NextStates[i].Word {
108			next = states[iState].NextStates[i]
109		}
110	}
111	return next.Word
112}
113func (markov Markov) generateText(states []State, initWord string, count int) string {
114	var generatedText []string
115	word := initWord
116	generatedText = append(generatedText, word)
117	for i := 0; i < count; i++ {
118		word = getNextMarkovState(states, word)
119		generatedText = append(generatedText, word)
120	}
121	generatedText = append(generatedText, ".")
122	text := strings.Join(generatedText, " ")
123	return text
124}