problem 1
This commit is contained in:
parent
d3c4e41a12
commit
a7fafcff22
35
Cargo.lock
generated
35
Cargo.lock
generated
@ -519,6 +519,12 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45"
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
@ -581,6 +587,28 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mini-internal"
|
||||
version = "0.1.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f09fa787e06d071d09c2964b065eb7cb1b842a7af5382fc4c9142089f8383f08"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniserde"
|
||||
version = "0.1.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e19a2e17a11c24d44c84d7e1b61477e20cd503d024e4b0eb3e97eb9a4d24fa87"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"mini-internal",
|
||||
"ryu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.2"
|
||||
@ -685,6 +713,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"miette",
|
||||
"miniserde",
|
||||
"smol",
|
||||
]
|
||||
|
||||
@ -730,6 +759,12 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.1"
|
||||
|
@ -6,4 +6,5 @@ edition = "2021"
|
||||
[dependencies]
|
||||
futures = "0.3.30"
|
||||
miette = { version = "5", features = ["fancy"] }
|
||||
miniserde = "0.1.38"
|
||||
smol = "1.3.0"
|
||||
|
158
src/main.rs
158
src/main.rs
@ -1,9 +1,161 @@
|
||||
use futures::{AsyncReadExt, StreamExt};
|
||||
use futures::{
|
||||
future::ready, io::BufReader, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, StreamExt,
|
||||
TryStreamExt,
|
||||
};
|
||||
use miette::IntoDiagnostic;
|
||||
use miniserde::{json::Number, Deserialize, Serialize};
|
||||
|
||||
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 {
|
||||
match number {
|
||||
Number::U64(n) => is_prime(n),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
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) = stream?.split();
|
||||
futures::io::copy(reader, &mut writer).await.map(|_| {})
|
||||
let (reader, writer) = stream?.split();
|
||||
let mut alive = true;
|
||||
BufReader::new(reader)
|
||||
.lines()
|
||||
.map_ok(process)
|
||||
.take_while(|item| {
|
||||
ready(match item {
|
||||
Ok(s) if s.is_empty() => std::mem::take(&mut alive),
|
||||
_ => alive,
|
||||
})
|
||||
})
|
||||
.map_ok(|s| s + "\n")
|
||||
.forward(writer.into_sink::<String>())
|
||||
.await
|
||||
}
|
||||
|
||||
fn main() -> miette::Result<()> {
|
||||
|
Loading…
Reference in New Issue
Block a user