Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
35
Task/Hamming-numbers/Go/hamming-numbers-1.go
Normal file
35
Task/Hamming-numbers/Go/hamming-numbers-1.go
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
func min(a, b *big.Int) *big.Int {
|
||||
if a.Cmp(b) < 0 {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func hamming(n int) []*big.Int {
|
||||
h := make([]*big.Int, n)
|
||||
h[0] = big.NewInt(1)
|
||||
two, three, five := big.NewInt(2), big.NewInt(3), big.NewInt(5)
|
||||
next2, next3, next5 := big.NewInt(2), big.NewInt(3), big.NewInt(5)
|
||||
i, j, k := 0, 0, 0
|
||||
for m := 1; m < len(h); m++ {
|
||||
h[m] = new(big.Int).Set(min(next2, min(next3, next5)))
|
||||
if h[m].Cmp(next2) == 0 { i++; next2.Mul( two, h[i]) }
|
||||
if h[m].Cmp(next3) == 0 { j++; next3.Mul(three, h[j]) }
|
||||
if h[m].Cmp(next5) == 0 { k++; next5.Mul( five, h[k]) }
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func main() {
|
||||
h := hamming(1e6)
|
||||
fmt.Println(h[:20])
|
||||
fmt.Println(h[1691-1])
|
||||
fmt.Println(h[len(h)-1])
|
||||
}
|
||||
93
Task/Hamming-numbers/Go/hamming-numbers-2.go
Normal file
93
Task/Hamming-numbers/Go/hamming-numbers-2.go
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"math/big"
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
// print the whole sequence or just one element?
|
||||
|
||||
seqMode = flag.Bool("s", false, "sequence mode")
|
||||
// precomputed base-2 logarithms for 3 and 5
|
||||
lg3, lg5 float64 = math.Log2(3), math.Log2(5)
|
||||
|
||||
// state of the three multiplied sequences
|
||||
front = [3]cursor{
|
||||
{0, 0, 1}, // 2
|
||||
{1, 0, lg3}, // 3
|
||||
{2, 0, lg5}, // 5
|
||||
}
|
||||
|
||||
// table for dynamic-programming stored results
|
||||
table [][3]int16
|
||||
)
|
||||
|
||||
type cursor struct {
|
||||
f int // index (0, 1, 2) corresponding to factor (2, 3, 5)
|
||||
i int // index into table for the entry being multiplied
|
||||
lg float64 // base-2 logarithm of the multiple (for ordering)
|
||||
}
|
||||
|
||||
func (c *cursor) val() [3]int16 {
|
||||
x := table[c.i]
|
||||
x[c.f]++ // multiply by incrementing the exponent
|
||||
return x
|
||||
}
|
||||
|
||||
func (c *cursor) advance() {
|
||||
c.i++
|
||||
// skip entries that would produce duplicates
|
||||
for (c.f < 2 && table[c.i][2] > 0) || (c.f < 1 && table[c.i][1] > 0) {
|
||||
c.i++
|
||||
}
|
||||
x := c.val()
|
||||
c.lg = float64(x[0]) + lg3*float64(x[1]) + lg5*float64(x[2])
|
||||
}
|
||||
|
||||
func step() {
|
||||
table = append(table, front[0].val())
|
||||
front[0].advance()
|
||||
// re-establish sorted order
|
||||
if front[0].lg > front[1].lg {
|
||||
front[0], front[1] = front[1], front[0]
|
||||
if front[1].lg > front[2].lg {
|
||||
front[1], front[2] = front[2], front[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
func show(elem [3]int16) {
|
||||
z := big.NewInt(1)
|
||||
for i, base := range []int64{2, 3, 5} {
|
||||
b := big.NewInt(base)
|
||||
x := big.NewInt(int64(elem[i]))
|
||||
z.Mul(z, b.Exp(b, x, nil))
|
||||
}
|
||||
fmt.Println(z)
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.SetPrefix(os.Args[0] + ": ")
|
||||
log.SetOutput(os.Stderr)
|
||||
flag.Parse()
|
||||
if flag.NArg() != 1 {
|
||||
log.Fatalln("need one positive integer argument")
|
||||
}
|
||||
var ordinal int // ordinal of last sequence element to compute
|
||||
_, err := fmt.Sscan(flag.Arg(0), &ordinal)
|
||||
if err != nil || ordinal <= 0 {
|
||||
log.Fatalln("argument must be a positive integer")
|
||||
}
|
||||
table = make([][3]int16, 1, ordinal)
|
||||
for i, n := 1, ordinal; i < n; i++ {
|
||||
if *seqMode {
|
||||
show(table[i-1])
|
||||
}
|
||||
step()
|
||||
}
|
||||
show(table[ordinal-1])
|
||||
}
|
||||
110
Task/Hamming-numbers/Go/hamming-numbers-3.go
Normal file
110
Task/Hamming-numbers/Go/hamming-numbers-3.go
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
// Hamming project main.go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
)
|
||||
|
||||
type lazyList struct {
|
||||
head *big.Int
|
||||
tail *lazyList
|
||||
contf func() *lazyList
|
||||
}
|
||||
|
||||
func (oll *lazyList) next() *lazyList {
|
||||
if oll.contf != nil { // not thread-safe
|
||||
oll.tail = oll.contf()
|
||||
oll.contf = nil
|
||||
}
|
||||
return oll.tail
|
||||
}
|
||||
|
||||
func merge(a *lazyList, b *lazyList) *lazyList {
|
||||
rslt := new(lazyList)
|
||||
x := a.head
|
||||
y := b.head
|
||||
if x.Cmp(y) < 0 {
|
||||
rslt.head = x
|
||||
rslt.contf = func() *lazyList {
|
||||
return merge(a.next(), b)
|
||||
}
|
||||
} else {
|
||||
rslt.head = y
|
||||
rslt.contf = func() *lazyList {
|
||||
return merge(a, b.next())
|
||||
}
|
||||
}
|
||||
return rslt
|
||||
}
|
||||
|
||||
func llmult(m *big.Int, ll *lazyList) *lazyList {
|
||||
rslt := new(lazyList)
|
||||
rslt.head = new(big.Int).Set(big.NewInt(0)).Mul(m, ll.head)
|
||||
rslt.contf = func() *lazyList {
|
||||
return llmult(m, ll.next())
|
||||
}
|
||||
return rslt
|
||||
}
|
||||
|
||||
func u(s *lazyList, n *big.Int) *lazyList {
|
||||
rslt := new(lazyList)
|
||||
cr := new(lazyList)
|
||||
cr.head = big.NewInt(1)
|
||||
cr.contf = func() *lazyList {
|
||||
return rslt
|
||||
}
|
||||
if s == nil {
|
||||
rslt = llmult(n, cr)
|
||||
} else {
|
||||
rslt = merge(s, llmult(n, cr))
|
||||
}
|
||||
return rslt
|
||||
}
|
||||
|
||||
func Hamming() func() *big.Int {
|
||||
prms := []int64{5, 3, 2}
|
||||
curr := new(lazyList)
|
||||
curr.head = big.NewInt(1)
|
||||
curr.contf = func() *lazyList {
|
||||
var r *lazyList = nil
|
||||
for _, v := range prms {
|
||||
r = u(r, big.NewInt(v))
|
||||
}
|
||||
return r
|
||||
}
|
||||
return func() *big.Int {
|
||||
temp := curr
|
||||
curr = curr.next()
|
||||
return temp.head
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
n := 1000000
|
||||
|
||||
hamiter := Hamming()
|
||||
rarr := make([]*big.Int, 20)
|
||||
for i, _ := range rarr {
|
||||
rarr[i] = hamiter()
|
||||
}
|
||||
fmt.Println(rarr)
|
||||
|
||||
hamiter = Hamming()
|
||||
for i := 1; i < 1691; i++ {
|
||||
hamiter()
|
||||
}
|
||||
fmt.Println(hamiter())
|
||||
|
||||
strt := time.Now()
|
||||
|
||||
hamiter = Hamming()
|
||||
for i := 1; i < n; i++ {
|
||||
hamiter()
|
||||
}
|
||||
rslt := hamiter()
|
||||
|
||||
end := time.Now()
|
||||
fmt.Printf("Found the %vth Hamming number as %v in %v.\r\n", n, rslt.String(), end.Sub(strt))
|
||||
}
|
||||
148
Task/Hamming-numbers/Go/hamming-numbers-4.go
Normal file
148
Task/Hamming-numbers/Go/hamming-numbers-4.go
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"time"
|
||||
)
|
||||
|
||||
// constants as expanded integers to minimize round-off errors, and
|
||||
// reduce execution time using integer operations not float...
|
||||
const cLAA2 uint64 = 35184372088832 // 2.0f64.ln() * 2.0f64.powi(45)).round() as u64;
|
||||
const cLBA2 uint64 = 55765910372219 // 3.0f64.ln() / 2.0f64.ln() * 2.0f64.powi(45)).round() as u64;
|
||||
const cLCA2 uint64 = 81695582054030 // 5.0f64.ln() / 2.0f64.ln() * 2.0f64.powi(45)).round() as u64;
|
||||
|
||||
type logelm struct { // log representation of an element with only allowable powers
|
||||
exp2 uint16
|
||||
exp3 uint16
|
||||
exp5 uint16
|
||||
logr uint64 // log representation used for comparison only - not exact
|
||||
}
|
||||
|
||||
func (self *logelm) lte(othr *logelm) bool {
|
||||
if self.logr <= othr.logr {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
func (self *logelm) mul2() logelm {
|
||||
return logelm{
|
||||
exp2: self.exp2 + 1,
|
||||
exp3: self.exp3,
|
||||
exp5: self.exp5,
|
||||
logr: self.logr + cLAA2,
|
||||
}
|
||||
}
|
||||
func (self *logelm) mul3() logelm {
|
||||
return logelm{
|
||||
exp2: self.exp2,
|
||||
exp3: self.exp3 + 1,
|
||||
exp5: self.exp5,
|
||||
logr: self.logr + cLBA2,
|
||||
}
|
||||
}
|
||||
func (self *logelm) mul5() logelm {
|
||||
return logelm{
|
||||
exp2: self.exp2,
|
||||
exp3: self.exp3,
|
||||
exp5: self.exp5 + 1,
|
||||
logr: self.logr + cLCA2,
|
||||
}
|
||||
}
|
||||
|
||||
func log_nodups_hamming(n uint) *big.Int {
|
||||
if n < 1 {
|
||||
panic("log_nodups_hamming: argument < 1!")
|
||||
}
|
||||
if n < 2 { // trivial case of first in sequence
|
||||
return big.NewInt(1)
|
||||
}
|
||||
if n > 1.2e15 {
|
||||
panic("log_nodups_hamming: argument too large!")
|
||||
}
|
||||
|
||||
one := logelm{}
|
||||
next5, merge := one.mul5(), one.mul3()
|
||||
next53, next532 := merge.mul3(), one.mul2()
|
||||
|
||||
g := make([]logelm, 1, 65536)
|
||||
g[0] = one // never used, just so append works
|
||||
h := make([]logelm, 1, 65536)
|
||||
h[0] = one // never used, just so append works
|
||||
|
||||
i, j := 1, 1
|
||||
for m := uint(1); m < n; m++ {
|
||||
cph := cap(h)
|
||||
if i >= cph/2 {
|
||||
nm := copy(h[0:i], h[i:])
|
||||
h = h[0:nm:cph]
|
||||
i = 0
|
||||
}
|
||||
if next532.lte(&merge) {
|
||||
h = append(h, next532)
|
||||
next532 = h[i].mul2()
|
||||
i++
|
||||
} else {
|
||||
h = append(h, merge)
|
||||
if next53.lte(&next5) {
|
||||
merge = next53
|
||||
next53 = g[j].mul3()
|
||||
j++
|
||||
} else {
|
||||
merge = next5
|
||||
next5 = next5.mul5()
|
||||
}
|
||||
cpg := cap(g)
|
||||
if j >= cpg/2 {
|
||||
nm := copy(g[0:j], g[j:])
|
||||
g = g[0:nm:cpg]
|
||||
j = 0
|
||||
}
|
||||
g = append(g, merge)
|
||||
}
|
||||
}
|
||||
|
||||
two, three, five := big.NewInt(2), big.NewInt(3), big.NewInt(5)
|
||||
o := h[len(h)-1] // convert last element to big integer...
|
||||
ob := big.NewInt(1)
|
||||
for i := uint16(0); i < o.exp2; i++ {
|
||||
ob.Mul(two, ob)
|
||||
}
|
||||
for i := uint16(0); i < o.exp3; i++ {
|
||||
ob.Mul(three, ob)
|
||||
}
|
||||
for i := uint16(0); i < o.exp5; i++ {
|
||||
ob.Mul(five, ob)
|
||||
}
|
||||
return ob
|
||||
}
|
||||
|
||||
func main() {
|
||||
n := uint(1e6)
|
||||
|
||||
rarr := make([]*big.Int, 20)
|
||||
for i, _ := range rarr {
|
||||
rarr[i] = log_nodumps_hamming(i)
|
||||
}
|
||||
fmt.Println(rarr)
|
||||
|
||||
fmt.Println(log_nodups_hamming(1691))
|
||||
|
||||
strt := time.Now()
|
||||
|
||||
rslt := log_nodups_hamming(n)
|
||||
|
||||
end := time.Now()
|
||||
|
||||
rs := rslt.String()
|
||||
lrs := len(rs)
|
||||
fmt.Printf("%v digits:\r\n", lrs)
|
||||
ndx := 0
|
||||
for ; ndx < lrs-100; ndx += 100 {
|
||||
fmt.Println(rs[ndx : ndx+100])
|
||||
}
|
||||
fmt.Println(rs[ndx:])
|
||||
|
||||
fmt.Printf("This last found the %vth hamming number in %v.\r\n", n, end.Sub(strt))
|
||||
}
|
||||
123
Task/Hamming-numbers/Go/hamming-numbers-5.go
Normal file
123
Task/Hamming-numbers/Go/hamming-numbers-5.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
type logrep struct {
|
||||
lg float64
|
||||
x2, x3, x5 uint32
|
||||
}
|
||||
type logreps []logrep
|
||||
|
||||
func (s logreps) Len() int { // necessary methods for sorting
|
||||
return len(s)
|
||||
}
|
||||
func (s logreps) Swap(i, j int) {
|
||||
s[i], s[j] = s[j], s[i]
|
||||
}
|
||||
func (s logreps) Less(i, j int) bool {
|
||||
return s[j].lg < s[i].lg // sort in decreasing order (reverse order compare)
|
||||
}
|
||||
|
||||
func nthHamming(n uint64) (uint32, uint32, uint32) {
|
||||
if n < 2 {
|
||||
if n < 1 {
|
||||
panic("nthHamming: argument is zero!")
|
||||
}
|
||||
return 0, 0, 0
|
||||
}
|
||||
const lb3 = 1.5849625007211561814537389439478 // math.Log2(3.0)
|
||||
const lb5 = 2.3219280948873623478703194294894 // math.Log2(5.0)
|
||||
fctr := 6.0 * lb3 * lb5
|
||||
crctn := math.Log2(math.Sqrt(30.0)) // from WP formula
|
||||
lgest := math.Pow(fctr*float64(n), 1.0/3.0) - crctn
|
||||
var frctn float64
|
||||
if n < 1000000000 {
|
||||
frctn = 0.509
|
||||
} else {
|
||||
frctn = 0.106
|
||||
}
|
||||
lghi := math.Pow(fctr*(float64(n)+frctn*lgest), 1.0/3.0) - crctn
|
||||
lglo := 2.0*lgest - lghi // and a lower limit of the upper "band"
|
||||
var count uint64 = 0
|
||||
bnd := make(logreps, 0) // give it one value so doubling size works
|
||||
klmt := uint32(lghi/lb5) + 1
|
||||
for k := uint32(0); k < klmt; k++ {
|
||||
p := float64(k) * lb5
|
||||
jlmt := uint32((lghi-p)/lb3) + 1
|
||||
for j := uint32(0); j < jlmt; j++ {
|
||||
q := p + float64(j)*lb3
|
||||
ir := lghi - q
|
||||
lg := q + math.Floor(ir) // current log value estimated
|
||||
count += uint64(ir) + 1
|
||||
if lg >= lglo {
|
||||
bnd = append(bnd, logrep{lg, uint32(ir), j, k})
|
||||
}
|
||||
}
|
||||
}
|
||||
if n > count {
|
||||
panic("nthHamming: band high estimate is too low!")
|
||||
}
|
||||
ndx := int(count - n)
|
||||
if ndx >= bnd.Len() {
|
||||
panic("nthHamming: band low estimate is too high!")
|
||||
}
|
||||
sort.Sort(bnd) // sort decreasing order due definition of Less above
|
||||
|
||||
rslt := bnd[ndx]
|
||||
return rslt.x2, rslt.x3, rslt.x5
|
||||
}
|
||||
|
||||
func convertTpl2BigInt(x2, x3, x5 uint32) *big.Int {
|
||||
result := big.NewInt(1)
|
||||
two := big.NewInt(2)
|
||||
three := big.NewInt(3)
|
||||
five := big.NewInt(5)
|
||||
for i := uint32(0); i < x2; i++ {
|
||||
result.Mul(result, two)
|
||||
}
|
||||
for i := uint32(0); i < x3; i++ {
|
||||
result.Mul(result, three)
|
||||
}
|
||||
for i := uint32(0); i < x5; i++ {
|
||||
result.Mul(result, five)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func main() {
|
||||
for i := 1; i <= 20; i++ {
|
||||
fmt.Printf("%v ", convertTpl2BigInt(nthHamming(uint64(i))))
|
||||
}
|
||||
fmt.Println()
|
||||
fmt.Println(convertTpl2BigInt(nthHamming(1691)))
|
||||
|
||||
strt := time.Now()
|
||||
x2, x3, x5 := nthHamming(uint64(1e6))
|
||||
end := time.Now()
|
||||
|
||||
fmt.Printf("2^%v times 3^%v times 5^%v\r\n", x2, x3, x5)
|
||||
lrslt := convertTpl2BigInt(x2, x3, x5)
|
||||
lgrslt := (float64(x2) + math.Log2(3.0)*float64(x3) +
|
||||
math.Log2(5.0)*float64(x5)) * math.Log10(2.0)
|
||||
exp := math.Floor(lgrslt)
|
||||
mant := math.Pow(10.0, lgrslt-exp)
|
||||
fmt.Printf("Approximately: %vE+%v\r\n", mant, exp)
|
||||
rs := lrslt.String()
|
||||
lrs := len(rs)
|
||||
fmt.Printf("%v digits:\r\n", lrs)
|
||||
if lrs <= 10000 {
|
||||
ndx := 0
|
||||
for ; ndx < lrs-100; ndx += 100 {
|
||||
fmt.Println(rs[ndx : ndx+100])
|
||||
}
|
||||
fmt.Println(rs[ndx:])
|
||||
}
|
||||
|
||||
fmt.Printf("This last found the %vth hamming number in %v.\r\n", uint64(1e6), end.Sub(strt))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue