aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Manring <michael@manring>2022-06-13 08:23:36 +0700
committerMichael Manring <michael@manring>2022-06-19 23:34:16 +0700
commit41bc78a200dcb010fd8d388a103c4e02b085f10a (patch)
tree93adcac79787b2999dad48e8e566682e5f9ffd8d
parentdf3ae74efc5d4c300be815c37001376db61d7ab6 (diff)
downloadperlweeklychallenge-club-41bc78a200dcb010fd8d388a103c4e02b085f10a.tar.gz
perlweeklychallenge-club-41bc78a200dcb010fd8d388a103c4e02b085f10a.tar.bz2
perlweeklychallenge-club-41bc78a200dcb010fd8d388a103c4e02b085f10a.zip
refactored and add tests
-rw-r--r--challenge-168/pokgopun/go/ch-1.go47
-rw-r--r--challenge-168/pokgopun/go/ch-2.go149
-rw-r--r--challenge-168/pokgopun/go/homeprime/homeprime.go97
-rw-r--r--challenge-168/pokgopun/go/homeprime/homeprime_test.go18
-rw-r--r--challenge-168/pokgopun/go/perrinprime/perrinprime.go51
-rw-r--r--challenge-168/pokgopun/go/perrinprime/perrinprime_test.go11
-rw-r--r--challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/.gitignore5
-rw-r--r--challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/LICENSE21
-rw-r--r--challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/README.md23
-rw-r--r--challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/count.go73
-rw-r--r--challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/fill.go104
-rw-r--r--challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/primegen.go137
-rw-r--r--challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/sieve.go530
-rw-r--r--challenge-168/pokgopun/go/vendor/modules.txt3
14 files changed, 1108 insertions, 161 deletions
diff --git a/challenge-168/pokgopun/go/ch-1.go b/challenge-168/pokgopun/go/ch-1.go
index 39b69a4633..9e2b200626 100644
--- a/challenge-168/pokgopun/go/ch-1.go
+++ b/challenge-168/pokgopun/go/ch-1.go
@@ -1,42 +1,29 @@
+/*
+The Perrin sequence is defined to start with [3, 0, 2]; after that, term N is the sum of terms N-2 and N-3. (So it continues 3, 2, 5, 5, 7, ….)
+
+A Perrin prime is a number in the Perrin sequence which is also a prime number.
+
+Calculate the first 13 Perrin Primes.
+
+f(13) = [2, 3, 5, 7, 17, 29, 277, 367, 853, 14197, 43721, 1442968193, 792606555396977]
+*/
package main
import (
"fmt"
- "math/big"
+ "log"
"os"
- "sort"
+
+ "github.com/pokgopun/go/perrinprime"
)
func main() {
- l := 13
+ n := 13
if len(os.Args) > 1 {
- fmt.Sscanf(os.Args[1], "%d", &l)
- }
- p := [3]uint{3, 0, 2}
- pp := map[uint]struct{}{}
- e := 0.25
- i, n := 0, 1
- for len(pp) < l && i < 1_000_000 {
- i++
- for float64(e) > 1/float64(p[0]) {
- e *= 0.25
- n++
- }
- //fmt.Printf("p0=%v,n=%v\n", p[0], n)
- if big.NewInt(int64(p[0])).ProbablyPrime(n) {
- pp[p[0]] = struct{}{}
+ _, err := fmt.Sscanf(os.Args[1], "%d", &n)
+ if err != nil {
+ log.Fatal(err)
}
- p = [3]uint{p[1], p[2], p[0] + p[1]}
- }
- ppl := make([]uint, len(pp))
- var j int
- for k := range pp {
- ppl[j] = k
- j++
}
- sort.SliceStable(ppl, func(i, j int) bool {
- return ppl[i] < ppl[j]
- })
- fmt.Println(ppl)
- //fmt.Println(len(pp))
+ fmt.Printf("f(%d) = [%v]\n", n, perrinprime.NewPerrinPrime(n))
}
diff --git a/challenge-168/pokgopun/go/ch-2.go b/challenge-168/pokgopun/go/ch-2.go
index 59d4413c81..70b413fbcc 100644
--- a/challenge-168/pokgopun/go/ch-2.go
+++ b/challenge-168/pokgopun/go/ch-2.go
@@ -1,150 +1,37 @@
+/*
+You are given an integer greater than 1.
+
+Write a script to find the home prime of the given number.
+
+In number theory, the home prime HP(n) of an integer n greater than 1 is the prime number obtained by repeatedly factoring the increasing concatenation of prime factors including repetitions.
+*/
package main
import (
"fmt"
"log"
- "math"
"math/big"
"os"
- "strconv"
+
+ "github.com/pokgopun/go/homeprime"
)
func main() {
- var hp homePrime
- hp.buildPrime(5_000_000, 0)
- //fmt.Println(hp.plist, len(hp.plist))
+ var s []*big.Int
if len(os.Args) > 1 {
for _, v := range os.Args[1:] {
- n, err := strconv.Atoi(v)
- if err != nil {
- log.Fatal(err)
+ n, ok := new(big.Int).SetString(v, 10)
+ if !ok {
+ log.Fatal("failed to set string for big.int")
}
- fmt.Printf("HP(%d) = %d\n", n, hp.find(n))
+ s = append(s, n)
}
} else {
- for i := 1; i <= 47; i++ {
- fmt.Printf("HP(%d) = %d\n", i, hp.find(i))
- }
- }
-}
-
-func (hp homePrime) find(n int) *big.Int {
- bi := big.NewInt(int64(n))
- if n == 1 {
- return bi
- }
- i := 1
- e := big.NewInt(4)
- for e.Cmp(bi) == -1 {
- e.Mul(e, big.NewInt(4))
- i++
- }
- for !bi.ProbablyPrime(i) {
- var str string
- f := hp.factor(bi)
- //fmt.Println(f)
- for _, v := range f {
- str += strconv.Itoa(int(v))
- }
- //fmt.Println(str)
- _, ok := bi.SetString(str, 0)
- if !ok {
- //fmt.Println("Failed on SetString for", bi)
- return big.NewInt(-1)
+ for i := int64(2); i <= 64; i++ {
+ s = append(s, big.NewInt(i))
}
}
- return bi
-}
-
-func (hp *homePrime) buildPrime(n int, o int) {
- hp.pmap = make([]bool, int(n)+1)
- //for i := 2; i <= n; i++ {
- for i := 1; i <= n; i++ {
- hp.pmap[i] = true
- }
- if o < 1 {
- hp.pmap[1] = false
+ for _, v := range s {
+ fmt.Printf("HP(%d) = %v\n", v, homeprime.NewHomePrime(v))
}
- //for i := 2; float64(i) <= math.Sqrt(float64(n)); i++ {
- for i := 2; float64(i) <= math.Sqrt(float64(n+o)); i++ {
- j := i * i
- /*
- for j <= n {
- hp.pmap[j] = false
- j += i
- }
- */
- for j <= n+o {
- if j > o {
- hp.pmap[j-o] = false
- }
- j += i
- }
- }
- hp.plist = []int{}
- /*
- for i := 2; i < len(hp.pmap); i++ {
- if hp.pmap[i] {
- hp.plist = append(hp.plist, i)
- }
- }
- */
- for i := 1; i < len(hp.pmap); i++ {
- if hp.pmap[i] {
- hp.plist = append(hp.plist, i+o)
- }
- }
-}
-
-func (hp *homePrime) factor(n *big.Int) (s []int) {
- if n.Cmp(big.NewInt(1)) == 1 {
- j := 1
- e := big.NewInt(4)
- for e.Cmp(n) == -1 {
- e.Mul(e, big.NewInt(4))
- j++
- //fmt.Println("In factor's e calculation => e=", e)
- }
- if n.ProbablyPrime(j) {
- return []int{int(n.Int64())}
- }
- i := 0
- m := new(big.Int)
- nextPrime := big.NewInt(2)
- if hp.plist[0] != 2 {
- hp.buildPrime(5_000_000, 0)
- }
- o := 0
- for {
- if m.Mod(n, nextPrime).Cmp(big.NewInt(0)) != 0 {
- i++
- if i+1 > len(hp.plist) {
- if o < 100_000_000_000 {
- //hp.buildPrime(l * 1_000)
- o += 5_000_000
- hp.buildPrime(5_000_000, o)
- i = 0
- } else {
- return []int{}
- }
- }
- nextPrime = big.NewInt(int64(hp.plist[i]))
- } else {
- s = append(s, int(nextPrime.Int64()))
- n.Div(n, nextPrime)
- if n.Cmp(big.NewInt(1)) == 0 {
- break
- } else if n.ProbablyPrime(j) {
- s = append(s, int(n.Int64()))
- break
- }
- }
- }
- }
- return s
-}
-
-type homePrime struct {
- pmap []bool
- plist []int
}
diff --git a/challenge-168/pokgopun/go/homeprime/homeprime.go b/challenge-168/pokgopun/go/homeprime/homeprime.go
new file mode 100644
index 0000000000..48f56c43c6
--- /dev/null
+++ b/challenge-168/pokgopun/go/homeprime/homeprime.go
@@ -0,0 +1,97 @@
+/*
+You are given an integer greater than 1.
+
+Write a script to find the home prime of the given number.
+
+In number theory, the home prime HP(n) of an integer n greater than 1 is the prime number obtained by repeatedly factoring the increasing concatenation of prime factors including repetitions.
+*/
+package homeprime
+
+import (
+ "log"
+ "math/big"
+
+ "github.com/jbarham/primegen"
+)
+
+type abstractPrimegen struct {
+ nextUint64 func() uint64
+ reset func()
+}
+
+func (apg abstractPrimegen) Next() *big.Int {
+ return new(big.Int).SetUint64(apg.nextUint64())
+}
+func (apg abstractPrimegen) Reset() {
+ apg.reset()
+}
+
+type bigPrimeGenerator interface {
+ Next() *big.Int
+ Reset()
+}
+type ppFactorizer struct {
+ pg bigPrimeGenerator
+}
+
+func (ppf ppFactorizer) factor(n *big.Int) (s []*big.Int) {
+ d := new(big.Int).Set(ppf.pg.Next())
+ for {
+ if new(big.Int).Mod(n, d).Cmp(big.NewInt(0)) != 0 {
+ d.Set(ppf.pg.Next())
+ } else {
+ s = append(s, new(big.Int).Set(d))
+ n.Div(n, d)
+ if n.Cmp(big.NewInt(1)) == 0 {
+ break
+ } else if n.ProbablyPrime(0) {
+ s = append(s, n)
+ break
+ }
+ }
+ }
+ ppf.pg.Reset()
+ return s
+}
+
+type homePrime struct {
+ n, val *big.Int
+ f interface {
+ factor(*big.Int) []*big.Int
+ }
+}
+
+func (hp homePrime) String() string {
+ return hp.val.String()
+}
+func (hp *homePrime) resolve() *homePrime {
+ if hp.n.Cmp(big.NewInt(2)) == -1 {
+ log.Fatal("input must be greater than 1")
+ } else if hp.n.Cmp(big.NewInt(49)) == 0 || hp.n.Cmp(big.NewInt(77)) == 0 {
+ hp.val = new(big.Int).SetInt64(-1)
+ return hp
+ }
+ hp.val = new(big.Int).Set(hp.n)
+ for !hp.val.ProbablyPrime(0) {
+ //hp.val.SetString(strings.ReplaceAll(hp.f.factor(hp.val), " ", ""), 10)
+ var str string
+ for _, v := range hp.f.factor(hp.val) {
+ str += v.String()
+ }
+ hp.val.SetString(str, 10)
+ //fmt.Println(hp)
+ }
+ return hp
+}
+func NewHomePrime(n *big.Int) *homePrime {
+ pg := primegen.New()
+ var apg abstractPrimegen
+ apg.nextUint64 = pg.Next
+ apg.reset = pg.Reset
+ var ppf ppFactorizer
+ ppf.pg = apg
+ var hp homePrime
+ hp.f = ppf
+ hp.n = new(big.Int).Set(n)
+ return hp.resolve()
+}
diff --git a/challenge-168/pokgopun/go/homeprime/homeprime_test.go b/challenge-168/pokgopun/go/homeprime/homeprime_test.go
new file mode 100644
index 0000000000..e0c130c962
--- /dev/null
+++ b/challenge-168/pokgopun/go/homeprime/homeprime_test.go
@@ -0,0 +1,18 @@
+package homeprime
+
+import (
+ "math/big"
+ "strings"
+ "testing"
+)
+
+const series string = "2, 3, 211, 5, 23, 7, 3331113965338635107, 311, 773, 11, 223, 13, 13367, 1129, 31636373, 17, 233, 19, 3318308475676071413, 37, 211, 23, 331319, 773, 3251, 13367, 227, 29, 547, 31, 241271, 311, 31397, 1129, 71129, 37, 373, 313, 3314192745739, 41, 379, 43, 22815088913, 3411949, 223, 47, 6161791591356884791277, -1"
+
+func TestNewHomePrime(t *testing.T) {
+ for i, ans := range strings.Split(series, ", ") {
+ res := NewHomePrime(new(big.Int).SetInt64(int64(i) + 2)).String()
+ if res != ans {
+ t.Error("incorrect result: expected " + ans + ", got " + res)
+ }
+ }
+}
diff --git a/challenge-168/pokgopun/go/perrinprime/perrinprime.go b/challenge-168/pokgopun/go/perrinprime/perrinprime.go
new file mode 100644
index 0000000000..410970b8ca
--- /dev/null
+++ b/challenge-168/pokgopun/go/perrinprime/perrinprime.go
@@ -0,0 +1,51 @@
+/*
+The Perrin sequence is defined to start with [3, 0, 2]; after that, term N is the sum of terms N-2 and N-3. (So it continues 3, 2, 5, 5, 7, ….)
+
+A Perrin prime is a number in the Perrin sequence which is also a prime number.
+
+Calculate the first 13 Perrin Primes.
+
+f(13) = [2, 3, 5, 7, 17, 29, 277, 367, 853, 14197, 43721, 1442968193, 792606555396977]
+*/
+package perrinprime
+
+import (
+ "log"
+ "math/big"
+ "sort"
+ "strconv"
+)
+
+type perrinPrime struct {
+ big.Int
+ base [3]uint
+ vals []uint
+}
+
+func NewPerrinPrime(n int) (pp perrinPrime) {
+ if n < 1 {
+ log.Fatal("must be greater than 1")
+ }
+ pp.base = [3]uint{3, 0, 2}
+ vals := map[uint]struct{}{}
+ for i := 0; i < 1_000_000 && len(vals) < n; i++ {
+ if pp.SetInt64(int64(pp.base[0])).ProbablyPrime(0) {
+ vals[pp.base[0]] = struct{}{}
+ }
+ pp.base = [3]uint{pp.base[1], pp.base[2], pp.base[0] + pp.base[1]}
+ }
+ for k := range vals {
+ pp.vals = append(pp.vals, k)
+ }
+ sort.SliceStable(pp.vals, func(i, j int) bool {
+ return pp.vals[i] < pp.vals[j]
+ })
+ return pp
+}
+func (pp perrinPrime) String() string {
+ var str string
+ for _, v := range pp.vals {
+ str += ", " + strconv.FormatUint(uint64(v), 10)
+ }
+ return str[2:]
+}
diff --git a/challenge-168/pokgopun/go/perrinprime/perrinprime_test.go b/challenge-168/pokgopun/go/perrinprime/perrinprime_test.go
new file mode 100644
index 0000000000..917b7ba9a8
--- /dev/null
+++ b/challenge-168/pokgopun/go/perrinprime/perrinprime_test.go
@@ -0,0 +1,11 @@
+package perrinprime
+
+import "testing"
+
+func TestNewPerrinPrime(t *testing.T) {
+ res := NewPerrinPrime(13).String()
+ ans := "2, 3, 5, 7, 17, 29, 277, 367, 853, 14197, 43721, 1442968193, 792606555396977"
+ if res != ans {
+ t.Error("incorrect result: expected " + ans + ", got " + res)
+ }
+}
diff --git a/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/.gitignore b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/.gitignore
new file mode 100644
index 0000000000..3ee7710113
--- /dev/null
+++ b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/.gitignore
@@ -0,0 +1,5 @@
+_*
+6.out
+*.6
+primes
+primespeed
diff --git a/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/LICENSE b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/LICENSE
new file mode 100644
index 0000000000..c4642a0d3e
--- /dev/null
+++ b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 John Barham
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/README.md b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/README.md
new file mode 100644
index 0000000000..24e32cecb9
--- /dev/null
+++ b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/README.md
@@ -0,0 +1,23 @@
+# primegen
+
+*primegen* is a Go package that generates prime numbers in order using the Sieve
+of Atkin instead of the traditional Sieve of Eratosthenes.
+
+It is a relatively straightforward port of D. J. Bernstein's
+[original C implementation](http://cr.yp.to/primegen.html) but makes use of
+Go's concurrency features which should make it faster on multi-core CPUs.
+
+Do `go get github.com/jbarham/primegen` to install the package.
+
+View the package documentation online at
+https://pkg.go.dev/github.com/jbarham/primegen
+or on the command line by running `go doc github.com/jbarham/primegen`.
+
+The repository includes two additional programs that illustrate usage of the
+primegen package:
+
+1. primes, which writes prime numbers to standard out
+2. primespeed, which prints the time taken to generate the first 50,847,534
+ prime numbers
+
+John Barham, [Wombat Software](https://www.wombatsoftware.com/)
diff --git a/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/count.go b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/count.go
new file mode 100644
index 0000000000..b905b06deb
--- /dev/null
+++ b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/count.go
@@ -0,0 +1,73 @@
+package primegen
+
+var pop = []uint32{
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8}
+
+// Count returns the number of prime numbers from the generator's current
+// position up to x.
+func (pg *Primegen) Count(x uint64) uint64 {
+ var count uint64 = 0
+ var smallcount, bits uint32
+
+ for {
+ for pg.num != 0 {
+ if pg.p[pg.num-1] >= x {
+ return count
+ }
+ count++
+ pg.num--
+ }
+
+ smallcount = 0
+ pos := pg.pos
+ for (pos < _B32) && (pg.base+1920 < x) {
+ for j := 0; j < 16; j++ {
+ bits = ^pg.buf[j][pos]
+ smallcount += pop[bits&255]
+ bits >>= 8
+ smallcount += pop[bits&255]
+ bits >>= 8
+ smallcount += pop[bits&255]
+ bits >>= 8
+ smallcount += pop[bits&255]
+ }
+ pg.base += 1920
+ pos++
+ }
+ pg.pos = pos
+ count += uint64(smallcount)
+
+ if pos == _B32 {
+ for pg.base+_B*60 < x {
+ pg.sieve()
+ pg._L += _B
+
+ smallcount = 0
+ for j := 0; j < 16; j++ {
+ for pos = 0; pos < _B32; pos++ {
+ bits = ^pg.buf[j][pos]
+ smallcount += pop[bits&255]
+ bits >>= 8
+ smallcount += pop[bits&255]
+ bits >>= 8
+ smallcount += pop[bits&255]
+ bits >>= 8
+ smallcount += pop[bits&255]
+ }
+ }
+ count += uint64(smallcount)
+ pg.base += _B * 60
+ }
+ }
+
+ pg.fill()
+ }
+ return count // Shouldn't get here.
+}
diff --git a/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/fill.go b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/fill.go
new file mode 100644
index 0000000000..479d86b603
--- /dev/null
+++ b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/fill.go
@@ -0,0 +1,104 @@
+package primegen
+
+func (pg *Primegen) fill() {
+ var bits0, bits1, bits2, bits3, bits4, bits5, bits6, bits7 uint32
+ var bits8, bits9, bits10, bits11, bits12, bits13, bits14, bits15 uint32
+
+ i := pg.pos
+ if i == _B32 {
+ pg.sieve()
+ pg._L += _B
+ i = 0
+ }
+ pg.pos = i + 1
+
+ bits0 = ^pg.buf[0][i]
+ bits1 = ^pg.buf[1][i]
+ bits2 = ^pg.buf[2][i]
+ bits3 = ^pg.buf[3][i]
+ bits4 = ^pg.buf[4][i]
+ bits5 = ^pg.buf[5][i]
+ bits6 = ^pg.buf[6][i]
+ bits7 = ^pg.buf[7][i]
+ bits8 = ^pg.buf[8][i]
+ bits9 = ^pg.buf[9][i]
+ bits10 = ^pg.buf[10][i]
+ bits11 = ^pg.buf[11][i]
+ bits12 = ^pg.buf[12][i]
+ bits13 = ^pg.buf[13][i]
+ bits14 = ^pg.buf[14][i]
+ bits15 = ^pg.buf[15][i]
+
+ base := pg.base + 1920
+ pg.base = base
+
+ pg.num = 0
+
+ for mask := uint32(0x80000000); mask != 0; mask >>= 1 {
+ base -= 60
+ if bits15&mask != 0 {
+ pg.p[pg.num] = base + 59
+ pg.num++
+ }
+ if bits14&mask != 0 {
+ pg.p[pg.num] = base + 53
+ pg.num++
+ }
+ if bits13&mask != 0 {
+ pg.p[pg.num] = base + 49
+ pg.num++
+ }
+ if bits12&mask != 0 {
+ pg.p[pg.num] = base + 47
+ pg.num++
+ }
+ if bits11&mask != 0 {
+ pg.p[pg.num] = base + 43
+ pg.num++
+ }
+ if bits10&mask != 0 {
+ pg.p[pg.num] = base + 41
+ pg.num++
+ }
+ if bits9&mask != 0 {
+ pg.p[pg.num] = base + 37
+ pg.num++
+ }
+ if bits8&mask != 0 {
+ pg.p[pg.num] = base + 31
+ pg.num++
+ }
+ if bits7&mask != 0 {
+ pg.p[pg.num] = base + 29
+ pg.num++
+ }
+ if bits6&mask != 0 {
+ pg.p[pg.num] = base + 23
+ pg.num++
+ }
+ if bits5&mask != 0 {
+ pg.p[pg.num] = base + 19
+ pg.num++
+ }
+ if bits4&mask != 0 {
+ pg.p[pg.num] = base + 17
+ pg.num++
+ }
+ if bits3&mask != 0 {
+ pg.p[pg.num] = base + 13
+ pg.num++
+ }
+ if bits2&mask != 0 {
+ pg.p[pg.num] = base + 11
+ pg.num++
+ }
+ if bits1&mask != 0 {
+ pg.p[pg.num] = base + 7
+ pg.num++
+ }
+ if bits0&mask != 0 {
+ pg.p[pg.num] = base + 1
+ pg.num++
+ }
+ }
+}
diff --git a/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/primegen.go b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/primegen.go
new file mode 100644
index 0000000000..0a69312525
--- /dev/null
+++ b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/primegen.go
@@ -0,0 +1,137 @@
+// The primegen package generates prime numbers in order. It uses the Sieve of
+// Atkin instead of the traditional Sieve of Eratosthenes.
+//
+// The primegen Go package is a port of D. J. Bernstein's original implementation
+// in C (http://cr.yp.to/primegen.html).
+package primegen
+
+import (
+ "bufio"
+ "io"
+)
+
+const (
+ _PRIMEGEN_WORDS = 8192 // Assumes 32K L1 data cache
+ _B32 = _PRIMEGEN_WORDS
+ _B = _PRIMEGEN_WORDS * 32
+)
+
+type Primegen struct {
+ buf [16][]uint32
+ p [512]uint64 /* p[num-1] ... p[0], in that order */
+ num int
+ pos int /* next entry to use in buf; _PRIMEGEN_WORDS to restart */
+ base uint64
+ _L uint64
+}
+
+// New returns a new primegen.Primegen prime number generator.
+func New() *Primegen {
+ pg := new(Primegen)
+ for i := 0; i < len(pg.buf); i++ {
+ pg.buf[i] = make([]uint32, _PRIMEGEN_WORDS)
+ }
+ pg.Reset()
+ return pg
+}
+
+// Reset resets the generator at the first prime number.
+func (pg *Primegen) Reset() {
+ pg._L = 1
+ pg.base = 60
+
+ pg.pos = _PRIMEGEN_WORDS
+
+ pg.p[0] = 59
+ pg.p[1] = 53
+ pg.p[2] = 47
+ pg.p[3] = 43
+ pg.p[4] = 41
+ pg.p[5] = 37
+ pg.p[6] = 31
+ pg.p[7] = 29
+ pg.p[8] = 23
+ pg.p[9] = 19
+ pg.p[10] = 17
+ pg.p[11] = 13
+ pg.p[12] = 11
+ pg.p[13] = 7
+ pg.p[14] = 5
+ pg.p[15] = 3
+ pg.p[16] = 2
+
+ pg.num = 17
+}
+
+// Peek returns the next prime number, without advancing the generator.
+func (pg *Primegen) Peek() uint64 {
+ for pg.num == 0 {
+ pg.fill()
+ }
+
+ return pg.p[pg.num-1]
+}
+
+// Next returns the next prime number and advances the generator.
+func (pg *Primegen) Next() uint64 {
+ p := pg.Peek()
+ pg.num--
+ return p
+}
+
+// SkipTo advances the generator to generate prime numbers >= x.
+func (pg *Primegen) SkipTo(x uint64) {
+ for {
+ for pg.num != 0 {
+ if pg.p[pg.num-1] >= x {
+ return
+ }
+ pg.num--
+ }
+
+ pos := pg.pos
+ for (pos < _B32) && (pg.base+1920 < x) {
+ pg.base += 1920
+ pos++
+ }
+ pg.pos = pos
+ if pos == _B32 {
+ for pg.base+_B*60 < x {
+ pg._L += _B
+ pg.base += _B * 60
+ }
+ }
+
+ pg.fill()
+ }
+}
+
+const ndigits = 32
+
+// Write efficiently writes the list of prime numbers between low and high,
+// separated by newline, to w.
+func Write(w io.Writer, low, high uint64) (err error) {
+ var i int
+ digits := make([]byte, 32)
+ digits[ndigits-1] = '\n'
+
+ sieve := New()
+ sieve.SkipTo(low)
+ x := sieve.Next()
+ b := bufio.NewWriter(w)
+ for x < high {
+ xx := x
+ for i = ndigits - 2; i > 0; i-- {
+ digits[i] = '0' + byte(xx%10)
+ if xx < 10 {
+ break
+ }
+ xx /= 10
+ }
+ if _, err = b.Write(digits[i:]); err != nil {
+ return err
+ }
+ x = sieve.Next()
+ }
+ return b.Flush()
+}
diff --git a/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/sieve.go b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/sieve.go
new file mode 100644
index 0000000000..b4973dde1f
--- /dev/null
+++ b/challenge-168/pokgopun/go/vendor/github.com/jbarham/primegen/sieve.go
@@ -0,0 +1,530 @@
+package primegen
+
+import (
+ "runtime"
+ "sync"
+)
+
+var two = [32]uint32{
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080,
+ 0x00000100, 0x00000200, 0x00000400, 0x00000800,
+ 0x00001000, 0x00002000, 0x00004000, 0x00008000,
+ 0x00010000, 0x00020000, 0x00040000, 0x00080000,
+ 0x00100000, 0x00200000, 0x00400000, 0x00800000,
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+}
+
+func doit4(a []uint32, x, y int, start int64) {
+ var i, i0, y0 int
+
+ x += x
+ x += 15
+ y += 15
+
+ start += 1000000000
+ for start < 0 {
+ start += int64(x)
+ x += 30
+ }
+ start -= 1000000000
+ i = int(start)
+
+ for i < _B {
+ i += x
+ x += 30
+ }
+
+ for {
+ x -= 30
+ if x <= 15 {
+ return
+ }
+ i -= x
+
+ for i < 0 {
+ i += y
+ y += 30
+ }
+
+ i0 = i
+ y0 = y
+ for i < _B {
+ pos := uint32(i) >> 5
+ data := uint32(i) & 31
+ i += y
+ y += 30
+ bits := a[pos]
+ data = two[data]
+ bits ^= data
+ a[pos] = bits
+ }
+ i = i0
+ y = y0
+ }
+}
+
+func doit6(a []uint32, x, y int, start int64) {
+ var i, i0, y0 int
+
+ x += 5
+ y += 15
+
+ start += 1000000000
+ for start < 0 {
+ start += int64(x)
+ x += 10
+ }
+ start -= 1000000000
+ i = int(start)
+ for i < _B {
+ i += x
+ x += 10
+ }
+
+ for {
+ x -= 10
+ if x <= 5 {
+ return
+ }
+ i -= x
+
+ for i < 0 {
+ i += y
+ y += 30
+ }
+
+ i0 = i
+ y0 = y
+ for i < _B {
+ pos := uint32(i) >> 5
+ data := uint32(i) & 31
+ i += y
+ y += 30
+ bits := a[pos]
+ data = two[data]
+ bits ^= data
+ a[pos] = bits
+ }
+ i = i0
+ y = y0
+ }
+}
+
+func doit12(a []uint32, x, y int, start int64) {
+ var i, i0, y0 int
+
+ x += 5
+
+ start += 1000000000
+ for start < 0 {
+ start += int64(x)
+ x += 10
+ }
+ start -= 1000000000
+ i = int(start)
+ for i < 0 {
+ i += x
+ x += 10
+ }
+
+ y += 15
+ x += 10
+
+ for {
+ for i >= _B {
+ if x <= y {
+ return
+ }
+ i -= y
+ y += 30
+ }
+ i0 = i
+ y0 = y
+ for (i >= 0) && (y < x) {
+ pos := uint32(i) >> 5
+ data := uint32(i) & 31
+ i -= y
+ y += 30
+ bits := a[pos]
+ data = two[data]
+ bits ^= data
+ a[pos] = bits
+ }
+ i = i0
+ y = y0
+ i += x - 10
+ x += 10
+ }
+}
+
+var deltainverse = [60]int{
+ -1, _B32 * 0, -1, -1, -1, -1, -1, _B32 * 1, -1, -1, -1, _B32 * 2, -1, _B32 * 3, -1,
+ -1, -1, _B32 * 4, -1, _B32 * 5, -1, -1, -1, _B32 * 6, -1, -1, -1, -1, -1, _B32 * 7,
+ -1, _B32 * 8, -1, -1, -1, -1, -1, _B32 * 9, -1, -1, -1, _B32 * 10, -1, _B32 * 11, -1,
+ -1, -1, _B32 * 12, -1, _B32 * 13, -1, -1, -1, _B32 * 14, -1, -1, -1, -1, -1, _B32 * 15,
+}
+
+func squarefree1big(buf [16][]uint32, base uint64, q uint32, qq uint64) {
+ var i uint64
+ bound := base + 60*_B
+
+ for qq < bound {
+ if bound < 2000000000 {
+ i = qq - uint64(uint32(base)%uint32(qq))
+ } else {
+ i = qq - (base % qq)
+ }
+ if (i & 1) == 0 {
+ i += qq
+ }
+
+ if i < _B*60 {
+ pos := uint32(i)
+ n := deltainverse[pos%60]
+ if n >= 0 {
+ pos /= 60
+ idx := n + int(pos>>5)
+ buf[idx/_B32][idx%_B32] |= two[pos&31]
+ }
+ }
+
+ qq += uint64(q)
+ q += 1800
+ }
+}
+
+func squarefree1(buf [16][]uint32, L uint64, q uint32) {
+ var i uint32
+
+ base := 60 * L
+ qq := q * q
+ q = 60*q + 900
+
+ for qq < _B*60 {
+ if base < 2000000000 {
+ i = qq - (uint32(base) % qq)
+ } else {
+ i = qq - uint32(base%uint64(qq))
+ }
+ if (i & 1) == 0 {
+ i += qq
+ }
+
+ if i < _B*60 {
+ qqhigh := qq / 60
+ ilow := i % 60
+ ihigh := i / 60
+
+ qqhigh += qqhigh
+ for ihigh < _B {
+ n := deltainverse[ilow]
+ if n >= 0 {
+ idx := n + int(ihigh>>5)
+ buf[idx/_B32][idx%_B32] |= two[ihigh&31]
+ }
+
+ ilow += 2
+ ihigh += qqhigh
+ if ilow >= 60 {
+ ilow -= 60
+ ihigh += 1
+ }
+ }
+ }
+
+ qq += q
+ q += 1800
+ }
+
+ squarefree1big(buf, base, q, uint64(qq))
+}
+
+func squarefree49big(buf [16][]uint32, base uint64, q uint32, qq uint64) {
+ var i uint64
+ bound := base + 60*_B
+
+ for qq < bound {
+ if bound < 2000000000 {
+ i = qq - uint64(uint32(base)%uint32(qq))
+ } else {
+ i = qq - (base % qq)
+ }
+ if (i & 1) == 0 {
+ i += qq
+ }
+
+ if i < _B*60 {
+ pos := uint32(i)
+ n := deltainverse[pos%60]
+ if n >= 0 {
+ pos /= 60
+ idx