Advertisement
Guest User

Untitled

a guest
Sep 16th, 2019
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.03 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 SimpleSieve {
  13. primes: Vec<u32>,
  14. }
  15. impl SimpleSieve {
  16. fn new(high: usize) -> Self {
  17. assert_eq!(high | 1, high);
  18. let mut pvec = vec![false; (high + 1)/2];
  19. let mut primes = vec![];
  20. let n = high >> 1;
  21. let mut i = 3;
  22. while i*i <= high {
  23. if !pvec[i >> 1] {
  24. primes.push(i as u32);
  25. let mut j = (i*i) >> 1;
  26. while j <= n {
  27. pvec[j] = true;
  28. j += i;
  29. }
  30. }
  31. i += 2;
  32. }
  33. i >>= 1;
  34. while i <= n {
  35. if !pvec[i] {
  36. primes.push(((i << 1) | 1) as u32);
  37. }
  38. i += 1;
  39. }
  40. dbg!(primes.len());
  41. SimpleSieve { primes, }
  42. }
  43. }
  44.  
  45. type CBFn<'a> = &'a mut dyn FnMut(usize);
  46. struct SieveSlice<'a> {
  47. low: usize,
  48. high: usize,
  49. bslice: &'a mut [bool],
  50. }
  51. impl<'a> SieveSlice<'a> {
  52. fn new(low: usize, high: usize, bslice: &'a mut [bool]) -> Self {
  53. // assert_eq!(low | 1, low);
  54. // assert_eq!(high | 1, high);
  55. // dbg!(low, high, );
  56. SieveSlice { low, high, bslice }
  57. }
  58. fn find(&mut self, f: CBFn, sieve: &SimpleSieve) {
  59. let (low, high) = (self.low, self.high);
  60.  
  61. // generate primes
  62. let n = (high + 2 - low) >> 1;
  63. for i in 0..sieve.primes.len() {
  64. let p = sieve.primes[i] as usize;
  65. let mut j = p*p;
  66. if j < low {
  67. j += (low - 1 - j + p*2)/2/p*p*2;
  68. }
  69. if j > high {//?? moved here
  70. break;
  71. }
  72. j = (j - low) >> 1;
  73. while j < n {
  74. self.bslice[j] = true;
  75. j += p;
  76. }
  77. }
  78. // callback primes
  79. if low < 2 && high > 2 {
  80. self.bslice[0] = true; // 1 is not prime
  81. f(2); // 2 is prime
  82. }
  83. for i in 0..n {
  84. if !self.bslice[i] {
  85. f((i << 1) + low);
  86. }
  87. }
  88. }
  89. }
  90.  
  91. use rayon::prelude::*;
  92. struct Primes {
  93. low: usize,
  94. high: usize,
  95. seg_size: usize,
  96. seg_num_chunks: usize,
  97. }
  98. impl Primes {
  99. fn new(mut low: usize, mut high: usize, seg_size_kb: usize, seg_num_chunks: usize) -> Result<Self, ()> {
  100. // lowest odd >= low
  101. low |= 1;
  102. if low > high || seg_size_kb == 0 || seg_num_chunks == 0 || seg_size_kb*1024 < seg_num_chunks {
  103. return Err(());
  104. }
  105. // highest odd <= high
  106. high = (high - 1) | 1;
  107. let seg_size = seg_size_kb.next_power_of_two()*1024;
  108. Ok(Primes { low, high, seg_size, seg_num_chunks })
  109. }
  110. fn callback(&self, f: CBFn) {
  111. let high = self.high;
  112.  
  113. // x where x: odd and (x+2)^2 > high and x^2 < high
  114. let ss_high = (sqrt(high) - 1) | 1;
  115. let sieve = SimpleSieve::new(ss_high);
  116.  
  117. // track odds only
  118. let seg_nprimes_per_byte = 2;
  119.  
  120. let mut seg_low = self.low;
  121. dbg!(self.low, ss_high, seg_low, high, self.seg_num_chunks, self.seg_size, );
  122. let mut sieve_seg = vec![false; self.seg_size];
  123. let mut c = 0;
  124. while seg_low <= high {
  125. let mut segments = vec!();
  126. for bslice in sieve_seg.chunks_mut(self.seg_size/self.seg_num_chunks) {
  127. let mut seg_high = seg_low + bslice.len()*seg_nprimes_per_byte - 2;
  128. if seg_high > high {
  129. seg_high = high;
  130. }
  131. segments.push(SieveSlice::new(seg_low, seg_high, bslice));
  132. seg_low = seg_high + 2;
  133. if seg_low > high {
  134. break;
  135. }
  136. }
  137. //dbg!(segments[0].bslice.len(), segments.len());
  138. segments.iter_mut().for_each(|seg| seg.find(f, &sieve));
  139. sieve_seg.iter_mut().for_each(|x| *x = false);
  140. c += 1;
  141. }
  142. dbg!(c);
  143. }
  144. }
  145.  
  146. #[derive(Debug)]
  147. struct FILO<T>(Vec<T>);
  148. impl<T: Copy + PartialEq> FILO<T> {
  149. fn new(value: T, size: usize) -> Self {
  150. FILO(vec![value; size])
  151. }
  152. #[inline(always)]
  153. fn push(&mut self, mut value: T) -> T {
  154. self.0.iter_mut().for_each(|v| { let tmp = *v; *v = value; value = tmp; } );
  155. self.0[self.0.len() - 1]
  156. }
  157. #[inline(always)]
  158. fn contains(&self, value: T) -> bool {
  159. self.0.iter().any(|x| *x == value)
  160. }
  161. }
  162.  
  163. use time::PreciseTime;
  164. use std::io::Write;
  165. fn main() {
  166. let mut args = std::env::args()
  167. .skip(1)
  168. .map(|a| a
  169. .split('_')
  170. .fold("".to_string(), |a, s| a + s)
  171. .parse::<usize>());
  172.  
  173. if args.len() <= 4 {
  174. if let (Ok(low), Ok(high), Ok(seg_size_kb), Ok(seg_num_chunks)) = (
  175. args.next().unwrap_or(Ok(3)),
  176. args.next().unwrap_or(Ok(1000000)),
  177. args.next().unwrap_or(Ok(32)),
  178. args.next().unwrap_or(Ok(4))) {
  179. let start = PreciseTime::now();
  180. if let Ok(primes) = Primes::new(low, high + 6, seg_size_kb, seg_num_chunks) {
  181. let mut count = 0;
  182. let mut nprimes = 0;
  183. let mut pbuf = FILO::new(0, 3);
  184. primes.callback(&mut |p| {//?? &mut? dyn?
  185. if p <= high {
  186. nprimes += 1;
  187. if p < 200 { print!("{} ", p); }
  188. }
  189. if pbuf.contains(p) {
  190. count += 1;
  191. }
  192. pbuf.push(p + 6);
  193. });
  194. let end = PreciseTime::now();
  195. println!("\ndone counting primes in {:.2} secs...", start.to(end).num_milliseconds() as f64 / 1000.0);
  196. println!("{} of {} primes are sexy", count, nprimes);
  197. return;
  198. }
  199. }
  200. }
  201.  
  202. writeln!(
  203. std::io::stderr(),
  204. "Usage: sexy_primes low high seg_size(kb)"
  205. ).unwrap();
  206. std::process::exit(1);
  207. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement