solve all previous levels
This commit is contained in:
@@ -11,6 +11,8 @@ reqwest = { version = "0.12.23", features = ["blocking"] }
|
|||||||
rug = "1.28.0"
|
rug = "1.28.0"
|
||||||
rand = "0.9.2"
|
rand = "0.9.2"
|
||||||
tqdm = "0.8.0"
|
tqdm = "0.8.0"
|
||||||
|
sha2 = "0.10.9"
|
||||||
|
percent-encoding = "2.3.2"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "lib"
|
name = "lib"
|
||||||
|
@@ -1,125 +1,12 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use lib::submit;
|
use lib::submit;
|
||||||
use std::fs::File;
|
use lib::challenges::c7_weird_assembly_machine::f_n;
|
||||||
use std::io::{BufRead, BufReader};
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
lazy_static!(
|
|
||||||
static ref DATA: Vec<u64> = {
|
|
||||||
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 N: u64 = 979607657800000055;
|
const N: u64 = 979607657800000055;
|
||||||
const X: u64 = 10962444957429324784;
|
const X: u64 = 10962444957429324784;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
fn sum(n: u64, k: u64) -> u64 {
|
let (n, x) = f_n(N, X, 1_000_000_000_000_000_000u64 - N);
|
||||||
let mut sum = 0u64;
|
|
||||||
for i in 1..=k {
|
|
||||||
sum = add(sum, fg_n(n + i, k - i));
|
|
||||||
}
|
|
||||||
sum
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fast_sum(n: u64, k: u64) -> u64 {
|
|
||||||
debug_assert!(k % 192 == 0);
|
|
||||||
let mut result = sum(n, 0);
|
|
||||||
result = add(result, ((13556435138434861179u128 * (k / 192) as u128) % (u64::MAX as u128)) as u64);
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut n = N;
|
|
||||||
let mut x = X;
|
|
||||||
|
|
||||||
n += 1;
|
|
||||||
x = sub(f(x), n);
|
|
||||||
|
|
||||||
let k = (1_000_000_000_000_000_000u64 - n) / 192 * 192;
|
|
||||||
let sum = fast_sum(n , k);
|
|
||||||
x = sub(fg_n(x, k), sum);
|
|
||||||
n += k;
|
|
||||||
|
|
||||||
x = g(x);
|
|
||||||
|
|
||||||
submit(n, x).unwrap();
|
|
||||||
println!("n = {n}");
|
println!("n = {n}");
|
||||||
println!("x = {x}");
|
println!("x = {x}");
|
||||||
}
|
submit(n, x).unwrap();
|
||||||
|
|
||||||
fn f(x: u64) -> u64 {
|
|
||||||
evaluate(x, &DATA[..128], &DATA[..128])
|
|
||||||
}
|
|
||||||
|
|
||||||
fn g(x: u64) -> u64 {
|
|
||||||
evaluate(x, &DATA[128..], &DATA[128..])
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fg(x: u64) -> u64 {
|
|
||||||
!x.rotate_left(17)
|
|
||||||
// evaluate(x, FG_DATA_EVEN, FG_DATA_ODD)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fg_n(mut x: u64, n: u64) -> u64 {
|
|
||||||
for _ in 0..n%64 {
|
|
||||||
x = fg(x);
|
|
||||||
}
|
|
||||||
x
|
|
||||||
}
|
|
||||||
|
|
||||||
fn evaluate(x: u64, data_even: &[u64], data_odd: &[u64]) -> u64 {
|
|
||||||
let data = if x.count_ones() % 2 == 0 { data_even } else { data_odd };
|
|
||||||
|
|
||||||
let mut out = 0;
|
|
||||||
for i in 0..data.len() {
|
|
||||||
out = xor_mul(out, x) ^ data[i];
|
|
||||||
}
|
|
||||||
out
|
|
||||||
}
|
|
||||||
|
|
||||||
#[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
|
|
||||||
}
|
|
||||||
}
|
}
|
26
src/bin/main.rs
Normal file
26
src/bin/main.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use lib::submit_with_name;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let name = "((ο)=>((o)=>o(((o(((ο*o([!+[]+!+";
|
||||||
|
|
||||||
|
let (n, x) = lib::challenges::c1_welcome::solve();
|
||||||
|
println!("n = {:?}\nx = {:?}\n{:?}\n", n, x, submit_with_name(name, n, x));
|
||||||
|
|
||||||
|
let (n, x) = lib::challenges::c2_these_numbers_are_big::solve(name);
|
||||||
|
println!("n = {:?}\nx = {:?}\n{:?}\n", n, x, submit_with_name(name, n, x.clone()));
|
||||||
|
|
||||||
|
let (n, x) = lib::challenges::c3_are_you_still_doing_this_by_hand::solve(n, x);
|
||||||
|
println!("n = {:?}\nx = {:?}\n{:?}\n", n, x, submit_with_name(name, n, x.clone()));
|
||||||
|
|
||||||
|
let (n, x) = lib::challenges::c4_broken_proof_of_work::solve(n, x);
|
||||||
|
println!("n = {:?}\nx = {:?}\n{:?}\n", n, x, submit_with_name(name, n, x.clone()));
|
||||||
|
|
||||||
|
let (n, x) = lib::challenges::c5_what_the_bf::solve(n, x);
|
||||||
|
println!("n = {:?}\nx = {:?}\n{:?}\n", n, x, submit_with_name(name, n, x.clone()));
|
||||||
|
|
||||||
|
let (n, x) = lib::challenges::c6_automation_is_not_enough::solve(n, x);
|
||||||
|
println!("n = {:?}\nx = {:?}\n{:?}\n", n, x, submit_with_name(name, n, x.clone()));
|
||||||
|
|
||||||
|
let (n, x) = lib::challenges::c7_weird_assembly_machine::solve(n, x);
|
||||||
|
println!("n = {:?}\nx = {:?}\n{:?}\n", n, x, submit_with_name(name, n, x.clone()));
|
||||||
|
}
|
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)
|
||||||
|
}
|
26
src/lib/challenges/c2_these_numbers_are_big.rs
Normal file
26
src/lib/challenges/c2_these_numbers_are_big.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use rug::Integer;
|
||||||
|
use rug::integer::Order;
|
||||||
|
use sha2::{Sha256, Digest};
|
||||||
|
|
||||||
|
lazy_static!(
|
||||||
|
static ref M: Integer = Integer::from_str("14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923").unwrap();
|
||||||
|
static ref E: Integer = Integer::from(65537);
|
||||||
|
);
|
||||||
|
|
||||||
|
pub fn solve(name: &str) -> (u64, Integer) {
|
||||||
|
let mut x = sha256(name);
|
||||||
|
println!("sha256 = {x}");
|
||||||
|
x += 4;
|
||||||
|
for _ in tqdm::tqdm(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)
|
||||||
|
}
|
87
src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs
Normal file
87
src/lib/challenges/c3_are_you_still_doing_this_by_hand.rs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
use rug::Integer;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use tqdm::tqdm;
|
||||||
|
|
||||||
|
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))
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
fn f(mut x: u128) -> u128 {
|
||||||
|
x = x * A % B;
|
||||||
|
x = (x * C + D) / B;
|
||||||
|
x
|
||||||
|
}
|
26
src/lib/challenges/c6_automation_is_not_enough.rs
Normal file
26
src/lib/challenges/c6_automation_is_not_enough.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
use lazy_static::lazy_static;
|
||||||
|
use rug::Integer;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
const START: u64 = 1_000_000_000_000u64;
|
||||||
|
const LIMIT: u64 = 10_000_000_000_000_000u64;
|
||||||
|
|
||||||
|
lazy_static!(
|
||||||
|
static ref M: Integer = Integer::from_str("14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923").unwrap();
|
||||||
|
static ref A: Integer = Integer::from_str("10729297455904899337681752672816753703351288544833760635567859176397566160330812285369370751389224534974913042757043771146367160829669925123791471756026119030734890865062863499420767799283504416995775836275660636668989077836006690621539265605").unwrap();
|
||||||
|
static ref B: Integer = Integer::from_str("4997609466256208183077203585670710326160976219126614124062259398288517298185253986607627790890962248558793881836308854443463332741665631247256917127102588793451033551034614994254514161235462726178612824897626185944163885786520174491419225456").unwrap();
|
||||||
|
);
|
||||||
|
|
||||||
|
pub fn solve(n: u64, x: Integer) -> (u64, Integer) {
|
||||||
|
assert_eq!(n, START);
|
||||||
|
let m: &Integer = &M;
|
||||||
|
let a: &Integer = &A;
|
||||||
|
let b: &Integer = &B;
|
||||||
|
|
||||||
|
let mut x = x;
|
||||||
|
x = (x + a) % m;
|
||||||
|
x = x * 2 % m;
|
||||||
|
x = (x + b) % m;
|
||||||
|
|
||||||
|
(LIMIT, x)
|
||||||
|
}
|
128
src/lib/challenges/c7_weird_assembly_machine.rs
Normal file
128
src/lib/challenges/c7_weird_assembly_machine.rs
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
|
use std::str::FromStr;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use rug::Integer;
|
||||||
|
|
||||||
|
lazy_static!(
|
||||||
|
static ref DATA: Vec<u64> = {
|
||||||
|
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) = f_n(n, x, LIMIT - n);
|
||||||
|
(n, Integer::from(x))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn f_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 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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f(x: u64) -> u64 {
|
||||||
|
evaluate(x, &DATA[..128], &DATA[..128])
|
||||||
|
}
|
||||||
|
|
||||||
|
fn g(x: u64) -> u64 {
|
||||||
|
evaluate(x, &DATA[128..], &DATA[128..])
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fg(x: u64) -> u64 {
|
||||||
|
!x.rotate_left(17)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fg_n(mut x: u64, n: u64) -> u64 {
|
||||||
|
for _ in 0..n%64 {
|
||||||
|
x = fg(x);
|
||||||
|
}
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
|
fn evaluate(x: u64, data_even: &[u64], data_odd: &[u64]) -> u64 {
|
||||||
|
let data = if x.count_ones() % 2 == 0 { data_even } else { data_odd };
|
||||||
|
|
||||||
|
let mut out = 0;
|
||||||
|
for i in 0..data.len() {
|
||||||
|
out = xor_mul(out, x) ^ data[i];
|
||||||
|
}
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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,4 @@
|
|||||||
use anyhow::{Result, anyhow};
|
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,10 +7,17 @@ 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<T: Display + Send + 'static, R: Send + 'static>(mut function: impl FnMut(Sender<(T, T)>) -> R + Send + 'static ) -> R {
|
pub fn compute_async<T1: Display + Send + 'static, T2: Display + Send + 'static, R: Send + 'static>(function: impl FnMut(Sender<(T1, T2)>) -> R + Send + 'static ) -> R {
|
||||||
let (tx, jh1) = spawn_submission_thread();
|
compute_async_with_name(USER_NAME, function)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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, jh1) = spawn_submission_thread(name);
|
||||||
let jh2 = thread::spawn(move || {
|
let jh2 = thread::spawn(move || {
|
||||||
function(tx)
|
function(tx)
|
||||||
});
|
});
|
||||||
@@ -19,8 +26,8 @@ pub fn compute_async<T: Display + Send + 'static, R: Send + 'static>(mut functio
|
|||||||
jh2.join().unwrap()
|
jh2.join().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_submission_thread<T: Display + Send + 'static>() -> (Sender<(T, T)>, JoinHandle<()>) {
|
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::<(T, T)>();
|
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();
|
||||||
for (n, x) in rx {
|
for (n, x) in rx {
|
||||||
@@ -28,7 +35,7 @@ pub fn spawn_submission_thread<T: Display + Send + 'static>() -> (Sender<(T, T)>
|
|||||||
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 +44,13 @@ pub fn spawn_submission_thread<T: Display + Send + 'static>() -> (Sender<(T, T)>
|
|||||||
(tx, handle)
|
(tx, handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn submit<T: Display + Send>(n: T, x: T) -> Result<Option<String>> {
|
pub fn submit<T1: Display + Send, T2: Display + Send>(n: T1, x: T2) -> Result<Option<String>> {
|
||||||
let url = format!("https://button.qedaka.de/server.php?name={USER_NAME}&n={n}&x={x}");
|
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