Problem 7 "10001st prime"
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
問 7 「10001番目の素数」
素数を小さい方から6つ並べると 2, 3, 5, 7, 11, 13 であり, 6番目の素数は 13 である.
10 001 番目の素数を求めよ.
fn rule_out(sieve: &mut Vec<bool>, prime: usize) { for i in (prime * prime..sieve.len()).step_by(prime) { sieve[i] = false; } } fn rule_out_from_previous_position(sieve: &mut Vec<bool>, prime: usize, pp: usize) { use std::cmp::max; let begin = max((((pp - 1) / prime) + 1) * prime, prime * prime); for i in (begin..sieve.len()).step_by(prime) { sieve[i] = false; } } fn extend(sieve: &mut Vec<bool>, primes: &Vec<usize>) { let previous_len = sieve.len(); sieve.extend(vec![true; previous_len]); for &p in primes { rule_out_from_previous_position(sieve, p, previous_len); } } fn main() { let mut counter = 2u32; let mut sieve = vec![true; 10000]; let mut primes: Vec<usize> = vec![]; let mut cursor = 5usize; let mut ite = [2usize, 4].iter().cycle(); let n = 'exploration: loop { while cursor < sieve.len() { if !sieve[cursor] { cursor += ite.next().unwrap(); continue; } counter += 1; if counter == 10001 { break 'exploration cursor as u64; } &primes.push(cursor); rule_out(&mut sieve, cursor); cursor += ite.next().unwrap(); } extend(&mut sieve, &primes); }; println!("{}", n); assert_eq!(n, 104743); }
fn is_prime(n: u64) -> bool { if n < 2 { return false; } if n == 2 || n == 3 || n == 5 { return true; } for d in &[2u64, 3, 5] { if n % *d == 0 { return false; } } let side = (n as f64).sqrt() as u64; let mut d = 5u64; for i in [2u64, 4].iter().cycle() { d += *i; if d > side { break; } if n % d == 0 { return false; } } true } fn main() { let mut n = 0u64; let mut counter = 0u32; while counter < 10001 { n += 1; if is_prime(n) { counter += 1; } } println!("{}", n); assert_eq!(n, 104743); }
package main
import "fmt"
type Index struct {
i int
f uint8
}
func (i *Index) increment() {
i.i += 2 << i.f
i.f ^= 1
}
func ruleout(sieve []bool, p int) {
for i := p * p; i < len(sieve); i += p {
sieve[i] = true
}
}
func ruleoutFromPosition(sieve []bool, prime, position int) {
pos := (((position - 1) / prime) + 1) * prime
sq := prime * prime
if pos < sq {
pos = sq
}
for i := pos; i < len(sieve); i += prime {
sieve[i] = true
}
}
func extend(sieve *[]bool, primes []int) {
previousLen := len(*sieve)
*sieve = append(*sieve, make([]bool, previousLen)...)
for _, p := range primes {
ruleoutFromPosition(*sieve, p, previousLen)
}
}
func Example() {
counter := 2
sieve := make([]bool, 10000)
primes := []int{}
i := Index{i: 5}
Exploration:
for {
for i.i < len(sieve) {
if sieve[i.i] {
i.increment()
continue
}
counter++
if counter == 10001 {
break Exploration
}
primes = append(primes, i.i)
ruleout(sieve, i.i)
i.increment()
}
extend(&sieve, primes)
}
fmt.Println(i.i)
// Output: 104743
}
https://stackoverflow.com/questions/23304854/how-do-you-determine-if-a-variable-is-a-slice-or-array
→ Go playgroundfunction assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new Error(msg);
}
}
class Index {
i: number;
#f: number;
constructor() {
this.i = 5;
this.#f = 0;
}
increment() {
this.i += 2 << this.#f;
this.#f ^= 1;
}
}
function ruleoutFromPosition(
sieve: boolean[],
prime: number,
position: number,
) {
const sq = prime * prime;
const head = (((position - 1) / prime | 0) + 1) * prime;
for (let i = Math.max(sq, head); i < sieve.length; i += prime) {
sieve[i] = false;
}
}
function ruleout(sieve: boolean[], p: number) {
for (let i = p * p; i < sieve.length; i += p) {
sieve[i] = false;
}
}
function extend(sieve: boolean[], primes: number[]) {
const previousLen = sieve.length;
sieve.push(...Array(previousLen).fill(true));
for (const p of primes) {
ruleoutFromPosition(sieve, p, previousLen);
}
}
let counter = 2;
let sieve = Array(10000).fill(true);
let primes = [];
const i = new Index();
exploration:
while (true) {
while (i.i < sieve.length) {
if (!sieve[i.i]) {
i.increment();
continue;
}
counter++;
if (counter === 10001) {
break exploration;
}
primes.push(i.i);
ruleout(sieve, i.i);
i.increment();
}
extend(sieve, primes);
}
console.log(i.i);
assert(i.i === 104743);
→ TypeScript playground
- https://en.wikipedia.org/wiki/Logical_connective#Overview
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_XOR