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("\ntotal 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}