use std::panic;
#[derive(Debug, Clone)]
pub struct Polynomial {
pub coeffs: Vec<i64>, }
impl Polynomial {
pub fn new(coeffs: Vec<i64>) -> Self {
Polynomial { coeffs }
}
pub fn decode(&self) -> Vec<i64> {
self.coeffs.iter().map(|&c| {
let real = (c as f64) / 10_000_000.0;
real.round() as i64 }).collect()
}
pub fn add(&self, other: &Polynomial) -> Polynomial {
let len = self.coeffs.len().max(other.coeffs.len());
let mut result = vec![0; len];
for i in 0..len {
let a = if i < self.coeffs.len() { self.coeffs[i] } else { 0 }; let b = if i < other.coeffs.len() { other.coeffs[i] } else { 0 }; result[i] = a + b; }
Polynomial::new(result) }
pub fn subtract(&self, other: &Polynomial) -> Polynomial {
let len = self.coeffs.len().max(other.coeffs.len());
let mut result = vec![0; len];
for i in 0..len {
let a = if i < self.coeffs.len() { self.coeffs[i] } else { 0 }; let b = if i < other.coeffs.len() { other.coeffs[i] } else { 0 }; result[i] = a - b; }
Polynomial::new(result) }
pub fn multiply(&self, other: &Polynomial) -> Polynomial {
let result_size = self.coeffs.len().max(other.coeffs.len());
let mut result_coeffs = vec![0.0; result_size];
let min_len = self.coeffs.len().min(other.coeffs.len());
for i in 0..min_len {
result_coeffs[i] = (self.coeffs[i] as f64 * other.coeffs[i] as f64) / 1e7; }
Polynomial::new(result_coeffs.iter().map(|&x| x.round() as i64).collect())
}
pub fn negation(&self) -> Polynomial {
let negated_coeffs: Vec<f64> = self.coeffs.iter().map(|&c| -(c as f64)).collect();
Polynomial::new(negated_coeffs.iter().map(|&x| x.round() as i64).collect())
}
pub fn divide(&self, divisor: &Polynomial, scaling_factor: f64) -> Polynomial {
let mut result_coeffs = Vec::new();
if divisor.coeffs.len() == 1 {
let scalar = divisor.coeffs[0];
if scalar == 0 {
eprintln!("Division by zero encountered in scalar divisor. Skipping computation.");
return Polynomial::new(vec![]); }
for a in &self.coeffs {
let result = panic::catch_unwind(|| {
let scaled_result = (*a as f64 / scalar as f64) * scaling_factor;
scaled_result.round() as i64
});
match result {
Ok(value) => result_coeffs.push(value),
Err(_) => {
eprintln!("Panic occurred during scalar division. Skipping coefficient.");
result_coeffs.push(0); }
}
}
} else {
for i in 0..std::cmp::max(self.coeffs.len(), divisor.coeffs.len()) {
let a = self.coeffs.get(i).copied().unwrap_or(0); let b = divisor.coeffs.get(i).copied().unwrap_or(0);
if b == 0 {
eprintln!(
"Division by zero encountered at index {}. Defaulting to 0.",
i
);
result_coeffs.push(0);
continue;
}
let result = panic::catch_unwind(|| {
let scaled_result = (a as f64 / b as f64) * scaling_factor;
scaled_result.round() as i64
});
match result {
Ok(value) => result_coeffs.push(value),
Err(_) => {
eprintln!("Panic occurred during polynomial division at index {}. Defaulting to 0.", i);
result_coeffs.push(0); }
}
}
}
Polynomial::new(result_coeffs)
}
}