summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--factor_info.go12
-rw-r--r--factors/factors_test.go9
-rw-r--r--factors/totative.go15
3 files changed, 30 insertions, 6 deletions
diff --git a/factor_info.go b/factor_info.go
index ce014ed..93cb9d2 100644
--- a/factor_info.go
+++ b/factor_info.go
@@ -20,6 +20,9 @@ type FactorInfo struct {
Factors []uint
// An estimate of the utility of the radix's factors.
Score float64
+ // The number of digits that are totatives (numbers that share no
+ // factors with the radix - they are the worst kind of digits)
+ TotativeCount uint
// The fraction of digits that are totatives (numbers that share no
// factors with the radix - they are the worst kind of digits)
TotativeRatio float64
@@ -70,15 +73,16 @@ func GetFactorInfo(radix uint) *FactorInfo {
}
return &FactorInfo{radix, factors.PrimeFactorize(radix),
- r_factors, factors.Score(radix), factors.TotativeRatio(radix),
- factors.BasicRank(radix), r_type_ptr, mtc_ptr,
- math.Log(float64(radix)), digitMap}
+ r_factors, factors.Score(radix), factors.TotativeCount(radix),
+ factors.TotativeRatio(radix), factors.BasicRank(radix),
+ r_type_ptr, mtc_ptr, math.Log(float64(radix)), digitMap}
}
func (fi *FactorInfo) WriteTo(w io.Writer) {
fmt.Fprintln(w, fi.Radix, "=", fi.PrimeFactorization)
fmt.Fprintf(w, "Factors: %v (Score: %.4f)\n", fi.Factors, fi.Score)
- fmt.Fprintf(w, "Totative Ratio: %.3f%%\n", fi.TotativeRatio * 100.0)
+ fmt.Fprintf(w, "Totative Digit Count: %d (%.3f%%)\n",
+ fi.TotativeCount, fi.TotativeRatio * 100.0)
fmt.Fprintln(w, "2345 Rank:", fi.BasicRank)
if fi.Type != nil {
writeTypeMessage(w, *fi.Type)
diff --git a/factors/factors_test.go b/factors/factors_test.go
index 8373ede..6b56e25 100644
--- a/factors/factors_test.go
+++ b/factors/factors_test.go
@@ -71,6 +71,15 @@ func TestTotativeRatio(t *testing.T) {
tableTest(t, TotativeRatio, totativeRatioCases, stdEquals, "TotativeRatio")
}
+var totativeCountCases = map[uint]uint{
+ 1: 1, 2: 1, 3: 2, 4: 2, 6: 2, 7: 6, 8: 4, 12: 4,
+ 14: 6, 15: 8, 30: 8, 60: 16, 120: 32,
+}
+
+func TestTotativeCount(t *testing.T) {
+ tableTest(t, TotativeCount, totativeCountCases, stdEquals, "TotativeCount")
+}
+
var factorScoreCases = map[uint]float64{
1: 1.0,
2: 1.5,
diff --git a/factors/totative.go b/factors/totative.go
index 3a1f635..7a4bebe 100644
--- a/factors/totative.go
+++ b/factors/totative.go
@@ -1,12 +1,22 @@
package factors
-// TotativeRatio calculates the fraction of numbers less than n that
+// TotativeRatio calculates the fraction of numbers that
// are totatives of n (share no factors with n)
func TotativeRatio(n uint) float64 {
if n == 0 {
panic("0 has no totative ratio!")
}
+ return float64(TotativeCount(n)) / float64(n)
+}
+
+// TotativeCount calculates the number of numbers less than n that
+// are totatives of n (share no factors with n)
+func TotativeCount(n uint) uint {
+ if n == 0 {
+ return 0
+ }
+
primeFactorization := PrimeFactorize(n)
num, denom := uint(1), uint(1)
@@ -14,5 +24,6 @@ func TotativeRatio(n uint) float64 {
num *= p - 1
denom *= p
}
- return float64(num) / float64(denom)
+
+ return num * (n / denom)
}