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

// 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 {
		panic("Cannot get factor score of 0.")
	}

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

// BasicRank returns a rank describing how well a base handles the simplest
// fractions (1/2, 1/3, 1/4 and 1/5)
// 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
}