wordsearch/match/match.go

81 lines
1.2 KiB
Go
Raw Permalink Normal View History

2023-10-08 14:25:57 +01:00
package match
2023-10-07 17:12:47 +01:00
import (
"bufio"
"io"
2023-10-08 15:05:12 +01:00
"github.com/ray1729/wordsearch/util"
2023-10-07 17:12:47 +01:00
)
type DB struct {
2023-10-08 14:25:57 +01:00
Root *Node
}
func New() DB {
return DB{Root: &Node{}}
2023-10-08 14:25:57 +01:00
}
func (db DB) Add(s string) {
2023-10-08 14:25:57 +01:00
xs := util.LowerCaseAlpha(s)
db.Root.add(xs, s)
2023-10-07 17:12:47 +01:00
}
type Node struct {
Value byte
Children []*Node
Results []string
}
2023-10-08 14:25:57 +01:00
func (n *Node) add(xs []byte, s string) {
2023-10-07 17:12:47 +01:00
if len(xs) == 0 {
n.Results = append(n.Results, s)
return
}
x := xs[0]
var child *Node
for _, c := range n.Children {
if c.Value == x {
child = c
break
}
}
if child == nil {
child = &Node{Value: x}
n.Children = append(n.Children, child)
}
2023-10-08 14:25:57 +01:00
child.add(xs[1:], s)
2023-10-07 17:12:47 +01:00
}
func Load(r io.Reader) (DB, error) {
2023-10-08 14:25:57 +01:00
db := New()
2023-10-07 17:12:47 +01:00
sc := bufio.NewScanner(r)
for sc.Scan() {
2023-10-08 14:25:57 +01:00
db.Add(sc.Text())
2023-10-07 17:12:47 +01:00
}
return db, sc.Err()
2023-10-07 17:12:47 +01:00
}
func (db DB) FindMatches(s string) []string {
2023-10-08 14:25:57 +01:00
return db.Root.find(util.LowerCaseAlphaOrDot(s))
2023-10-07 17:12:47 +01:00
}
func (n *Node) find(xs []byte) []string {
if len(xs) == 0 {
return n.Results
}
x := xs[0]
if x == '.' {
var result []string
for _, c := range n.Children {
result = append(result, c.find(xs[1:])...)
}
return result
}
for _, c := range n.Children {
if c.Value == x {
return c.find(xs[1:])
}
}
return nil
}