forked from an/flokati
markov.go: slightly reworked
This commit is contained in:
parent
ea01cd063e
commit
7fe45e2bc7
|
@ -130,13 +130,9 @@ func (p MarkovPrefix) String() string {
|
||||||
|
|
||||||
// Shift removes the first word from the Prefix and appends the given word.
|
// Shift removes the first word from the Prefix and appends the given word.
|
||||||
func (p MarkovPrefix) Shift(word string) {
|
func (p MarkovPrefix) Shift(word string) {
|
||||||
if len(p) < *markovPrefixLen {
|
|
||||||
p = append(p, word)
|
|
||||||
} else {
|
|
||||||
copy(p, p[1:])
|
copy(p, p[1:])
|
||||||
p[len(p)-1] = word
|
p[len(p)-1] = word
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// MarkovChain contains a map ("chain") of prefixes to a list of suffixes.
|
// MarkovChain contains a map ("chain") of prefixes to a list of suffixes.
|
||||||
// A prefix is a string of prefixLen words joined with spaces.
|
// A prefix is a string of prefixLen words joined with spaces.
|
||||||
|
@ -155,6 +151,15 @@ func markovNewChain(prefixLen int) *MarkovChain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func markovContains(a []string, s string) bool {
|
||||||
|
for _, v := range a {
|
||||||
|
if v == s {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Write parses the bytes into prefixes and suffixes that are stored in MarkovChain.
|
// Write parses the bytes into prefixes and suffixes that are stored in MarkovChain.
|
||||||
func (c *MarkovChain) Write(in string) (int, error) {
|
func (c *MarkovChain) Write(in string) (int, error) {
|
||||||
in = strings.ToLower(in)
|
in = strings.ToLower(in)
|
||||||
|
@ -164,17 +169,20 @@ func (c *MarkovChain) Write(in string) (int, error) {
|
||||||
}
|
}
|
||||||
sr := strings.NewReader(in)
|
sr := strings.NewReader(in)
|
||||||
p := make(MarkovPrefix, c.prefixLen)
|
p := make(MarkovPrefix, c.prefixLen)
|
||||||
|
c.mu.Lock()
|
||||||
|
defer c.mu.Unlock()
|
||||||
for {
|
for {
|
||||||
var s string
|
var s string
|
||||||
if _, err := fmt.Fscan(sr, &s); err != nil {
|
if _, err := fmt.Fscan(sr, &s); err != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
key := p.String()
|
key := p.String()
|
||||||
c.mu.Lock()
|
if !markovContains(c.MarkovChain[key], s) {
|
||||||
c.MarkovChain[key] = append(c.MarkovChain[key], s)
|
c.MarkovChain[key] = append(c.MarkovChain[key], s)
|
||||||
c.mu.Unlock()
|
|
||||||
xlog.Debug("Chain len: %d, learned [%s] [%s]", len(c.MarkovChain), key, s)
|
xlog.Debug("Chain len: %d, learned [%s] [%s]", len(c.MarkovChain), key, s)
|
||||||
fmt.Println(c.MarkovChain[key])
|
} else {
|
||||||
|
xlog.Debug("Chain len: %d, [%s] [%s] is already known", len(c.MarkovChain), key, s)
|
||||||
|
}
|
||||||
p.Shift(s)
|
p.Shift(s)
|
||||||
}
|
}
|
||||||
return len(in), nil
|
return len(in), nil
|
||||||
|
@ -193,19 +201,10 @@ func (c *MarkovChain) Generate(n int, in string) string {
|
||||||
var words []string
|
var words []string
|
||||||
var start string
|
var start string
|
||||||
for attempt := 0; attempt < 10; attempt++ {
|
for attempt := 0; attempt < 10; attempt++ {
|
||||||
/*
|
|
||||||
p = make(MarkovPrefix, c.prefixLen)
|
p = make(MarkovPrefix, c.prefixLen)
|
||||||
p = strings.Split(in, " ")
|
|
||||||
if len(p) > c.prefixLen {
|
|
||||||
i := rand.Intn(len(p) - 2)
|
|
||||||
p = p[i : i+c.prefixLen]
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
p = make(MarkovPrefix, 1)
|
|
||||||
inWords := strings.Split(in, " ")
|
inWords := strings.Split(in, " ")
|
||||||
start = inWords[rand.Intn(len(inWords))]
|
start = inWords[rand.Intn(len(inWords))]
|
||||||
p[0] = start
|
p.Shift(start)
|
||||||
//ss = p.String()
|
|
||||||
xlog.Debug("Looking for answer on [%s]", start)
|
xlog.Debug("Looking for answer on [%s]", start)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
choices := c.MarkovChain[p.String()]
|
choices := c.MarkovChain[p.String()]
|
||||||
|
|
Loading…
Reference in New Issue