[06_automation_is_not_enough] add solution
This commit is contained in:
@@ -8,6 +8,7 @@ anyhow = "1.0.99"
|
|||||||
json = "0.12.4"
|
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"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "lib"
|
name = "lib"
|
||||||
|
|||||||
65538
res/06_faulhaber_coefficient_65537.log
Normal file
65538
res/06_faulhaber_coefficient_65537.log
Normal file
File diff suppressed because it is too large
Load Diff
159
src/bin/06_automation_is_not_enough.rs
Normal file
159
src/bin/06_automation_is_not_enough.rs
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader};
|
||||||
|
use rug::ops::MulFrom;
|
||||||
|
use rug::{Assign, Integer};
|
||||||
|
use std::ops::Add;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::sync::LazyLock;
|
||||||
|
use lib::submit;
|
||||||
|
|
||||||
|
static N0: LazyLock<Integer> = LazyLock::new(|| Integer::from(1001997000002u128));
|
||||||
|
static X0: LazyLock<Integer> = LazyLock::new(|| Integer::from_str("13361120425250501347832030920224855036595311511513374827901659942687569213067904382419070310529480239935839308518100143939024253857202176158254361885679515473530816156355117821922648901555956036125537445852483998567339002752976575910942962150").unwrap());
|
||||||
|
|
||||||
|
static N1: LazyLock<Integer> = LazyLock::new(|| Integer::from(1774734677598263u128));
|
||||||
|
static X1: LazyLock<Integer> = LazyLock::new(|| Integer::from_str("11593323295292067533341930289979269834079920106030434522240627836294015987043679078861672344892723053626369715841527508395668434915559610809835295347647318767117730544084796074700752732601302352244011354650441946234192592199510139121367920997").unwrap());
|
||||||
|
|
||||||
|
static M: LazyLock<Integer> = LazyLock::new(|| Integer::from_str("14004392365098131090160062970945115111185775413941111064876648140973294115502980816410773368597517292734034227298996122159833675150497554142801209096513652073059992938078366061434391648276904643753267405058183481162693381822800709938988762923").unwrap());
|
||||||
|
static E: LazyLock<Integer> = LazyLock::new(|| Integer::from(65537));
|
||||||
|
|
||||||
|
static A: LazyLock<Integer> = LazyLock::new(|| Integer::from_str("1466928606874115117499939299261").unwrap());
|
||||||
|
static B: LazyLock<Integer> = LazyLock::new(|| Integer::from_str("49119078231137394008451554322").unwrap());
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let f = faulhaber_formula_from_file("res/06_faulhaber_coefficient_65537.log").unwrap();
|
||||||
|
|
||||||
|
let n: Integer = Integer::from(10000000000000000u128);
|
||||||
|
let x = (X1.clone() + f(n.clone()) - f(N1.clone())).modulo(&M);
|
||||||
|
println!("{:?}", x);
|
||||||
|
println!("{:?}", submit(n, x).unwrap());
|
||||||
|
|
||||||
|
// Use the submission server as an oracle to find the `n` at which `x` needs to be doubles.
|
||||||
|
// let (mut low, mut high) = (
|
||||||
|
// Integer::from(1774734677598262u128),
|
||||||
|
// Integer::from(1774734677598263u128),
|
||||||
|
// );
|
||||||
|
// while low != high {
|
||||||
|
// assert!(low < high);
|
||||||
|
// let mid: Integer = (high.clone() + low.clone()) / 2;
|
||||||
|
// let x = (X1.clone() + f(mid.clone()) - f(N1.clone())).modulo(&M);
|
||||||
|
//
|
||||||
|
// (low, high) = match submit(mid.clone(), x.clone()) {
|
||||||
|
// Ok(_) => {
|
||||||
|
// println!("n = {}", mid);
|
||||||
|
// println!("x = {}", x);
|
||||||
|
// (mid, high)
|
||||||
|
// },
|
||||||
|
// Err(_) => (low, mid),
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes one step of the challenge.
|
||||||
|
fn step(mut n: Integer, mut x: Integer) -> (Integer, Integer) {
|
||||||
|
n += 1;
|
||||||
|
|
||||||
|
let b: &Integer = &B;
|
||||||
|
|
||||||
|
// a = pow(n, e, m)
|
||||||
|
let a = n.clone().pow_mod(&E, &M).unwrap();
|
||||||
|
|
||||||
|
// if (a % A == b) {
|
||||||
|
if a.clone().modulo(&A).eq(b) {
|
||||||
|
// x += x
|
||||||
|
x *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// x += a
|
||||||
|
// x %= m
|
||||||
|
x = x.add(&a).modulo(&M);
|
||||||
|
|
||||||
|
(n, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn faulhaber_formula(n: usize) -> impl Fn(Integer) -> Integer {
|
||||||
|
let coefficients = faulhaber_triangle(n);
|
||||||
|
for (i, coeff) in coefficients.iter().enumerate() {
|
||||||
|
println!("{i} = {coeff}");
|
||||||
|
}
|
||||||
|
faulhaber_formula_from_coefficients(coefficients)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn faulhaber_formula_from_file(path: &str) -> Result<impl Fn(Integer) -> Integer> {
|
||||||
|
let mut coefficients = Vec::new();
|
||||||
|
|
||||||
|
let file = File::open(path)?;
|
||||||
|
let reader = BufReader::new(file);
|
||||||
|
for line in reader.lines() {
|
||||||
|
coefficients.push(Integer::from_str(&line?)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("{:?}", coefficients.len());
|
||||||
|
|
||||||
|
let mut sum = coefficients.iter().fold(Integer::from(0), Integer::add);
|
||||||
|
sum.modulo_mut(&M);
|
||||||
|
println!("{:?}", sum);
|
||||||
|
|
||||||
|
Ok(faulhaber_formula_from_coefficients(coefficients))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn faulhaber_formula_from_coefficients(coefficients: Vec<Integer>) -> impl Fn(Integer) -> Integer {
|
||||||
|
move |x| {
|
||||||
|
let mut result = Integer::from(0);
|
||||||
|
let mut temp = Integer::from(0);
|
||||||
|
let mut y = x.clone();
|
||||||
|
|
||||||
|
for coeff in coefficients.iter() {
|
||||||
|
temp.assign(&y);
|
||||||
|
temp.mul_from(coeff);
|
||||||
|
|
||||||
|
result += &temp;
|
||||||
|
result.modulo_mut(&M);
|
||||||
|
|
||||||
|
y *= &x;
|
||||||
|
y.modulo_mut(&M);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Computes the coefficients of the Faulhaber's formula.
|
||||||
|
fn faulhaber_triangle(n: usize) -> Vec<Integer> {
|
||||||
|
let neg1 = Integer::from(-1);
|
||||||
|
let mut inv = Vec::with_capacity(n + 10);
|
||||||
|
inv.push(Integer::from(0));
|
||||||
|
for i in 1..n+10 {
|
||||||
|
inv.push(Integer::from(i).pow_mod(&neg1, &M).unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut previous = vec![Integer::from(1)];
|
||||||
|
|
||||||
|
for i in tqdm::tqdm(1..=n) {
|
||||||
|
let mut row = Vec::with_capacity(i + 1);
|
||||||
|
row.push(Integer::from(0));
|
||||||
|
|
||||||
|
let mut sum = Integer::from(1);
|
||||||
|
|
||||||
|
for j in 1..=i {
|
||||||
|
let mut value = (&previous[j - 1]).clone();
|
||||||
|
value.mul_from(i);
|
||||||
|
value.modulo_mut(&M);
|
||||||
|
value.mul_from(&inv[j + 1]);
|
||||||
|
value.modulo_mut(&M);
|
||||||
|
|
||||||
|
sum -= &value;
|
||||||
|
|
||||||
|
row.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sum.modulo_mut(&M);
|
||||||
|
row[0] = sum;
|
||||||
|
|
||||||
|
previous = row;
|
||||||
|
}
|
||||||
|
|
||||||
|
previous
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user