-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfactoradic.go
51 lines (46 loc) · 1.36 KB
/
factoradic.go
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
// Package factoradic provides support for [factorial numbers](https://xkcd.com/2835/).
package factoradic
import "fmt"
// A Number represents an integer value between 0 and 3628799₁₀ which renders in factorial base.
type Number int32
// String returns the factorial-base representation of a Number.
func (n Number) String() string {
if n >= 0 {
nn := int32(n)
var result [9]byte
for base := int32(2); base <= 10; base++ {
result[10-base] = '0' + byte(nn%base)
nn /= base
if nn == 0 {
return string(result[10-base:])
}
}
}
return "###"
}
// ParseNumber interprets a string in factorial base and returns the corresponding value as a Number.
// Returns a syntax error if any of the digits is outside of the allowable digits for that position,
// or if the string length is longer than the maximum 9 digits allowed for factorial-base numbers.
func ParseNumber(str string) (Number, error) {
if len(str) == 0 || len(str) > 9 {
return 0, syntaxError(str)
}
var (
result int32
base int32 = 2
cumBase int32 = 1
)
for i := len(str) - 1; i >= 0; i-- {
digit := int32(str[i] - '0')
if digit < 0 || digit >= base {
return 0, syntaxError(str)
}
result += digit * cumBase
cumBase *= base
base++
}
return Number(result), nil
}
func syntaxError(s string) error {
return fmt.Errorf("factoradic.Parse: parsing %q: invalid syntax", s)
}