-
Notifications
You must be signed in to change notification settings - Fork 4
/
divide-by-nines.go
68 lines (60 loc) · 1.16 KB
/
divide-by-nines.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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package main
import (
"fmt"
"log"
"math/big"
"strings"
)
func main() {
log.SetFlags(0)
log.SetPrefix("divide-by-nines: ")
for i := int64(0); i < 1e4; i++ {
_, period := div9(big.NewInt(i), 1e3)
fmt.Println(i, period)
}
}
func newint(s string) *big.Int {
x := new(big.Int)
_, ok := x.SetString(s, 0)
if !ok {
log.Fatal("invalid integer:", s)
}
return x
}
// if we divide by the number x by 9.999....
// where 9.999... is as long as the number of digits x has
// it generates a repeating pattern of that digit until it
// dries out, we log that inside period
// if the number happens to be 99 etc then it will not work
// and it won't repeat
func div9(x *big.Int, prec int) (val string, period int) {
n := new(big.Rat)
d := new(big.Rat)
n.SetInt(x)
t := x.String()
s := ""
for i := 0; i < len(t); i++ {
s += "9"
if i == 0 {
s += "."
}
}
if len(t) == 1 {
s = ".9"
}
d.SetString(s)
n.Quo(n, d)
f := new(big.Float)
f.SetRat(n)
val = f.Text('f', prec)
val = strings.ReplaceAll(val, ".", "")
loop:
for j := 0; ; period++ {
for i := 0; i < len(t); i, j = i+1, j+1 {
if j >= len(val) || t[i] != val[j] {
break loop
}
}
}
return
}