use crate::natural::Natural;
use crate::natural_vector::NaturalVector;
use crate::platform::Limb;
use alloc::vec;
use alloc::vec::Vec;
use malachite_base::num::basic::traits::Zero;
use malachite_base::unsigned_vector::UnsignedVector;
pub(crate) fn naturals_and_columns(
moduli: &[Limb],
residues: &[UnsignedVector<Limb>],
) -> Option<(Vec<Natural>, Vec<Vec<Natural>>)> {
let moduli: Vec<Natural> = moduli.iter().copied().map(Natural::from).collect();
Natural::multi_crt(&moduli, &vec![Natural::ZERO; moduli.len()])?;
let columns = (0..residues[0].elements.len())
.map(|i| {
residues
.iter()
.map(|rs| Natural::from(rs.elements[i]))
.collect()
})
.collect();
Some((moduli, columns))
}
pub fn natural_vector_multi_crt_naive(
moduli: &[Limb],
residues: &[UnsignedVector<Limb>],
) -> Option<NaturalVector> {
let (moduli, columns) = naturals_and_columns(moduli, residues)?;
Some(NaturalVector {
elements: columns
.iter()
.map(|column| Natural::multi_crt(&moduli, column))
.collect::<Option<_>>()?,
})
}