Skip to content

Commit

Permalink
Add new functions
Browse files Browse the repository at this point in the history
  • Loading branch information
goloop committed Jul 1, 2023
1 parent 065d32e commit 31c3156
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 12 deletions.
74 changes: 67 additions & 7 deletions fn.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ var (
// may outweigh the benefits of concurrent processing. This variable
// specifies the minimum number of iterations per goroutine to ensure
// an efficient division of labor.
minLoadPeGoroutine = 1024
minLoadPerGoroutine = 1024
)

// Logicable is a special data type from which to determine the state of Trit
Expand Down Expand Up @@ -234,11 +234,11 @@ func All[T Logicable](t ...T) Trit {
found := &logicFoundValue{value: True}

// If the length of the slice is less than or equal to
// the minLoadPeGoroutine, then we do not need
// the minLoadPerGoroutine, then we do not need
// to use goroutines.
if l := len(t); l == 0 {
return False
} else if l/p < minLoadPeGoroutine {
} else if l/p < minLoadPerGoroutine {
for _, v := range t {
trit := logicToTrit(v)
if trit.IsFalse() || trit.IsUnknown() {
Expand Down Expand Up @@ -302,11 +302,11 @@ func Any[T Logicable](t ...T) Trit {
found := &logicFoundValue{value: False}

// If the length of the slice is less than or equal to
// the minLoadPeGoroutine, then we do not need
// the minLoadPerGoroutine, then we do not need
// to use goroutines.
if l := len(t); l == 0 {
return False
} else if l/p < minLoadPeGoroutine {
} else if l/p < minLoadPerGoroutine {
for _, v := range t {
trit := logicToTrit(v)
if trit.IsTrue() {
Expand Down Expand Up @@ -548,11 +548,11 @@ func Known[T Logicable](ts ...T) Trit {
found := &logicFoundValue{value: True}

// If the length of the slice is less than or equal to
// the minLoadPeGoroutine, then we do not need
// the minLoadPerGoroutine, then we do not need
// to use goroutines.
if l := len(ts); l == 0 {
return False
} else if l/p < minLoadPeGoroutine {
} else if l/p < minLoadPerGoroutine {
for _, t := range ts {
trit := logicToTrit(t)
if trit == Unknown {
Expand Down Expand Up @@ -664,3 +664,63 @@ func Random(up ...uint8) Trit {

return False
}

// Consensus returns True if all input trits are True, False if all are False,
// and Unknown otherwise.
//
// Example usage:
//
// t1, t2, t3 := trit.True, trit.True, trit.Unknown
// result := Consensus(t1, t2, t3)
// // result will be Unknown, as not all trits are the same
func Consensus[T Logicable](trits ...T) Trit {
countT := 0
countF := 0
for _, x := range trits {
trit := logicToTrit(x)
switch trit.Val() {
case True:
countT++
case False:
countF++
default:
return Unknown
}
}
if countT == len(trits) {
return True
} else if countF == len(trits) {
return False
}

return Unknown
}

// Majority returns True if more than half of the input trits are True, False
// if more than half are False, and Unknown otherwise.
//
// Example usage:
//
// t1, t2, t3, t4 := trit.True, trit.True, trit.False, trit.Unknown
// result := Majority(t1, t2, t3, t4)
// // result will be True, as more than half of the trits are True
func Majority[T Logicable](trits ...T) Trit {
countT := 0
countF := 0
for _, x := range trits {
trit := logicToTrit(x)
switch trit.Val() {
case True:
countT++
case False:
countF++
}
}
if countT > len(trits)/2 {
return True
} else if countF > len(trits)/2 {
return False
} else {
return Unknown
}
}
58 changes: 53 additions & 5 deletions fn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func TestConvert(t *testing.T) {
// TestAll tests the All function.
func TestAll(t *testing.T) {
ParallelTasks(2)
minLoadPeGoroutine = 20
minLoadPerGoroutine = 20
tests := []struct {
name string
in []Trit
Expand Down Expand Up @@ -218,7 +218,7 @@ func TestAll(t *testing.T) {
// TestAny tests the Any function.
func TestAny(t *testing.T) {
ParallelTasks(2)
minLoadPeGoroutine = 20
minLoadPerGoroutine = 20
tests := []struct {
name string
in []Trit
Expand Down Expand Up @@ -988,7 +988,7 @@ func TestNeq(t *testing.T) {
// TestKnown tests the Known function.
func TestKnown(t *testing.T) {
ParallelTasks(2)
minLoadPeGoroutine = 20
minLoadPerGoroutine = 20
tests := []struct {
name string
in []Trit
Expand Down Expand Up @@ -1107,7 +1107,7 @@ func TestRandom(t *testing.T) {
}

// Unknow - 0%
for i := 0; i < 100; i++ {
for i := 0; i < 10; i++ {
result = Random(0)
if result == Unknown {
t.Errorf("Expected a random value as True or False, got %v",
Expand All @@ -1116,10 +1116,58 @@ func TestRandom(t *testing.T) {
}

// Two arguments.
for i := 0; i < 100; i++ {
for i := 0; i < 10; i++ {
result = Random(90, 5, 5)
if result != Unknown {
t.Errorf("Expected a random value as Unknown, got %v", result)
}
}

result = Random(90, 60, 90)
if result != Unknown {
t.Errorf("Expected a random value as Unknown, got %v", result)
}
}

// TestConsensus tests Consensus function.
func TestConsensus(t *testing.T) {
testCases := []struct {
name string
input []Trit
expected Trit
}{
{"All True", []Trit{True, True, True}, True},
{"All False", []Trit{False, False, False}, False},
{"Mixed", []Trit{True, False, True}, Unknown},
{"With Unknown", []Trit{True, True, Unknown}, Unknown},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if result := Consensus(tc.input...); result != tc.expected {
t.Fatalf("Expected %v, but got %v", tc.expected, result)
}
})
}
}

// TestMajority tests Majority function.
func TestMajority(t *testing.T) {
testCases := []struct {
name string
input []Trit
expected Trit
}{
{"Majority True", []Trit{True, True, False}, True},
{"Majority False", []Trit{False, False, True}, False},
{"No Majority", []Trit{True, False, Unknown}, Unknown},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
if result := Majority(tc.input...); result != tc.expected {
t.Fatalf("Expected %v, but got %v", tc.expected, result)
}
})
}
}

0 comments on commit 31c3156

Please sign in to comment.