Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Initial
- Loading branch information
Paul Boyd
committed
Jul 20, 2018
0 parents
commit b533f93
Showing
3 changed files
with
125 additions
and
0 deletions.
There are no files selected for viewing
80
builder.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
11
chain.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package markov | ||
|
||
type Node struct { | ||
Value interface{} | ||
Children []NodeProbability | ||
} | ||
|
||
type NodeProbability struct { | ||
*Node | ||
Probability float64 | ||
} |