reset
This commit is contained in:
parent
f879ff30d2
commit
81802063f1
156
src/main.rs
156
src/main.rs
@ -1,158 +1,8 @@
|
||||
use miette::IntoDiagnostic;
|
||||
use miniserde::{json::Number, Deserialize, Serialize};
|
||||
use smol::{
|
||||
io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
|
||||
stream::StreamExt,
|
||||
};
|
||||
use smol::stream::StreamExt;
|
||||
|
||||
fn pow(a: u64, d: u64, n: u64) -> u64 {
|
||||
let n: u128 = n.into();
|
||||
let mut d: u128 = d.into();
|
||||
let mut x: u128 = 1;
|
||||
let mut q: u128 = a.into();
|
||||
while d != 0 {
|
||||
if d & 1 == 1 {
|
||||
x *= q;
|
||||
x %= n;
|
||||
}
|
||||
q *= q;
|
||||
q %= n;
|
||||
d >>= 1;
|
||||
}
|
||||
x as _
|
||||
}
|
||||
|
||||
fn square(x: u64, n: u64) -> u64 {
|
||||
let n: u128 = n.into();
|
||||
let mut x: u128 = x.into();
|
||||
x *= x;
|
||||
x %= n;
|
||||
x as _
|
||||
}
|
||||
|
||||
fn is_prime(n: u64) -> bool {
|
||||
const LOG_2_TO_E: [u64; 65] = [
|
||||
0, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 10, 10, 11, 12, 12, 13, 14, 14, 15, 16, 16, 17, 18,
|
||||
19, 19, 20, 21, 21, 22, 23, 23, 24, 25, 25, 26, 27, 28, 28, 29, 30, 30, 31, 32, 32, 33, 34,
|
||||
34, 35, 36, 37, 37, 38, 39, 39, 40, 41, 41, 42, 43, 43, 44, 45,
|
||||
];
|
||||
|
||||
match n {
|
||||
0 => false,
|
||||
1 => false,
|
||||
2 => true,
|
||||
3.. => {
|
||||
let n1 = n - 1;
|
||||
let s = n1.trailing_zeros();
|
||||
let d = n1 >> s;
|
||||
let log_e_approx = LOG_2_TO_E[(n.ilog2() + 1) as usize];
|
||||
for a in 2..=(n - 2).min(2 * log_e_approx * log_e_approx) {
|
||||
let mut x = pow(a, d, n);
|
||||
for _ in 0..s {
|
||||
let y = square(x, n);
|
||||
if y == 1 && x != 1 && x != n1 {
|
||||
return false;
|
||||
}
|
||||
x = y;
|
||||
}
|
||||
if x != 1 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn primes() {
|
||||
assert!(!is_prime(0));
|
||||
assert!(!is_prime(1));
|
||||
assert!(is_prime(2));
|
||||
assert!(is_prime(3));
|
||||
assert!(!is_prime(4));
|
||||
assert!(is_prime(5));
|
||||
assert!(!is_prime(6));
|
||||
assert!(is_prime(7));
|
||||
assert!(!is_prime(8));
|
||||
assert!(!is_prime(9));
|
||||
assert!(!is_prime(10));
|
||||
assert!(is_prime(11));
|
||||
assert!(!is_prime(12));
|
||||
assert!(is_prime(13));
|
||||
assert!(!is_prime(14));
|
||||
assert!(!is_prime(15));
|
||||
assert!(!is_prime(16));
|
||||
assert!(is_prime(17));
|
||||
assert!(!is_prime(18));
|
||||
assert!(is_prime(19));
|
||||
assert!(!is_prime(20));
|
||||
assert!(!is_prime(21));
|
||||
assert!(!is_prime(22));
|
||||
assert!(is_prime(23));
|
||||
assert!(!is_prime(57));
|
||||
assert!(is_prime(97));
|
||||
assert!(is_prime(101));
|
||||
assert!(is_prime(179));
|
||||
assert!(!is_prime(216));
|
||||
assert!(!is_prime(426));
|
||||
assert!(is_prime(997));
|
||||
assert!(is_prime(65537));
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
enum Method {
|
||||
#[serde(rename = "isPrime")]
|
||||
IsPrime,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct Request {
|
||||
method: Method,
|
||||
number: Number,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct Response {
|
||||
method: Method,
|
||||
prime: bool,
|
||||
}
|
||||
|
||||
fn json_prime(number: Number) -> bool {
|
||||
matches!(number, Number::U64(n) if is_prime(n))
|
||||
}
|
||||
|
||||
fn try_process(input: String) -> miniserde::Result<String> {
|
||||
let Request {
|
||||
method: Method::IsPrime,
|
||||
number,
|
||||
} = miniserde::json::from_str(&input)?;
|
||||
let response = Response {
|
||||
method: Method::IsPrime,
|
||||
prime: json_prime(number),
|
||||
};
|
||||
Ok(miniserde::json::to_string(&response))
|
||||
}
|
||||
|
||||
fn process(input: String) -> String {
|
||||
try_process(input).unwrap_or_default()
|
||||
}
|
||||
|
||||
async fn handle(stream: smol::io::Result<smol::net::TcpStream>) -> smol::io::Result<()> {
|
||||
let (reader, mut writer) = smol::io::split(stream?);
|
||||
let mut alive = true;
|
||||
let mut items = BufReader::new(reader)
|
||||
.lines()
|
||||
.map(|r| r.map(process))
|
||||
.take_while(|item| match item {
|
||||
Ok(s) if s.is_empty() => std::mem::take(&mut alive),
|
||||
_ => alive,
|
||||
})
|
||||
.map(|r| r.map(|s| s + "\n"));
|
||||
while let Some(item) = items.next().await.transpose()? {
|
||||
writer.write_all(item.as_bytes()).await?;
|
||||
}
|
||||
writer.close().await
|
||||
async fn handle(_stream: smol::io::Result<smol::net::TcpStream>) -> smol::io::Result<()> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn main() -> miette::Result<()> {
|
||||
|
Loading…
Reference in New Issue
Block a user