summaryrefslogtreecommitdiff
path: root/factors/score.go
blob: 9288e8fb647c21a954132b0c7b4e53a1d089210b (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
package factors

import "math"

// Score returns a "factor score" equal to the sum of the reciprocoals
// of the number n's factors.
// Rationale:
// A number's factors are one of the most important things that determines
// how well it functions as a number base.  An easy way to determine how
// good these factors are is to simply count them, but that comes with
// the problem that all factors are considered equal when they really aren't
// - divisibility by 2 (which ensures 1/2 is a terminating fraction and
// you can tell whether a number is even or odd by looking at the last digit)
// is more important than divisibility by 23.  The most obvious way of
// accounting for this is by giving each factor a score and adding those
// scores to get the overall score.  I chose score(f) = 1/f because it is
// the simplest function that captures the intuition that smaller factors
// are more valuable than larger ones.  It also gives the score a meaning:
// a factor's score is the probability a random number is divisible by it.
func Score(n uint) float64 {
	if n == 0 {
		return math.NaN()
	}

	factorSum := uint(0)
	for _, f := range Factors(n) {
		factorSum += f
	}
	return float64(factorSum) / float64(n)
}

// BasicRank returns a rank describing how well a radix handles the simplest
// fractions (1/2, 1/3, 1/4 and 1/5).  Zero and one are not true radices,
// but because this rank otherwise only depends on a radix's remainder
// mod 60, they have the same ranks as 60 and 61 (A+, F~).
// Also known as 2345 Rank.
func BasicRank(n uint) string {
	var firstRank, secondRank string
	if n%2 == 0 {
		if n%3 == 0 {
			if n%4 == 0 {
				firstRank = "A"
			} else {
				firstRank = "B"
			}
		} else {
			if n%4 == 0 {
				firstRank = "C"
			} else {
				firstRank = "D"
			}
		}
	} else {
		if n%3 == 0 {
			firstRank = "E"
		} else {
			firstRank = "F"
		}
	}

	switch n % 5 {
	case 0:
		secondRank = "+"
	case 1, 4:
		secondRank = "~"
	case 2, 3:
		secondRank = "-"
	}

	return firstRank + secondRank
}