summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrien Hopkins <adrien.p.hopkins@gmail.com>2023-08-03 18:17:55 -0500
committerAdrien Hopkins <adrien.p.hopkins@gmail.com>2023-08-18 14:26:13 -0500
commit1bef5152dfa454b308946791ad7a8efc747e3fbd (patch)
tree8bb7979bcb143a6d8ceaaf936a4693e7fd791d96
parentce37d0676c6f4c8b64fcaffc3c77c7b1b4d72568 (diff)
Add functionality to print prime factorization
-rw-r--r--factors/prime_factorization.go77
-rw-r--r--radix_info.go24
2 files changed, 101 insertions, 0 deletions
diff --git a/factors/prime_factorization.go b/factors/prime_factorization.go
new file mode 100644
index 0000000..62498b5
--- /dev/null
+++ b/factors/prime_factorization.go
@@ -0,0 +1,77 @@
+package factors
+
+import (
+ "fmt"
+ "sort"
+ "strings"
+)
+
+// PrimeFactorization represents how a number can be represented as a
+// product of prime numbers. This is surprisingly useful for learning
+// about number radices.
+type PrimeFactorization struct {
+ exponents map[uint]uint
+}
+
+// PrimeFactorize creates a PrimeFactorization by factorizing a number.
+func PrimeFactorize(n uint) PrimeFactorization {
+ unfactored := n // number with all found factors removed (divided)
+ exponents := make(map[uint]uint)
+
+ // try each factor starting at 2
+ // if unfactored is divisible divide out until it isn't
+ for f := uint(2); f*f <= unfactored; {
+ if unfactored%f == 0 {
+ unfactored /= f
+ exponents[f] += 1
+ } else {
+ f += 1
+ }
+ }
+
+ // by this point, unfactored is guaranteed to be 1 or prime
+ if unfactored > 1 {
+ exponents[unfactored] += 1
+ }
+ return PrimeFactorization{exponents}
+}
+
+// Exponent returns the exponent for the prime p.
+func (factors PrimeFactorization) Exponent(p uint) uint {
+ return factors.exponents[p]
+}
+
+// ExponentMap creates and returns a map mapping primes to their exponents.
+func (factors PrimeFactorization) ExponentMap() map[uint]uint {
+ exponentMap := make(map[uint]uint, len(factors.exponents))
+ for p, e := range factors.exponents {
+ exponentMap[p] = e
+ }
+ return exponentMap
+}
+
+// Size returns how many primes in this factorization have nonzero exponents.
+func (factors PrimeFactorization) Size() int {
+ return len(factors.exponents)
+}
+
+// String returns a string representation of the prime factorization,
+// which looks like "2^2 × 3".
+func (factors PrimeFactorization) String() string {
+ parts := make([]string, 0, factors.Size())
+ primes := make([]int, 0, factors.Size())
+ for p := range factors.exponents {
+ primes = append(primes, int(p))
+ }
+ sort.Ints(primes)
+
+ for _, p := range primes {
+ if factors.Exponent(uint(p)) == 1 {
+ parts = append(parts, fmt.Sprintf("%d", p))
+ } else {
+ parts = append(parts, fmt.Sprintf("%d^%d", p,
+ factors.Exponent(uint(p))))
+ }
+ }
+ return strings.Join(parts, " × ")
+}
diff --git a/radix_info.go b/radix_info.go
new file mode 100644
index 0000000..4067320
--- /dev/null
+++ b/radix_info.go
@@ -0,0 +1,24 @@
+package main
+
+import (
+ "aphopkins/radix_info/factors"
+ "fmt"
+ "os"
+ "strconv"
+)
+
+func main() {
+ if len(os.Args) > 1 {
+ if n, err := strconv.ParseUint(os.Args[1], 0, 0); err == nil {
+ if n > 1 {
+ fmt.Printf("%d = %s\n", n, factors.PrimeFactorize(uint(n)))
+ } else {
+ fmt.Println("Argument must be an integer above 1.")
+ }
+ } else {
+ fmt.Printf("Argument must be an integer above 1 [%v].\n", err)
+ }
+ } else {
+ fmt.Println("Please provide an argument (radix to study).")
+ }
+}