WIP(example/yolo)

This commit is contained in:
sugarme 2020-07-12 19:26:27 +10:00
parent 013e1e710b
commit 5f8e5a51a4
5 changed files with 477 additions and 0 deletions

View File

@ -0,0 +1 @@
package main

226
example/yolo/binary-tree.go Normal file
View File

@ -0,0 +1,226 @@
package main
import (
"fmt"
"log"
)
const (
black, red bool = true, false
)
// Tree is a tree container that holds TNode elements
type Tree struct {
Root *Node
size int
Comparator Comparator
}
// Node is a tree element
type Node struct {
Key interface{}
Value interface{}
Left *Node
Right *Node
Parent *Node
color bool
}
// NewTree creates a tree with a specified comparator
func NewTree(c Comparator) *Tree {
return &Tree{Comparator: c}
}
// Put inserts a node to tree
func (t *Tree) Put(k interface{}, v interface{}) (err error) {
var insertedNode *Node
if t.Root == nil {
t.Comparator = t.Comparator.Init()
t.Root = &Node{Key: k, Value: v, color: red}
err = nil
} else {
node := t.Root
var loop bool = true
for loop {
switch t.Comparator.Compare(k, node.Key) {
case 0:
node.Key = k
node.Value = v
return
case -1:
if node.Left == nil {
node.Left = &Node{Key: k, Value: v, color: red}
insertedNode = node.Left
loop = false
} else {
node = node.Left
}
case 1:
if node.Right == nil {
node.Right = &Node{Key: k, Value: v, color: red}
insertedNode = node.Right
loop = false
} else {
node = node.Right
}
}
} // end of for loop
insertedNode.Parent = node
}
t.insertCase1(insertedNode)
t.size++
return nil
}
// MustPut inserts new node. It will panic if err occurs.
func (t *Tree) MustPut(k interface{}, v interface{}) {
err := t.Put(k, v)
if err != nil {
log.Fatal(err)
}
}
// Get returns a corresponding value for specified key. If not found, returns
// nil.
func (t *Tree) Get(k interface{}) (retVal interface{}, found bool) {
node := t.lookup(k)
if node == nil {
return nil, false
}
return node.Value, true
}
func (t *Tree) Remove(k interface{}) (err error) {
var child *Node
node := t.lookup(k)
if node == nil {
err = fmt.Errorf("Node not found for specified key (%v)\n", k)
return err
}
if node.Left != nil && node.Right != nil {
pred := node.maximumNode()
node.Key = pred.Key
node.Value = pred.Value
node = pred
}
if node.Left != nil || node.Right != nil {
if node.Right == nil {
child = node.Left
} else {
child = node.Right
}
if node.color == black {
node.color = nodeColor(child)
t.deleteCase1(node)
}
t.replaceNode(node, child)
if node.Parent == nil && child != nil {
child.color = black
}
}
t.size--
return nil
}
// IsEmpty returns whether tree is empty
func (t *Tree) IsEmpty() (retVal bool) {
return t.size == 0
}
// Size returns number of nodes in tree
func (t *Tree) Size() (retVal int) {
return t.size
}
// Keys returns all keys (in order)
func (t *Tree) Keys() (retVal []interface{}) {
keys := make([]interface{}, t.size)
iter := t.Iterator()
for i := 0; iter.Next(); i++ {
keys[i] = iter.Key()
}
return keys
}
// Values returns all values of tree
func (t *Tree) Values() (retVal []interface{}) {
vals := make([]interface{}, t.size)
iter := t.Iterator()
for i := 0; iter.Next(); i++ {
vals[i] = iter.Value()
}
return vals
}
func (t *Tree) insertCase1(node *Node) {
if node.Parent == nil {
node.color = black
} else {
t.insertCase2(node)
}
}
func (tree *Tree) insertCase2(node *Node) {
if nodeColor(node.Parent) == black {
return
}
tree.insertCase3(node)
}
func (tree *Tree) insertCase3(node *Node) {
uncle := node.uncle()
if nodeColor(uncle) == red {
node.Parent.color = black
uncle.color = black
node.grandparent().color = red
tree.insertCase1(node.grandparent())
} else {
tree.insertCase4(node)
}
}
func (tree *Tree) insertCase4(node *Node) {
grandparent := node.grandparent()
if node == node.Parent.Right && node.Parent == grandparent.Left {
tree.rotateLeft(node.Parent)
node = node.Left
} else if node == node.Parent.Left && node.Parent == grandparent.Right {
tree.rotateRight(node.Parent)
node = node.Right
}
tree.insertCase5(node)
}
func (tree *Tree) insertCase5(node *Node) {
node.Parent.color = black
grandparent := node.grandparent()
grandparent.color = red
if node == node.Parent.Left && node.Parent == grandparent.Left {
tree.rotateRight(grandparent)
} else if node == node.Parent.Right && node.Parent == grandparent.Right {
tree.rotateLeft(grandparent)
}
}
func nodeColor(node *Node) bool {
if node == nil {
return black
}
return node.color
}

