solve all previous levels

This commit is contained in:
2025-09-12 01:26:50 +02:00
parent 1a3f5bb015
commit eea37dcd31
12 changed files with 378 additions and 124 deletions

View File

@@ -1,125 +1,12 @@
#![allow(dead_code)]
use lazy_static::lazy_static;
use lib::submit;
use std::fs::File;
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
};
);
use lib::challenges::c7_weird_assembly_machine::f_n;
const N: u64 = 979607657800000055;
const X: u64 = 10962444957429324784;
fn main() {
fn 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_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();
let (n, x) = f_n(N, X, 1_000_000_000_000_000_000u64 - N);
println!("n = {n}");
println!("x = {x}");
}
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
}
submit(n, x).unwrap();
}