summaryrefslogtreecommitdiff
path: root/factor_info.go
blob: ee04e32baf05419cbe4090c83e96846a6bb0bbf8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package main

import (
	"aphopkins/radix_info/factors"
	"fmt"
	"io"
	"math"
	"slices"
)

// FactorInfo contains all of the information this program
// calculates about a radix.
type FactorInfo struct {
	// The radix this info is about
	Radix uint
	// A representation of this radix as a product of prime numbers.
	// Most of the important info about radices is determined through this.
	PrimeFactorization factors.PrimeFactorization
	// The radix's factors, in sorted order.
	Factors []uint
	// An estimate of the utility of the radix's factors.
	Score float64
	// The fraction of digits that are totatives (numbers that share no
	// factors with the radix - they are the worst kind of digits)
	TotativeRatio float64
	// A rank measuring how well the radix works with the most elementary
	// numbers and ratios
	BasicRank string
	// Whether or not this radix is part of any special factor-related classes.
	// This is not calculated if the radix is too large - in this case
	// this field will be nil.
	Type *factors.NumberType
	// An estimate of the complexity of the radix's multiplication table.
	// This is not calculated if the radix is too large - in this case
	// this field will be nil.
	MTC *uint64
	// The radix's natural logarithm.  This determines the length of numbers
	// in this radix - higher Ln means numbers take up fewer digits.
	// If c = log(a)/log(b), then numbers in radix b will be around
	// c times longer than numbers in radix a.
	Ln float64
	// Information about each digit's compatibility with the radix.
	// This determines what kind of decimal expansion the digit's
	// reciprocoal has and what patterns are in its row of the multiplication
	// table.
	DigitMap []factors.DigitType
}

func GetFactorInfo(radix uint) *FactorInfo {
	r_factors := factors.Factors(radix)
	slices.Sort(r_factors)

	var r_type_ptr *factors.NumberType
	var mtc_ptr *uint64
	if radix < 1<<32 {
		r_type := factors.Type(uint32(radix))
		r_type_ptr = &r_type
		mtc := factors.MTC(uint64(radix))
		mtc_ptr = &mtc
	} else {
		r_type_ptr = nil
		mtc_ptr = nil
	}

	var digitMap []factors.DigitType
	if radix <= maxSmallRadix {
		digitMap = factors.DigitMap(radix)
	} else {
		digitMap = []factors.DigitType{}
	}

	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}
}

func (fi *FactorInfo) WriteTo(w io.Writer) {
	fmt.Fprintln(w, fi.Radix, "=", fi.PrimeFactorization)
	fmt.Fprintf(w, "Factors: %v (Score: %.2f)\n", fi.Factors, fi.Score)
	fmt.Fprintf(w, "Totative Ratio: %.1f%%\n", fi.TotativeRatio * 100.0)
	fmt.Fprintln(w, "2345 Rank:", fi.BasicRank)
	if fi.Type != nil {
		writeTypeMessage(w, *fi.Type)
	}
	if fi.MTC != nil {
		fmt.Fprintln(w, "Multiplication Table Complexity:", *fi.MTC)
	} else {
		fmt.Fprintf(w, "Multiplication Table Complexity ≤ %.4g\n",
			float32(fi.Radix)*float32(fi.Radix-2))
	}
	fmt.Fprintf(w, "Natural Logarithm: %.2f\n", fi.Ln)
	if len(fi.DigitMap) > 0 {
		writeDigitMap(w, fi.DigitMap)
	}
}

func writeTypeMessage(w io.Writer, t factors.NumberType) {
	switch t {
	case factors.ColossallyAbundant:
		fmt.Fprintln(w, "This radix is colossally abundant!")
	case factors.Superabundant:
		fmt.Fprintln(w, "This radix is superabundant.")
	case factors.OrderedExponent:
		fmt.Fprintln(w, "This radix has ordered exponents.")
	case factors.Practical:
		fmt.Fprintln(w, "This radix is practical.")
	}
}