Fork channel

Create a new channel as a copy of main.

Rename channel

Rename main to:

Delete channel

Delete main? This cannot be undone.

lib.rs
use std::convert::TryInto;

/*
Uses Sieve of Eratosthenes with some optimisations:
* Approximates size of the list required using the inverse of an approximation of the prime-counting function to save allocating too much extra space.
* Marks multiples starting from square of current prime.
* Stops marking multiples when the current index is ceil(sqrt(list size)) as the prime before that will be the last prime we need to check multiples for.
* Odd numbers only (wheel factorisation with base 2).

TODO:
* Use bases 2, 3, 5, 7 for wheel factorisation.
* Implement segmented sieve algorithm.
* Multi-thread with Mutex and lazy_static.
* Use bitbox from bitvec for bit compression.
*/

pub fn nth(n: u32) -> u32 {
	if n == 0 {
		return 2;
	}

	// List size approximation is insufficient for values of n = 0, 1, 2, 3, 4, 5, 6, 9, 11 and 12, requiring this correction.
	let corrected_n = (n + match n {
		0 | 11 => 3,
		1 | 5 | 6 | 9 => 4,
		2 | 4 => 6,
		3 => 5,
		7 | 8 | 12 => 1,
		_ => 0,
	}) as f64;
	// Approximated size of the list required using the inverse of an approximation of the prime-counting function, halved (as we're only interested in odd numbers). Lossy cast.
	let list_size = (corrected_n * (corrected_n * corrected_n.ln()).ln() / 2.0).ceil() as usize;
	/*
	Index at which we can stop marking new multiples.
	Array representing list of numbers.
	Prime count.
	 */
	let (limit, mut list, mut count) = (
		// Lossy cast.
		(list_size as f64).sqrt().ceil() as usize,
		vec![true; list_size],
		1,
	);

	for index in 1..limit {
		if list[index] {
			count += 1;
			if count > n {
				// Might panic if values greater than u32::MAX are converted.
				return (index * 2 + 1).try_into().unwrap();
			}
			for multiple in (((index * 2 + 1).pow(2) - 1) / 2..list_size).step_by(index * 2 + 1) {
				list[multiple] = false;
			}
		}
	}
	for index in limit..list_size {
		if list[index] {
			count += 1;
			if count > n {
				// Might panic if values greater than u32::MAX are converted.
				return (index * 2 + 1).try_into().unwrap();
			}
		}
	}

	unreachable!();
}