Advertisement
Guest User

Untitled

a guest
Sep 18th, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.65 KB | None | 0 0
  1. /* author Bill Wood */
  2.  
  3. fn sqrt(n: usize) -> usize {
  4. let (mut r1, mut r) = (n, n + 1);
  5. while r1 < r {
  6. r = r1;
  7. r1 = (r1 + n/r1) >> 1
  8. }
  9. r
  10. }
  11.  
  12. struct Bvec {
  13. v: Vec<u8>
  14. }
  15. impl Bvec {
  16. fn new(val: bool, s: usize) -> Self {
  17. let valu8 = if val { 255 } else { 0 };
  18. Bvec { v: vec![valu8; (s >> 3) + if (s & 7) == 0 { 0 } else { 1 } ] }
  19. }
  20. #[inline(always)]
  21. fn get(&self, index: usize) -> bool {
  22. self.v[index >> 3] & 1 << (index & 7) != 0
  23. }
  24. #[inline(always)]
  25. fn set(&mut self, mut index: usize, val: bool) {
  26. let bitpos = 1 << (index & 7);
  27. index >>= 3;
  28. if val {
  29. self.v[index] |= bitpos;
  30. } else {
  31. self.v[index] &= !bitpos;
  32. }
  33. }
  34. }
  35.  
  36. fn simple_sieve(mut high: usize) -> Vec<u32> {
  37. // x where x: odd and (x+2)^2 > high and x^2 < high
  38. high = (sqrt(high) - 1) | 1;
  39. let mut pvec = vec![false; (high + 1)/2];
  40. let mut primes = vec![];
  41. let n = high >> 1;
  42. let mut i = 3;
  43. while i*i <= high {
  44. if !pvec[i >> 1] {
  45. primes.push(i as u32);
  46. let mut j = (i*i) >> 1;
  47. while j <= n {
  48. pvec[j] = true;
  49. j += i;
  50. }
  51. }
  52. i += 2;
  53. }
  54. i >>= 1;
  55. while i <= n {
  56. if !pvec[i] {
  57. primes.push(((i << 1) | 1) as u32);
  58. }
  59. i += 1;
  60. }
  61. primes
  62. }
  63.  
  64. use rayon::prelude::*;
  65. use time::PreciseTime;
  66. use std::io::Write;
  67.  
  68. fn main() {
  69. let mut args = std::env::args()
  70. .skip(1)
  71. .map(|a| a
  72. .split('_')
  73. .fold("".to_string(), |a, s| a + s)
  74. .parse::<usize>());
  75.  
  76. if args.len() <= 3 {
  77. if let (Ok(mut low), Ok(mut high), Ok(seg_size_kb), ) = (
  78. args.next().unwrap_or(Ok(1_000_000_000)),
  79. args.next().unwrap_or(Ok(2_000_000_000)),
  80. args.next().unwrap_or(Ok(128)),) {
  81. println!("S14: Finding sexy primes with args {} {} {}", low, high, seg_size_kb, );
  82. let start = PreciseTime::now();
  83.  
  84. low = low | 1; // lowest odd >= low
  85. if low < 3 {
  86. low = 3;
  87. }
  88. high = (high - 1) | 1; // highest odd <= high
  89.  
  90. // prepare for parallel segment sieve
  91. let primes_per_seg = seg_size_kb.next_power_of_two()*1024*8*2;
  92. let mut seg_low = low;
  93. let mut segs = vec![];
  94. while seg_low < high {
  95. let mut seg_high = seg_low + primes_per_seg - 2;
  96. if seg_high > high {
  97. seg_high = high;
  98. }
  99. segs.push((seg_low, seg_high + 6));
  100. seg_low = seg_high + 2;
  101. }
  102.  
  103. // get sieving primes
  104. let sieve_primes = simple_sieve(high);
  105. // find sexy primes
  106. let (sexy_count, nprimes) =
  107. segs.into_par_iter()
  108. .map(|(low, high)| {
  109. let n = (high + 2 - low) >> 1;
  110. let mut sieve_seg = Bvec::new(false, n);
  111. for i in 0..sieve_primes.len() {
  112. let p = sieve_primes[i] as usize;
  113. let mut j = p*p;
  114. if j > high {
  115. break;
  116. }
  117. if j < low {
  118. j += (low - 1 - j + p*2)/2/p*p*2;
  119. }
  120. j = (j - low) >> 1;
  121. while j < n {
  122. sieve_seg.set(j, true);
  123. j += p;
  124. }
  125. }
  126.  
  127. let (mut sexy_count, mut nprimes) = (0_usize, 0_usize);
  128. for i in 0..n - 6/2 {
  129. if !sieve_seg.get(i) {
  130. nprimes += 1;
  131. if !sieve_seg.get(i + 6/2) {
  132. sexy_count += 1;
  133. }
  134. }
  135. }
  136. (sexy_count, nprimes)
  137. })
  138. .reduce(|| (0, 0),
  139. |a, b| (a.0 + b.0, a.1 + b.1));
  140.  
  141. let end = PreciseTime::now();
  142. println!("done generating primes in {:.2} secs...", start.to(end).num_milliseconds() as f64 / 1000.0);
  143. println!("\n{} of {} primes are sexy", sexy_count, nprimes);
  144. return;
  145. }
  146. }
  147.  
  148. writeln!(
  149. std::io::stderr(),
  150. "Usage: sexy_primes [low [high [seg_size(kb)]]]"
  151. ).unwrap();
  152. std::process::exit(1);
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement