Permalink
Browse files

Initial

  • Loading branch information...
pboyd committed Jul 20, 2018
0 parents commit b533f938d881596e786a764cce1dc8a88cac8b85
Showing with 125 additions and 0 deletions.
  1. +80 −0 builder.go
  2. +34 −0 builder_test.go
  3. +11 −0 chain.go
@@ -0,0 +1,80 @@
package markov
type Builder struct {
nodes map[interface{}]*builderNode
}
func NewBuilder() *Builder {
return &Builder{
nodes: make(map[interface{}]*builderNode, 1),
}
}
func (b *Builder) Build() []*Node {
nodes := make(map[interface{}]*Node, len(b.nodes))
for value, _ := range b.nodes {
nodes[value] = &Node{
Value: value,
}
}
nodeSlice := make([]*Node, 0, len(b.nodes))
for value, bn := range b.nodes {
node := nodes[value]
node.Children = make([]NodeProbability, 0, len(bn.counts))
for nextValue, probability := range bn.Probabilities() {
node.Children = append(node.Children, NodeProbability{
Node: nodes[nextValue],
Probability: probability,
})
}
nodeSlice = append(nodeSlice, node)
}
return nodeSlice
}
func (b *Builder) Feed(values <-chan interface{}) {
last := b.getNode(nil)
for val := range values {
last.counts[val]++
last = b.getNode(val)
}
}
func (b *Builder) getNode(value interface{}) *builderNode {
node, ok := b.nodes[value]
if !ok {
node = &builderNode{
counts: make(map[interface{}]int, 1),
}
b.nodes[value] = node
}
return node
}
type builderNode struct {
counts map[interface{}]int
}
func (bn *builderNode) Probabilities() map[interface{}]float64 {
sum := 0
for _, c := range bn.counts {
sum += c
}
values := make(map[interface{}]float64, len(bn.counts))
for value, count := range bn.counts {
values[value] = float64(count) / float64(sum)
}
return values
}
@@ -0,0 +1,34 @@
package markov
import (
"testing"
"unicode"
)
func TestFeed(t *testing.T) {
b := NewBuilder()
runes := split(`“Well, Prince, so Genoa and Lucca are now just family estates of the Buonapartes. But I warn you, if you don’t tell me that this means war, if you still try to defend the infamies and horrors perpetrated by that Antichrist—I really believe he is Antichrist—I will have nothing more to do with you and you are no longer my friend, no longer my ‘faithful slave,’ as you call yourself! But how do you do? I see I have frightened you—sit down and tell me all the news.”`)
b.Feed(runes)
nodes := b.Build()
if len(nodes) != 24 {
t.Errorf("got %d nodes, want 24", len(nodes))
}
}
func split(text string) <-chan interface{} {
runes := make(chan interface{})
go func() {
defer close(runes)
for _, r := range text {
if unicode.IsLetter(r) || unicode.IsSpace(r) {
runes <- unicode.ToLower(r)
}
}
}()
return runes
}
@@ -0,0 +1,11 @@
package markov
type Node struct {
Value interface{}
Children []NodeProbability
}
type NodeProbability struct {
*Node
Probability float64
}

0 comments on commit b533f93

Please sign in to comment.