coprime.rs

2.0 kB · rust · 85 lines

1use mrlynum::factor::coprime;2use std::thread;34pub const THREADS: u64 = 8;56fn row_slice(n: u32, rem: u64, step: u64) -> u64 {7    let mut count = 0u64;8    let mut m = 2 * rem + 1;9    while m < 1u64 << n {10        let rest = m - 1;11        let mut sub = rest;12        loop {13            if coprime(sub as usize + 1, m as usize) {14                count += 1;15            }16            if sub == 0 {17                break;18            }19            sub = (sub - 1) & rest;20        }21        m += 2 * step;22    }23    count24}2526fn complement_slice(n: u32, rem: u64, step: u64) -> u64 {27    let size = 1u64 << n;28    let mut count = 0u64;29    let mut i = rem;30    while i < size {31        let free = !i & (size - 1);32        let mut j = free;33        while j > i {34            if coprime(i as usize, j as usize) {35                count += 1;36            }37            j = (j - 1) & free;38        }39        i += step;40    }41    count42}4344fn spread(n: u32, slice: fn(u32, u64, u64) -> u64) -> u64 {45    let handles: Vec<thread::JoinHandle<u64>> = (0..THREADS)46        .map(|rem| thread::spawn(move || slice(n, rem, THREADS)))47        .collect();48    2 * handles.into_iter().map(|h| h.join().unwrap()).sum::<u64>()49}5051pub fn by_rows(n: u32) -> u64 {52    spread(n, row_slice)53}5455pub fn by_complement(n: u32) -> u64 {56    spread(n, complement_slice)57}5859pub fn by_pascal(n: u32) -> u64 {60    let mut row: Vec<u8> = vec![1];61    let mut total = 0u64;62    for m in 0..1u64 << n {63        for (k, entry) in row.iter().enumerate() {64            if *entry == 1 && coprime(k, m as usize - k) {65                total += 1;66            }67        }68        let mut next: Vec<u8> = Vec::with_capacity(row.len() + 1);69        next.push(1);70        for k in 1..row.len() {71            next.push((row[k - 1] + row[k]) & 1);72        }73        next.push(1);74        row = next;75    }76    total77}7879pub fn density(term: u64, n: u32) -> f64 {80    term as f64 / 3f64.powi(n as i32)81}8283pub fn limit() -> f64 {84    16.0 / (3.0 * std::f64::consts::PI * std::f64::consts::PI)85}