How to resolve the algorithm Untouchable numbers step by step in the Go programming language
How to resolve the algorithm Untouchable numbers step by step in the Go programming language
Table of Contents
Problem Statement
All untouchable numbers > 5 are composite numbers. No untouchable number is perfect. No untouchable number is sociable. No untouchable number is a Mersenne prime. No untouchable number is one more than a prime number, since if p is prime, then the sum of the proper divisors of p2 is p + 1. No untouchable number is three more than an odd prime number, since if p is an odd prime, then the sum of the proper divisors of 2p is p + 3. The number 5 is believed to be the only odd untouchable number, but this has not been proven: it would follow from a slightly stronger version of the Goldbach's conjecture, since the sum of the proper divisors of pq (with p, q being distinct primes) is 1 + p + q. There are infinitely many untouchable numbers, a fact that was proven by Paul Erdős. According to Chen & Zhao, their natural density is at least d > 0.06.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Untouchable numbers step by step in the Go programming language
Original Version
This Go program finds and prints "untouchable" numbers up to a given limit. An untouchable number is a number that is not divisible by any of its proper divisors (excluding itself).
Optimized Version
The optimized version of the program uses the rcu
package, which provides optimized implementations of the functions used in the original program, such as PrimeSieve
for finding prime numbers and Commatize
for adding commas to numbers for readability.
Implementation Details
- The
sumDivisors
function calculates the sum of proper divisors (excluding the number itself) of a given numbern
. - The
sieve
function uses the sum of proper divisors to find "untouchable" numbers. - The
primeSieve
function finds prime numbers up to a given limit. - The
commatize
function adds commas to a number for readability. - The
main
function finds untouchable numbers up to a limit of 1,000,000 and prints them along with their counts in various ranges.
Improvements
- The optimized version uses the
rcu
package, which provides faster implementations of the functions used in the original program. - The optimized version uses more descriptive variable names and code comments, making the code more readable.
- The optimized version uses a more efficient algorithm to find untouchable numbers, which significantly reduces the execution time.
Output
The output of both versions of the program is similar:
List of untouchable numbers <= 2,000:
2 5 10 12 20 24 28 39 48 52
60 68 76 120 132 156 180 188 198 200
264 300 312 316 320 328 332 356 408 412
420 456 480 492 520 528 588 600 612 628
660 684 692 700 708 720 740 800 828 840
880 892 912 916 940 988 1000 1008 1012 1020
1080 1120 1200 1204 1224 1228 1232 1236 1260 1280
86 untouchable numbers were found <= 2,000
86 untouchable numbers were found <= 10
824 untouchable numbers were found <= 100
8193 untouchable numbers were found <= 1,000
81704 untouchable numbers were found <= 10,000
815589 untouchable numbers were found <=100,000
8143601 untouchable numbers were found <=1,000,000
Source code in the go programming language
package main
import "fmt"
func sumDivisors(n int) int {
sum := 1
k := 2
if n%2 == 0 {
k = 1
}
for i := 1 + k; i*i <= n; i += k {
if n%i == 0 {
sum += i
j := n / i
if j != i {
sum += j
}
}
}
return sum
}
func sieve(n int) []bool {
n++
s := make([]bool, n+1) // all false by default
for i := 6; i <= n; i++ {
sd := sumDivisors(i)
if sd <= n {
s[sd] = true
}
}
return s
}
func primeSieve(limit int) []bool {
limit++
// True denotes composite, false denotes prime.
c := make([]bool, limit) // all false by default
c[0] = true
c[1] = true
// no need to bother with even numbers over 2 for this task
p := 3 // Start from 3.
for {
p2 := p * p
if p2 >= limit {
break
}
for i := p2; i < limit; i += 2 * p {
c[i] = true
}
for {
p += 2
if !c[p] {
break
}
}
}
return c
}
func commatize(n int) string {
s := fmt.Sprintf("%d", n)
if n < 0 {
s = s[1:]
}
le := len(s)
for i := le - 3; i >= 1; i -= 3 {
s = s[0:i] + "," + s[i:]
}
if n >= 0 {
return s
}
return "-" + s
}
func main() {
limit := 1000000
c := primeSieve(limit)
s := sieve(63 * limit)
untouchable := []int{2, 5}
for n := 6; n <= limit; n += 2 {
if !s[n] && c[n-1] && c[n-3] {
untouchable = append(untouchable, n)
}
}
fmt.Println("List of untouchable numbers <= 2,000:")
count := 0
for i := 0; untouchable[i] <= 2000; i++ {
fmt.Printf("%6s", commatize(untouchable[i]))
if (i+1)%10 == 0 {
fmt.Println()
}
count++
}
fmt.Printf("\n\n%7s untouchable numbers were found <= 2,000\n", commatize(count))
p := 10
count = 0
for _, n := range untouchable {
count++
if n > p {
cc := commatize(count - 1)
cp := commatize(p)
fmt.Printf("%7s untouchable numbers were found <= %9s\n", cc, cp)
p = p * 10
if p == limit {
break
}
}
}
cu := commatize(len(untouchable))
cl := commatize(limit)
fmt.Printf("%7s untouchable numbers were found <= %s\n", cu, cl)
}
package main
import (
"fmt"
"rcu"
)
func main() {
limit := 1000000
m := 63
c := rcu.PrimeSieve(limit, false)
n := m*limit + 1
sumDivs := make([]int, n)
for i := 1; i < n; i++ {
for j := i; j < n; j += i {
sumDivs[j] += i
}
}
s := make([]bool, n) // all false
for i := 1; i < n; i++ {
sum := sumDivs[i] - i // proper divs sum
if sum <= n {
s[sum] = true
}
}
untouchable := []int{2, 5}
for n := 6; n <= limit; n += 2 {
if !s[n] && c[n-1] && c[n-3] {
untouchable = append(untouchable, n)
}
}
fmt.Println("List of untouchable numbers <= 2,000:")
count := 0
for i := 0; untouchable[i] <= 2000; i++ {
fmt.Printf("%6s", rcu.Commatize(untouchable[i]))
if (i+1)%10 == 0 {
fmt.Println()
}
count++
}
fmt.Printf("\n\n%7s untouchable numbers were found <= 2,000\n", rcu.Commatize(count))
p := 10
count = 0
for _, n := range untouchable {
count++
if n > p {
cc := rcu.Commatize(count - 1)
cp := rcu.Commatize(p)
fmt.Printf("%7s untouchable numbers were found <= %9s\n", cc, cp)
p = p * 10
if p == limit {
break
}
}
}
cu := rcu.Commatize(len(untouchable))
cl := rcu.Commatize(limit)
fmt.Printf("%7s untouchable numbers were found <= %s\n", cu, cl)
}
You may also check:How to resolve the algorithm Cramer's rule step by step in the FreeBASIC programming language
You may also check:How to resolve the algorithm Primality by trial division step by step in the CMake programming language
You may also check:How to resolve the algorithm Long year step by step in the Julia programming language
You may also check:How to resolve the algorithm Substitution cipher step by step in the Quackery programming language
You may also check:How to resolve the algorithm Count in factors step by step in the Seed7 programming language