214
example/yolo/comparator.go Normal file
View File

@ -0,0 +1,214 @@
package main
import (
"log"
"reflect"
)
type Comparator struct{}
// Init initiates a Comparator object
func (c Comparator) Init() Comparator {
return Comparator{}
}
// Comparator compares 2 input a and b of generic type.
// It returns an interger result
// - 0: a == b
// - negative: a < b
// - positive: a > b
// Will be panic if a or be is not of asserted type.
// func (c Comparator) Compare(a, b interface{}) (retVal int) {
func (c Comparator) Compare(a, b interface{}) (retVal int) {
if reflect.TypeOf(a) != reflect.TypeOf(b) {
log.Fatalf("Expected a and b of the same type. Got a type: %v, b type: %v", reflect.TypeOf(a).Kind(), reflect.TypeOf(b).Kind())
}
typ := reflect.TypeOf(a)
switch typ.Name() {
case "string":
return compareString(a.(string), b.(string))
case "uint":
return compareUint(a.(uint), b.(uint))
case "uint8": // including `Byte` type
return compareUint8(a.(uint8), b.(uint8))
case "uint16":
return compareUint16(a.(uint16), b.(uint16))
case "uint32": // including `Rune` type
return compareUint32(a.(uint32), b.(uint32))
case "uint64":
return compareUint64(a.(uint64), b.(uint64))
case "int":
return compareInt(a.(int), b.(int))
case "int8":
return compareInt8(a.(int8), b.(int8))
case "int16":
return compareInt16(a.(int16), b.(int16))
case "int32":
return compareInt32(a.(int32), b.(int32))
case "int64":
return compareInt64(a.(int64), b.(int64))
case "float32":
return compareFloat32(a.(float32), b.(float32))
case "float64":
return compareFloat64(a.(float64), b.(float64))
default:
log.Fatalf("Unsupported a type() or b type().\n", reflect.TypeOf(a).Kind(), reflect.TypeOf(b).Kind())
}
return retVal
}
func compareString(a, b string) (retVal int) {
min := len(b)
if len(a) < len(b) {
min = len(a)
}
diff := 0
for i := 0; i < min && diff == 0; i++ {
diff = int(a[i]) - int(b[i])
}
if diff == 0 {
diff = len(a) - len(b)
}
if diff < 0 {
return -1
}
if diff > 0 {
return 1
}
return 0
}
func compareUint(a, b uint) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareUint8(a, b uint8) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareUint16(a, b uint16) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareUint32(a, b uint32) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareUint64(a, b uint64) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareInt(a, b int) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareInt8(a, b int8) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareInt16(a, b int16) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareInt32(a, b int32) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareInt64(a, b int64) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareFloat32(a, b float32) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}
func compareFloat64(a, b float64) (retVal int) {
switch {
case a > b:
return 1
case a < b:
return -1
default:
return 0
}
}

6
example/yolo/darknet.go Normal file
View File

@ -0,0 +1,6 @@
package main
type block struct {
blockType string
parameters
}

30
example/yolo/sort.go Normal file
View File

@ -0,0 +1,30 @@
package main
import (
"sort"
)
type sortable struct {
values []interface{}
comparator Comparator
}
// Implement `Interface` interface of Go package `sort` for sortable struct:
// =========================================================================
func (s sortable) Len() (retVal int) {
return len(s.values)
}
func (s sortable) Swap(idx1, idx2 int) {
s.values[idx1], s.values[idx2] = s.values[idx2], s.values[idx1]
}
func (s sortable) Less(idx1, idx2 int) (retVal bool) {
return s.comparator.Compare(s.values[idx1], s.values[idx2]) < 0
}
// Sort sorts values in-place.
func Sort(values []interface{}, comparator Comparator) {
sort.Sort(sortable{values, comparator})
}