Path: blob/main/foundations/02-rings-fields-polynomials/rust/src/lib.rs
483 views
unlisted
//! # Module 02: Rings, Fields, and Polynomials — Exercises1//!2//! Polynomials are `Vec<u64>` where index = degree: `vec![3, 0, 2]` = 2x² + 3.3//! All arithmetic is mod `p`.4//!5//! ## Progression6//! 1. `poly_eval` — Guided (Horner's method skeleton)7//! 2. `poly_add` — Guided (zip/pad approach)8//! 3. `poly_mul` — Scaffolded (convolution hint)9//! 4. `poly_div_rem` — Scaffolded (long division outline)10//! 5. `is_irreducible_mod_p` — Independent1112/// Evaluate polynomial at `x` mod `p` using Horner's method.13///14/// # Example15/// ```16/// # use rings_fields_poly::poly_eval;17/// assert_eq!(poly_eval(&[1, 2, 3], 5, 7), 2); // 1 + 10 + 75 = 86 ≡ 2 mod 718/// ```19pub fn poly_eval(coeffs: &[u64], x: u64, p: u64) -> u64 {20// Horner's method: iterate from highest degree to lowest.21// result = 022// for coeff in coeffs.iter().rev():23// result = (result * x + coeff) % p24let mut result: u64 = 0;25for &coeff in coeffs.iter().rev() {26// TODO: result = (result * x + coeff) % p27// Use u128 to avoid overflow.28todo!("Horner step")29}30result31}3233/// Add two polynomials coefficient-wise mod `p`. Trim trailing zeros.34pub fn poly_add(a: &[u64], b: &[u64], p: u64) -> Vec<u64> {35// Hint: result length = max(a.len(), b.len())36// Add corresponding coefficients mod p, then trim.37todo!("Add polynomials mod p")38}3940/// Multiply two polynomials mod `p` via convolution.41///42/// Coefficient of x^k = Σ a[i] * b[k-i] mod p for valid indices.43pub fn poly_mul(a: &[u64], b: &[u64], p: u64) -> Vec<u64> {44todo!("Polynomial convolution mod p")45}4647/// Polynomial long division: returns (quotient, remainder) mod `p`.48///49/// You'll need modular inverse of the leading coefficient of `b`.50pub fn poly_div_rem(a: &[u64], b: &[u64], p: u64) -> (Vec<u64>, Vec<u64>) {51todo!("Polynomial long division mod p")52}5354/// Check if polynomial is irreducible over Z/pZ by trial division.55///56/// Try all monic polynomials of degree 1..=deg/2. If none divide evenly,57/// the polynomial is irreducible.58pub fn is_irreducible_mod_p(coeffs: &[u64], p: u64) -> bool {59todo!("Brute-force irreducibility check")60}6162fn trim_poly(v: &mut Vec<u64>) {63while v.len() > 1 && *v.last().unwrap() == 0 {64v.pop();65}66}6768#[cfg(test)]69mod tests {70use super::*;7172#[test]73#[ignore]74fn test_poly_eval_basic() {75assert_eq!(poly_eval(&[1, 2, 3], 5, 7), 2);76}7778#[test]79#[ignore]80fn test_poly_eval_constant() {81assert_eq!(poly_eval(&[42], 999, 7), 0);82}8384#[test]85#[ignore]86fn test_poly_add_same_degree() {87assert_eq!(poly_add(&[1, 2, 3], &[4, 5, 6], 7), vec![5, 0, 2]);88}8990#[test]91#[ignore]92fn test_poly_add_different_degree() {93assert_eq!(poly_add(&[1, 2], &[3, 0, 1], 7), vec![4, 2, 1]);94}9596#[test]97#[ignore]98fn test_poly_mul_linear() {99assert_eq!(poly_mul(&[1, 1], &[1, 1], 7), vec![1, 2, 1]);100}101102#[test]103#[ignore]104fn test_poly_mul_mod() {105assert_eq!(poly_mul(&[3, 4], &[2, 5], 7), vec![6, 2, 6]);106}107108#[test]109#[ignore]110fn test_poly_div_rem_exact() {111let (q, r) = poly_div_rem(&[1, 2, 1], &[1, 1], 7);112assert_eq!(q, vec![1, 1]);113assert_eq!(r, vec![0]);114}115116#[test]117#[ignore]118fn test_irreducible_true() {119assert!(is_irreducible_mod_p(&[1, 1, 1], 2));120}121122#[test]123#[ignore]124fn test_irreducible_false() {125assert!(!is_irreducible_mod_p(&[1, 0, 1], 2));126}127}128129130