[08_revisit_everything] automate solution of challenges one through seven
This commit is contained in:
@@ -9,6 +9,8 @@ json = "0.12.4"
|
|||||||
reqwest = { version = "0.12.23", features = ["blocking"] }
|
reqwest = { version = "0.12.23", features = ["blocking"] }
|
||||||
rug = { version = "1.28.0", features = ["integer"], default-features = false }
|
rug = { version = "1.28.0", features = ["integer"], default-features = false }
|
||||||
tqdm = "0.8.0"
|
tqdm = "0.8.0"
|
||||||
|
sha2 = "0.10.9"
|
||||||
|
percent-encoding = "2.3.2"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "lib"
|
name = "lib"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
54
src/bin/main.rs
Normal file
54
src/bin/main.rs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
use std::env;
|
||||||
|
use std::fmt::Display;
|
||||||
|
use std::process::ExitCode;
|
||||||
|
use lib::submit_with_name;
|
||||||
|
|
||||||
|
fn main() -> ExitCode {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
if args.len() < 2 {
|
||||||
|
eprintln!("Usage: main NAME");
|
||||||
|
return ExitCode::FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
let name = args[1].clone();
|
||||||
|
|
||||||
|
print!("Solving challenge 01_welcome... ");
|
||||||
|
let (n, x) = lib::challenges::c1_welcome::solve();
|
||||||
|
submit_or_fail(&name, n, x.clone());
|
||||||
|
|
||||||
|
print!("Solving challenge 02_these_numbers_are_big... ");
|
||||||
|
let (n, x) = lib::challenges::c2_these_numbers_are_big::solve(&name);
|
||||||
|
submit_or_fail(&name, n, x.clone());
|
||||||
|
|
||||||
|
print!("Solving challenge 03_are_you_still_doing_this_by_hand... ");
|
||||||
|
let (n, x) = lib::challenges::c3_are_you_still_doing_this_by_hand::solve(n, x);
|
||||||
|
submit_or_fail(&name, n, x.clone());
|
||||||
|
|
||||||
|
print!("Solving challenge 04_broken_proof_of_work... ");
|
||||||
|
let (n, x) = lib::challenges::c4_broken_proof_of_work::solve(n, x);
|
||||||
|
submit_or_fail(&name, n, x.clone());
|
||||||
|
|
||||||
|
print!("Solving challenge 05_what_the_bf... ");
|
||||||
|
let (n, x) = lib::challenges::c5_what_the_bf::solve(n, x);
|
||||||
|
submit_or_fail(&name, n, x.clone());
|
||||||
|
|
||||||
|
print!("Solving challenge 06_automation_is_not_enough... ");
|
||||||
|
let (n, x) = lib::challenges::c6_automation_is_not_enough::solve(n, x);
|
||||||
|
submit_or_fail(&name, n, x.clone());
|
||||||
|
|
||||||
|
print!("Solving challenge 07_weird_assembly_machine... ");
|
||||||
|
let (n, x) = lib::challenges::c7_weird_assembly_machine::solve(n, x);
|
||||||
|
submit_or_fail(&name, n, x.clone());
|
||||||
|
|
||||||
|
println!("n = {n}");
|
||||||
|
println!("x = {x}");
|
||||||
|
|
||||||
|
ExitCode::SUCCESS
|
||||||
|
}
|
||||||
|
|
||||||
|
fn submit_or_fail<T1: Display + Send, T2: Display + Send>(name: &str, n: T1, x: T2) {
|
||||||
|
match submit_with_name(name, n, x) {
|
||||||
|
Ok(_) => println!("Success."),
|
||||||
|
Err(err) => println!("Failure: {}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/lib/challenges/c1_welcome.rs
Normal file
3
src/lib/challenges/c1_welcome.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
pub fn solve() -> (u64, u64) {
|
||||||
|
(10000, 4)
|
||||||
|
}
|
||||||
23
src/lib/challenges/c2_these_numbers_are_big.rs
Normal file
23
src/lib/challenges/c2_these_numbers_are_big.rs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
use std::sync::LazyLock;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use rug::Integer;
|
||||||
|
use rug::integer::Order;
|
||||||
|
use sha2::{Sha256, Digest};
|
||||||
|
|
||||||
|
static M: LazyLock<Integer> = LazyLock::new(|| Integer::from_str("14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923").unwrap());
|
||||||
|
static E: LazyLock<Integer> = LazyLock::new(|| Integer::from(65537));
|
||||||
|
|
||||||
|
pub fn solve(name: &str) -> (u64, Integer) {
|
||||||
|
let mut x = sha256(name);
|
||||||
|
x += 4;
|
||||||
|
for _ in 0..10_000 {
|
||||||
|
for _ in 0..100 {
|
||||||
|
x.pow_mod_mut(&E, &M).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(20_000, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sha256(name: &str) -> Integer {
|
||||||
|
Integer::from_digits(Sha256::digest(name).as_slice(), Order::MsfBe)
|
||||||
|
}
|
||||||
90
src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs
Normal file
90
src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
use rug::Integer;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use tqdm::tqdm;
|
||||||
|
|
||||||
|
/// the modul of the discrete logarithm
|
||||||
|
const P: u64 = 12345679943u64;
|
||||||
|
|
||||||
|
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
|
||||||
|
let x = x.modulo(&Integer::from(P - 1)).to_u64().unwrap();
|
||||||
|
|
||||||
|
let mut n = n;
|
||||||
|
let mut x = x.clone();
|
||||||
|
for _ in tqdm(0..10_000) {
|
||||||
|
n += 1;
|
||||||
|
x = log(42, 1 + (x + n) % (P - 1), P).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
(n, Integer::from(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the discrete logarithm of `b` to the base `g` modulo `m` using the Baby-Step-Giant-Step algorithm.
|
||||||
|
fn log(g: u64, b: u64, m: u64) -> Option<u64> {
|
||||||
|
let g: u128 = g as u128;
|
||||||
|
let b: u128 = b as u128;
|
||||||
|
let m: u128 = m as u128;
|
||||||
|
|
||||||
|
let s = m.isqrt() + 1;
|
||||||
|
let mut r = HashMap::new();
|
||||||
|
|
||||||
|
let mut a = b % m;
|
||||||
|
if a == 1 {
|
||||||
|
return Some(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for i in 0..s {
|
||||||
|
r.insert(a, i);
|
||||||
|
a *= g;
|
||||||
|
a %= m;
|
||||||
|
}
|
||||||
|
|
||||||
|
let gs = pow(g as u64, s as u64, m as u64) as u128;
|
||||||
|
a = gs;
|
||||||
|
for j in 1..=s {
|
||||||
|
if let Some(i) = r.get(&a) {
|
||||||
|
return Some((j * s - i) as u64);
|
||||||
|
}
|
||||||
|
|
||||||
|
a *= gs;
|
||||||
|
a %= m;
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the `k`-th power of `a` modulo `m`.
|
||||||
|
fn pow(a: u64, mut k: u64, m: u64) -> u64 {
|
||||||
|
let mut a: u128 = a as u128;
|
||||||
|
let m: u128 = m as u128;
|
||||||
|
let mut b = 1u128;
|
||||||
|
while k != 0 {
|
||||||
|
if k % 2 == 1 {
|
||||||
|
b *= a;
|
||||||
|
b %= m;
|
||||||
|
}
|
||||||
|
a *= a;
|
||||||
|
a %= m;
|
||||||
|
|
||||||
|
k >>= 1;
|
||||||
|
}
|
||||||
|
b as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn log_test() {
|
||||||
|
assert_eq!(log(3, 12, 23), Some(4));
|
||||||
|
assert_eq!(log(2, 3, 5), Some(3));
|
||||||
|
|
||||||
|
log(42, 3816393254, 12345679943);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pow_test() {
|
||||||
|
assert_eq!(pow(2, 3, 5), 3);
|
||||||
|
assert_eq!(pow(3, 4, 23), 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
src/lib/challenges/c4_broken_proof_of_work.rs
Normal file
17
src/lib/challenges/c4_broken_proof_of_work.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
use rug::Integer;
|
||||||
|
|
||||||
|
const LIMIT: u64 = 100_000_000;
|
||||||
|
|
||||||
|
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
|
||||||
|
let k = LIMIT - n;
|
||||||
|
|
||||||
|
let mut x = x + (k / 4) * 1_640_000;
|
||||||
|
for _ in 0..k%4 {
|
||||||
|
for _ in 0..10000 {
|
||||||
|
x += 41;
|
||||||
|
x ^= 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(LIMIT, x)
|
||||||
|
}
|
||||||
33
src/lib/challenges/c5_what_the_bf.rs
Normal file
33
src/lib/challenges/c5_what_the_bf.rs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
use rug::{Assign, Integer};
|
||||||
|
|
||||||
|
const LIMIT: u64 = 1_000_000_000_000u64;
|
||||||
|
const M: u64 = 1_000_000_000_000u64 - 11;
|
||||||
|
|
||||||
|
// x_{n+1} = 1/11 * x mod (10^12 - 11)
|
||||||
|
|
||||||
|
|
||||||
|
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
|
||||||
|
let k = LIMIT - n - 1;
|
||||||
|
|
||||||
|
let mut x = x;
|
||||||
|
for _ in 0..100 {
|
||||||
|
let y = x.to_u128().unwrap();
|
||||||
|
x.assign(f(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
let a = Integer::from(11).pow_mod(&Integer::from(-1), &Integer::from(M)).unwrap();
|
||||||
|
let b = a.pow_mod(&Integer::from(100 * k), &Integer::from(M)).unwrap();
|
||||||
|
|
||||||
|
(LIMIT, x * b % &M)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f(mut x: u128) -> u128 {
|
||||||
|
const A: u128 = 909_090_909_091u128; // (10 * b + 1) / 11
|
||||||
|
const B: u128 = 1_000_000_000_000u128; // 10^12
|
||||||
|
const C: u128 = 999_999_999_989u128; // b - 11
|
||||||
|
const D: u128 = 999_999_999_999u128; // b - 1
|
||||||
|
|
||||||
|
x = x * A % B;
|
||||||
|
x = (x * C + D) / B;
|
||||||
|
x
|
||||||
|
}
|
||||||
21
src/lib/challenges/c6_automation_is_not_enough.rs
Normal file
21
src/lib/challenges/c6_automation_is_not_enough.rs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
use rug::Integer;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
|
const START: u64 = 1_000_000_000_000u64;
|
||||||
|
const LIMIT: u64 = 10_000_000_000_000_000u64;
|
||||||
|
|
||||||
|
static M: LazyLock<Integer> = LazyLock::new(|| Integer::from_str("14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923").unwrap());
|
||||||
|
static A: LazyLock<Integer> = LazyLock::new(|| Integer::from_str("10729297455904899337681752672816753703351288544833760635567859176397566160330812285369370751389224534974913042757043771146367160829669925123791471756026119030734890865062863499420767799283504416995775836275660636668989077836006690621539265605").unwrap());
|
||||||
|
static B: LazyLock<Integer> = LazyLock::new(|| Integer::from_str("4997609466256208183077203585670710326160976219126614124062259398288517298185253986607627790890962248558793881836308854443463332741665631247256917127102588793451033551034614994254514161235462726178612824897626185944163885786520174491419225456").unwrap());
|
||||||
|
|
||||||
|
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
|
||||||
|
assert_eq!(n, START);
|
||||||
|
|
||||||
|
let mut x = x;
|
||||||
|
x = (x + &*A) % &*M;
|
||||||
|
x = x * 2 % &*M;
|
||||||
|
x = (x + &*B) % &*M;
|
||||||
|
|
||||||
|
(LIMIT, x)
|
||||||
|
}
|
||||||
132
src/lib/challenges/c7_weird_assembly_machine.rs
Normal file
132
src/lib/challenges/c7_weird_assembly_machine.rs
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::sync::LazyLock;
|
||||||
|
use rug::Integer;
|
||||||
|
|
||||||
|
static DATA: LazyLock<Vec<u64>> = LazyLock::new(|| {
|
||||||
|
let file = File::open("./res/07_weird_assembly_machine.data");
|
||||||
|
let lines = BufReader::new(file.unwrap()).lines();
|
||||||
|
|
||||||
|
let mut data = Vec::new();
|
||||||
|
for line in lines {
|
||||||
|
data.push(u64::from_str(&line.unwrap()).unwrap());
|
||||||
|
}
|
||||||
|
data
|
||||||
|
});
|
||||||
|
|
||||||
|
const LIMIT: u64 = 1_000_000_000_000_000_000u64;
|
||||||
|
|
||||||
|
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
|
||||||
|
let x = x.to_u64_wrapping();
|
||||||
|
let (n, x) = h_n(n, x, LIMIT - n);
|
||||||
|
(n, Integer::from(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn h(x: u64, n: u64) -> u64 {
|
||||||
|
g(sub(f(x), n))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn h_n(mut n: u64, mut x: u64, k: u64) -> (u64, u64) {
|
||||||
|
n += 1;
|
||||||
|
x = sub(f(x), n);
|
||||||
|
|
||||||
|
let fast_k = (k - 1) / 192 * 192;
|
||||||
|
let sum = fast_fg_sum(n , fast_k);
|
||||||
|
x = sub(fg_n(x, fast_k), sum);
|
||||||
|
n += fast_k;
|
||||||
|
|
||||||
|
let remaining = (k - 1) - fast_k;
|
||||||
|
let sum = fg_sum(n, remaining);
|
||||||
|
x = sub(fg_n(x, remaining), sum);
|
||||||
|
n += remaining;
|
||||||
|
|
||||||
|
x = g(x);
|
||||||
|
|
||||||
|
(n, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f(x: u64) -> u64 {
|
||||||
|
evaluate(x, &DATA[..128])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn g(x: u64) -> u64 {
|
||||||
|
evaluate(x, &DATA[128..])
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Quickly computes [`f`](f)([`g`](g)(x)).
|
||||||
|
fn fg(x: u64) -> u64 {
|
||||||
|
!x.rotate_left(17)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes [`fg`](fg)(...[`fg`](fg)(x)...) where [`fg`] is applied `n` times.
|
||||||
|
fn fg_n(mut x: u64, n: u64) -> u64 {
|
||||||
|
for _ in 0..n%64 {
|
||||||
|
x = fg(x);
|
||||||
|
}
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the sum from `i = 1` to `k` over `fg^(k-i)(n + i)`.
|
||||||
|
fn fg_sum(n: u64, k: u64) -> u64 {
|
||||||
|
let mut sum = 0u64;
|
||||||
|
for i in 1..=k {
|
||||||
|
sum = add(sum, fg_n(n + i, k - i));
|
||||||
|
}
|
||||||
|
sum
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Quickly computes `fg_sum` when `k` is divisible by `192`.
|
||||||
|
fn fast_fg_sum(n: u64, k: u64) -> u64 {
|
||||||
|
debug_assert!(k % 192 == 0);
|
||||||
|
let mut result = fg_sum(n, 0);
|
||||||
|
result = add(result, ((13556435138434861179u128 * (k / 192) as u128) % (u64::MAX as u128)) as u64);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluates a polynomial over `GF(2)[X] / (X^64 + 1)`
|
||||||
|
fn evaluate(x: u64, data: &[u64]) -> u64 {
|
||||||
|
let mut out = 0;
|
||||||
|
for i in 0..data.len() {
|
||||||
|
out = xor_mul(out, x) ^ data[i];
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add(a: u64, b: u64) -> u64 {
|
||||||
|
let (result, overflow) = a.overflowing_add(b);
|
||||||
|
result + overflow as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sub(x: u64, mut n: u64) -> u64 {
|
||||||
|
if x <= n {
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
x.wrapping_sub(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(all(target_arch = "x86_64", target_feature = "pclmulqdq")))]
|
||||||
|
fn xor_mul(a: u64, mut b: u64) -> u64 {
|
||||||
|
let mut x: u64 = 0;
|
||||||
|
while b != 0 {
|
||||||
|
let c = b.trailing_zeros();
|
||||||
|
b = b ^ 1u64.rotate_left(c);
|
||||||
|
x = x ^ a.rotate_left(c);
|
||||||
|
}
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(all(target_arch = "x86_64", target_feature = "pclmulqdq"))]
|
||||||
|
fn xor_mul(a: u64, b: u64) -> u64 {
|
||||||
|
use std::arch::x86_64::*;
|
||||||
|
unsafe {
|
||||||
|
let a_vec = _mm_set_epi64x(0, a as i64);
|
||||||
|
let b_vec = _mm_set_epi64x(0, b as i64);
|
||||||
|
let result = _mm_clmulepi64_si128(a_vec, b_vec, 0x00);
|
||||||
|
|
||||||
|
// Extract both 64-bit halves and XOR them
|
||||||
|
let low = _mm_extract_epi64(result, 0) as u64;
|
||||||
|
let high = _mm_extract_epi64(result, 1) as u64;
|
||||||
|
low ^ high
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/lib/challenges/mod.rs
Normal file
7
src/lib/challenges/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
pub mod c1_welcome;
|
||||||
|
pub mod c2_these_numbers_are_big;
|
||||||
|
pub mod c3_are_you_still_doing_this_by_hand;
|
||||||
|
pub mod c4_broken_proof_of_work;
|
||||||
|
pub mod c5_what_the_bf;
|
||||||
|
pub mod c6_automation_is_not_enough;
|
||||||
|
pub mod c7_weird_assembly_machine;
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
use anyhow::{Result, anyhow};
|
#![allow(dead_code)]
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
@@ -7,19 +8,41 @@ use std::thread;
|
|||||||
use std::thread::JoinHandle;
|
use std::thread::JoinHandle;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
pub mod challenges;
|
||||||
|
|
||||||
const USER_NAME: &str = "Jonah";
|
const USER_NAME: &str = "Jonah";
|
||||||
|
|
||||||
pub fn compute_async<T1: Display + Send + 'static, T2: Display + Send + 'static, R: Send + 'static>(mut function: impl FnMut(Sender<(T1, T2)>) -> R + Send + 'static ) -> R {
|
pub fn compute_async<
|
||||||
let (tx, jh1) = spawn_submission_thread();
|
T1: Display + Send + 'static,
|
||||||
let jh2 = thread::spawn(move || {
|
T2: Display + Send + 'static,
|
||||||
function(tx)
|
R: Send + 'static
|
||||||
});
|
>(
|
||||||
|
function: impl FnMut(Sender<(T1, T2)>) -> R + Send + 'static
|
||||||
jh1.join().unwrap();
|
) -> R {
|
||||||
jh2.join().unwrap()
|
compute_async_with_name(USER_NAME, function)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_submission_thread<T1: Display + Send + 'static, T2: Display + Send + 'static>() -> (Sender<(T1, T2)>, JoinHandle<()>) {
|
|
||||||
|
pub fn compute_async_with_name<
|
||||||
|
T1: Display + Send + 'static,
|
||||||
|
T2: Display + Send + 'static,
|
||||||
|
R: Send + 'static
|
||||||
|
>(
|
||||||
|
name: &'static str,
|
||||||
|
mut function: impl FnMut(Sender<(T1, T2)>) -> R + Send + 'static
|
||||||
|
) -> R {
|
||||||
|
let (tx, jh) = spawn_submission_thread(name);
|
||||||
|
let result = function(tx);
|
||||||
|
jh.join().unwrap();
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_submission_thread<
|
||||||
|
T1: Display + Send + 'static,
|
||||||
|
T2: Display + Send + 'static
|
||||||
|
>(
|
||||||
|
name: &'static str
|
||||||
|
) -> (Sender<(T1, T2)>, JoinHandle<()>) {
|
||||||
let (tx, rx) = mpsc::channel::<(T1, T2)>();
|
let (tx, rx) = mpsc::channel::<(T1, T2)>();
|
||||||
let handle = thread::spawn(move || {
|
let handle = thread::spawn(move || {
|
||||||
let mut t = Instant::now();
|
let mut t = Instant::now();
|
||||||
@@ -28,7 +51,7 @@ pub fn spawn_submission_thread<T1: Display + Send + 'static, T2: Display + Send
|
|||||||
println!("\nn = {n}\nx = {x}\nduration = {}", t2.duration_since(t).as_millis());
|
println!("\nn = {n}\nx = {x}\nduration = {}", t2.duration_since(t).as_millis());
|
||||||
t = t2;
|
t = t2;
|
||||||
|
|
||||||
match submit(n, x) {
|
match submit_with_name(name, n, x) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(err) => eprintln!("{:?}", err),
|
Err(err) => eprintln!("{:?}", err),
|
||||||
};
|
};
|
||||||
@@ -37,8 +60,23 @@ pub fn spawn_submission_thread<T1: Display + Send + 'static, T2: Display + Send
|
|||||||
(tx, handle)
|
(tx, handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn submit<T1: Display + Send, T2: Display + Send>(n: T1, x: T2) -> Result<Option<String>> {
|
pub fn submit<
|
||||||
let url = format!("https://button.qedaka.de/server.php?name={USER_NAME}&n={n}&x={x}");
|
T1: Display + Send,
|
||||||
|
T2: Display + Send
|
||||||
|
>(
|
||||||
|
n: T1, x: T2
|
||||||
|
) -> Result<Option<String>> {
|
||||||
|
submit_with_name(USER_NAME, n, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn submit_with_name<
|
||||||
|
T1: Display + Send,
|
||||||
|
T2: Display + Send
|
||||||
|
>(
|
||||||
|
name: &str, n: T1, x: T2
|
||||||
|
) -> Result<Option<String>> {
|
||||||
|
let name = percent_encoding::percent_encode(name.as_bytes(), percent_encoding::NON_ALPHANUMERIC);
|
||||||
|
let url = format!("https://button.qedaka.de/server.php?name={}&n={n}&x={x}", name);
|
||||||
let body = reqwest::blocking::get(url)?.text()?;
|
let body = reqwest::blocking::get(url)?.text()?;
|
||||||
match json::parse(&body)? {
|
match json::parse(&body)? {
|
||||||
JsonValue::Object(obj) => {
|
JsonValue::Object(obj) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user