func check_patition(startindex, prev int) int { var count int = 0 for i := startindex; i < nums.Len(); i++ { var number int = 0 for j := startindex; j <= i; j++ { number = number*10 + nums[j] } if number < prev { continue } if !mathutil.IsPrime(uint32(number)) { continue } if i == nums.Len()-1 { return count + 1 } count += check_patition(i+1, number) } return count }
func main() { pp := mathutil.PrimorialProductsUint32(0, math.MaxUint32, 32) sort.Sort(sortutil.Uint32Slice(pp)) var bestN, bestD uint32 = 1, 1 order, checks := 0, 0 var ixDirty uint32 m := make([]byte, math.MaxUint32>>3) for _, n := range pp { for i := range m[:ixDirty+1] { m[i] = 0 } ixDirty = 0 checks++ limit0 := mathutil.QScaleUint32(n, bestN, bestD) if limit0 > math.MaxUint32 { panic(0) } limit := uint32(limit0) n64 := uint64(n) hi := n64 >> 1 hits := uint32(0) check := true fmt.Printf("\r%10d %d/%d", n, checks, len(pp)) t0 := time.Now() for i := uint64(0); i < hi; i++ { sq := uint32(i * i % n64) ix := sq >> 3 msk := byte(1 << (sq & 7)) if m[ix]&msk == 0 { hits++ if hits >= limit { check = false break } } m[ix] |= msk if ix > ixDirty { ixDirty = ix } } adjPrime := ".." // Composite before if mathutil.IsPrime(n - 1) { adjPrime = "P." // Prime before } switch mathutil.IsPrime(n + 1) { case true: adjPrime += "P" // Prime after case false: adjPrime += "." // Composite after } if check && mathutil.QCmpUint32(hits, n, bestN, bestD) < 0 { order++ d := time.Since(t0) bestN, bestD = hits, n q := float64(hits) / float64(n) fmt.Printf( "\r%2s #%03d %d %d %.2f %.2E %s %s\n", adjPrime, order, n, hits, 1/q, q, d, time.Now().Format("15:04:05"), ) } } }