main.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright (c) 2011 jnml. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build ignore
  5. // Let QRN be the number of quadratic residues of N. Let Q be QRN/N. From a
  6. // sorted list of primorial products < 2^32 find "record breakers". "Record
  7. // breaker" is N with new lowest Q.
  8. //
  9. // There are only 49 "record breakers" < 2^32.
  10. //
  11. // To run the example $ go run main.go
  12. package main
  13. import (
  14. "fmt"
  15. "math"
  16. "sort"
  17. "time"
  18. "github.com/cznic/mathutil"
  19. "github.com/cznic/sortutil"
  20. )
  21. func main() {
  22. pp := mathutil.PrimorialProductsUint32(0, math.MaxUint32, 32)
  23. sort.Sort(sortutil.Uint32Slice(pp))
  24. var bestN, bestD uint32 = 1, 1
  25. order, checks := 0, 0
  26. var ixDirty uint32
  27. m := make([]byte, math.MaxUint32>>3)
  28. for _, n := range pp {
  29. for i := range m[:ixDirty+1] {
  30. m[i] = 0
  31. }
  32. ixDirty = 0
  33. checks++
  34. limit0 := mathutil.QScaleUint32(n, bestN, bestD)
  35. if limit0 > math.MaxUint32 {
  36. panic(0)
  37. }
  38. limit := uint32(limit0)
  39. n64 := uint64(n)
  40. hi := n64 >> 1
  41. hits := uint32(0)
  42. check := true
  43. fmt.Printf("\r%10d %d/%d", n, checks, len(pp))
  44. t0 := time.Now()
  45. for i := uint64(0); i < hi; i++ {
  46. sq := uint32(i * i % n64)
  47. ix := sq >> 3
  48. msk := byte(1 << (sq & 7))
  49. if m[ix]&msk == 0 {
  50. hits++
  51. if hits >= limit {
  52. check = false
  53. break
  54. }
  55. }
  56. m[ix] |= msk
  57. if ix > ixDirty {
  58. ixDirty = ix
  59. }
  60. }
  61. adjPrime := ".." // Composite before
  62. if mathutil.IsPrime(n - 1) {
  63. adjPrime = "P." // Prime before
  64. }
  65. switch mathutil.IsPrime(n + 1) {
  66. case true:
  67. adjPrime += "P" // Prime after
  68. case false:
  69. adjPrime += "." // Composite after
  70. }
  71. if check && mathutil.QCmpUint32(hits, n, bestN, bestD) < 0 {
  72. order++
  73. d := time.Since(t0)
  74. bestN, bestD = hits, n
  75. q := float64(hits) / float64(n)
  76. fmt.Printf(
  77. "\r%2s #%03d %d %d %.2f %.2E %s %s %v\n",
  78. adjPrime, order, n, hits,
  79. 1/q, q, d, time.Now().Format("15:04:05"), mathutil.FactorInt(n),
  80. )
  81. }
  82. }
  83. }