Skip to content

Commit 31c3156

Browse files
committed
Add new functions
1 parent 065d32e commit 31c3156

2 files changed

Lines changed: 120 additions & 12 deletions

File tree

fn.go

Lines changed: 67 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ var (
2424
// may outweigh the benefits of concurrent processing. This variable
2525
// specifies the minimum number of iterations per goroutine to ensure
2626
// an efficient division of labor.
27-
minLoadPeGoroutine = 1024
27+
minLoadPerGoroutine = 1024
2828
)
2929

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

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

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

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

665665
return False
666666
}
667+
668+
// Consensus returns True if all input trits are True, False if all are False,
669+
// and Unknown otherwise.
670+
//
671+
// Example usage:
672+
//
673+
// t1, t2, t3 := trit.True, trit.True, trit.Unknown
674+
// result := Consensus(t1, t2, t3)
675+
// // result will be Unknown, as not all trits are the same
676+
func Consensus[T Logicable](trits ...T) Trit {
677+
countT := 0
678+
countF := 0
679+
for _, x := range trits {
680+
trit := logicToTrit(x)
681+
switch trit.Val() {
682+
case True:
683+
countT++
684+
case False:
685+
countF++
686+
default:
687+
return Unknown
688+
}
689+
}
690+
if countT == len(trits) {
691+
return True
692+
} else if countF == len(trits) {
693+
return False
694+
}
695+
696+
return Unknown
697+
}
698+
699+
// Majority returns True if more than half of the input trits are True, False
700+
// if more than half are False, and Unknown otherwise.
701+
//
702+
// Example usage:
703+
//
704+
// t1, t2, t3, t4 := trit.True, trit.True, trit.False, trit.Unknown
705+
// result := Majority(t1, t2, t3, t4)
706+
// // result will be True, as more than half of the trits are True
707+
func Majority[T Logicable](trits ...T) Trit {
708+
countT := 0
709+
countF := 0
710+
for _, x := range trits {
711+
trit := logicToTrit(x)
712+
switch trit.Val() {
713+
case True:
714+
countT++
715+
case False:
716+
countF++
717+
}
718+
}
719+
if countT > len(trits)/2 {
720+
return True
721+
} else if countF > len(trits)/2 {
722+
return False
723+
} else {
724+
return Unknown
725+
}
726+
}

fn_test.go

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func TestConvert(t *testing.T) {
167167
// TestAll tests the All function.
168168
func TestAll(t *testing.T) {
169169
ParallelTasks(2)
170-
minLoadPeGoroutine = 20
170+
minLoadPerGoroutine = 20
171171
tests := []struct {
172172
name string
173173
in []Trit
@@ -218,7 +218,7 @@ func TestAll(t *testing.T) {
218218
// TestAny tests the Any function.
219219
func TestAny(t *testing.T) {
220220
ParallelTasks(2)
221-
minLoadPeGoroutine = 20
221+
minLoadPerGoroutine = 20
222222
tests := []struct {
223223
name string
224224
in []Trit
@@ -988,7 +988,7 @@ func TestNeq(t *testing.T) {
988988
// TestKnown tests the Known function.
989989
func TestKnown(t *testing.T) {
990990
ParallelTasks(2)
991-
minLoadPeGoroutine = 20
991+
minLoadPerGoroutine = 20
992992
tests := []struct {
993993
name string
994994
in []Trit
@@ -1107,7 +1107,7 @@ func TestRandom(t *testing.T) {
11071107
}
11081108

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

11181118
// Two arguments.
1119-
for i := 0; i < 100; i++ {
1119+
for i := 0; i < 10; i++ {
11201120
result = Random(90, 5, 5)
11211121
if result != Unknown {
11221122
t.Errorf("Expected a random value as Unknown, got %v", result)
11231123
}
11241124
}
1125+
1126+
result = Random(90, 60, 90)
1127+
if result != Unknown {
1128+
t.Errorf("Expected a random value as Unknown, got %v", result)
1129+
}
1130+
}
1131+
1132+
// TestConsensus tests Consensus function.
1133+
func TestConsensus(t *testing.T) {
1134+
testCases := []struct {
1135+
name string
1136+
input []Trit
1137+
expected Trit
1138+
}{
1139+
{"All True", []Trit{True, True, True}, True},
1140+
{"All False", []Trit{False, False, False}, False},
1141+
{"Mixed", []Trit{True, False, True}, Unknown},
1142+
{"With Unknown", []Trit{True, True, Unknown}, Unknown},
1143+
}
1144+
1145+
for _, tc := range testCases {
1146+
t.Run(tc.name, func(t *testing.T) {
1147+
if result := Consensus(tc.input...); result != tc.expected {
1148+
t.Fatalf("Expected %v, but got %v", tc.expected, result)
1149+
}
1150+
})
1151+
}
1152+
}
1153+
1154+
// TestMajority tests Majority function.
1155+
func TestMajority(t *testing.T) {
1156+
testCases := []struct {
1157+
name string
1158+
input []Trit
1159+
expected Trit
1160+
}{
1161+
{"Majority True", []Trit{True, True, False}, True},
1162+
{"Majority False", []Trit{False, False, True}, False},
1163+
{"No Majority", []Trit{True, False, Unknown}, Unknown},
1164+
}
1165+
1166+
for _, tc := range testCases {
1167+
t.Run(tc.name, func(t *testing.T) {
1168+
if result := Majority(tc.input...); result != tc.expected {
1169+
t.Fatalf("Expected %v, but got %v", tc.expected, result)
1170+
}
1171+
})
1172+
}
11251173
}

0 commit comments

Comments
 (0)