-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmodtabs.go
66 lines (56 loc) · 1.38 KB
/
modtabs.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
package main
import (
"flag"
"fmt"
"math/big"
"strconv"
"strings"
)
func gcd(a, b int) int {
for a > b && b != 0 {
a, b = b, a%b
}
return a
}
func main() {
flag.Usage = func() {
fmt.Println("Usage: go run modtabs -n=X")
flag.PrintDefaults()
}
var n int
flag.IntVar(&n, "n", 0, "mod n")
flag.Parse()
nLen := len(strconv.Itoa(n))
colFmt := fmt.Sprintf("%%%dd", nLen)
cols := make([]string, 0, n)
for i := 0; i < n; i++ {
cols = append(cols, colFmt)
}
colFmt = strings.Join(cols, " ")
nums := make([]interface{}, 0, n)
for i := 0; i < n; i++ {
nums = append(nums, i)
}
fmt.Println(fmt.Sprintf(strings.Repeat(" ", nLen+4)+colFmt+" (order/gcd)", nums...))
rowFmt := fmt.Sprintf("%%%dd | %s %%s", nLen, colFmt)
for r := 1; r < n; r++ {
rowElem := make([]interface{}, 0, n+2)
rowElem = append(rowElem, r)
order := -1
for c := 0; c < n; c++ {
x := big.NewInt(int64(r)).Exp(big.NewInt(int64(r)), big.NewInt(int64(c)), big.NewInt(int64(n))).Int64()
if order < 0 && c > 0 && x == 1 {
order = c
}
rowElem = append(rowElem, x)
}
if order < 0 {
rowElem = append(rowElem, fmt.Sprintf("%d (gcd)", gcd(n, r)))
} else if order == n-1 {
rowElem = append(rowElem, fmt.Sprintf("%d (p)", order))
} else {
rowElem = append(rowElem, fmt.Sprintf("%d", order))
}
fmt.Println(fmt.Sprintf(rowFmt, rowElem...))
}
}