extern crate alloc;
use alloc::vec::Vec;
use core::cmp::Ordering;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ExactRational {
numerator: i128,
denominator: i128,
}
fn gcd(a: i128, b: i128) -> i128 {
let (mut a, mut b) = (a.abs(), b.abs());
while b != 0 {
let t = b;
b = a % b;
a = t;
}
if a == 0 {
1
} else {
a
}
}
impl ExactRational {
pub const ZERO: Self = Self {
numerator: 0,
denominator: 1,
};
pub const ONE: Self = Self {
numerator: 1,
denominator: 1,
};
#[must_use]
pub fn new(numerator: i128, denominator: i128) -> Self {
debug_assert!(denominator != 0, "ExactRational: zero denominator");
let sign = if denominator < 0 { -1 } else { 1 };
let n = numerator * sign;
let d = denominator * sign;
let g = gcd(n, d);
Self {
numerator: n / g,
denominator: d / g,
}
}
#[must_use]
pub fn from_int(n: i128) -> Self {
Self {
numerator: n,
denominator: 1,
}
}
#[must_use]
pub fn numerator(self) -> i128 {
self.numerator
}
#[must_use]
pub fn denominator(self) -> i128 {
self.denominator
}
#[must_use]
pub fn is_zero(self) -> bool {
self.numerator == 0
}
#[must_use]
pub fn checked_add(self, other: Self) -> Option<Self> {
let n = self
.numerator
.checked_mul(other.denominator)?
.checked_add(other.numerator.checked_mul(self.denominator)?)?;
let d = self.denominator.checked_mul(other.denominator)?;
Some(Self::new(n, d))
}
#[must_use]
pub fn checked_div(self, other: Self) -> Option<Self> {
if other.numerator == 0 {
return None;
}
let n = self.numerator.checked_mul(other.denominator)?;
let d = self.denominator.checked_mul(other.numerator)?;
Some(Self::new(n, d))
}
#[must_use]
pub fn checked_square(self) -> Option<Self> {
let n = self.numerator.checked_mul(self.numerator)?;
let d = self.denominator.checked_mul(self.denominator)?;
Some(Self::new(n, d))
}
#[must_use]
pub fn checked_recip(self) -> Option<Self> {
if self.numerator == 0 {
return None;
}
Some(Self::new(self.denominator, self.numerator))
}
#[must_use]
pub fn to_q16_16_bits_round(self) -> u32 {
let scaled_num = self.numerator * 65536;
let doubled_num = scaled_num * 2 + self.denominator;
let doubled_den = self.denominator * 2;
let mut q = doubled_num / doubled_den;
if q < 0 {
q = 0;
}
if q > i128::from(u32::MAX) {
u32::MAX
} else {
q as u32
}
}
}
impl PartialOrd for ExactRational {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for ExactRational {
fn cmp(&self, other: &Self) -> Ordering {
(self.numerator * other.denominator).cmp(&(other.numerator * self.denominator))
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReferenceLens {
RareTwo,
RareOne,
Coverage,
Proportional,
ExploitTwo,
}
impl ReferenceLens {
#[must_use]
pub fn is_negative(self) -> bool {
matches!(self, ReferenceLens::RareTwo | ReferenceLens::RareOne)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReferenceEscortRefusal {
EmptyDomain,
ZeroMassUnderNegativeLens,
ZeroSupport,
ZeroPartitionSum,
ExactArithmeticOverflow,
}
fn raw_weight(lens: ReferenceLens, m: u64) -> Option<ExactRational> {
let m_rat = ExactRational::from_int(i128::from(m));
match lens {
ReferenceLens::RareTwo => {
let sq = m_rat.checked_square()?;
ExactRational::ONE.checked_div(sq)
}
ReferenceLens::RareOne => ExactRational::ONE.checked_div(m_rat),
ReferenceLens::Coverage => {
if m == 0 {
Some(ExactRational::ZERO)
} else {
Some(ExactRational::ONE)
}
}
ReferenceLens::Proportional => Some(m_rat),
ReferenceLens::ExploitTwo => m_rat.checked_square(),
}
}
pub fn escort(
lens: ReferenceLens,
masses: &[u64],
) -> Result<Vec<ExactRational>, ReferenceEscortRefusal> {
if masses.is_empty() {
return Err(ReferenceEscortRefusal::EmptyDomain);
}
if lens.is_negative() && masses.contains(&0) {
return Err(ReferenceEscortRefusal::ZeroMassUnderNegativeLens);
}
if masses.iter().all(|&m| m == 0) {
return Err(match lens {
ReferenceLens::Coverage => ReferenceEscortRefusal::ZeroSupport,
_ => ReferenceEscortRefusal::ZeroPartitionSum,
});
}
let mut weights: Vec<ExactRational> = Vec::with_capacity(masses.len());
for &m in masses {
let w = raw_weight(lens, m).ok_or(ReferenceEscortRefusal::ExactArithmeticOverflow)?;
weights.push(w);
}
let mut sum = ExactRational::ZERO;
for &w in &weights {
sum = sum
.checked_add(w)
.ok_or(ReferenceEscortRefusal::ExactArithmeticOverflow)?;
}
if sum.is_zero() {
return Err(ReferenceEscortRefusal::ZeroPartitionSum);
}
let mut out = Vec::with_capacity(weights.len());
for w in weights {
let share = w
.checked_div(sum)
.ok_or(ReferenceEscortRefusal::ExactArithmeticOverflow)?;
out.push(share);
}
Ok(out)
}
pub fn uniform_sibling_coverage(
masses: &[u64],
) -> Result<Vec<ExactRational>, ReferenceEscortRefusal> {
if masses.is_empty() {
return Err(ReferenceEscortRefusal::EmptyDomain);
}
let n = ExactRational::from_int(masses.len() as i128);
let w = ExactRational::ONE
.checked_div(n)
.expect("masses is nonempty, so n != 0");
Ok(masses.iter().map(|_| w).collect())
}
#[cfg(test)]
mod tests {
use super::*;
fn r(n: i128, d: i128) -> ExactRational {
ExactRational::new(n, d)
}
#[test]
fn proportional_1234_matches_lean_golden_vector() {
let out = escort(ReferenceLens::Proportional, &[1, 2, 3, 4]).unwrap();
assert_eq!(out, alloc::vec![r(1, 10), r(2, 10), r(3, 10), r(4, 10)]);
}
#[test]
fn exploit2_1234_matches_lean_golden_vector() {
let out = escort(ReferenceLens::ExploitTwo, &[1, 2, 3, 4]).unwrap();
assert_eq!(out, alloc::vec![r(1, 30), r(4, 30), r(9, 30), r(16, 30)]);
}
#[test]
fn coverage_1234_matches_lean_golden_vector() {
let out = escort(ReferenceLens::Coverage, &[1, 2, 3, 4]).unwrap();
assert_eq!(out, alloc::vec![r(1, 4), r(1, 4), r(1, 4), r(1, 4)]);
}
#[test]
fn rare1_1234_matches_lean_golden_vector() {
let out = escort(ReferenceLens::RareOne, &[1, 2, 3, 4]).unwrap();
assert_eq!(out, alloc::vec![r(12, 25), r(6, 25), r(4, 25), r(3, 25)]);
}
#[test]
fn rare2_1234_matches_lean_golden_vector() {
let out = escort(ReferenceLens::RareTwo, &[1, 2, 3, 4]).unwrap();
assert_eq!(
out,
alloc::vec![r(144, 205), r(36, 205), r(16, 205), r(9, 205)]
);
}
#[test]
fn proportional_123_matches_lean_golden_vector() {
let out = escort(ReferenceLens::Proportional, &[1, 2, 3]).unwrap();
assert_eq!(out, alloc::vec![r(1, 6), r(2, 6), r(3, 6)]);
}
#[test]
fn coverage_013_excludes_zero_mass_support() {
let out = escort(ReferenceLens::Coverage, &[0, 1, 3]).unwrap();
assert_eq!(out, alloc::vec![r(0, 1), r(1, 2), r(1, 2)]);
}
#[test]
fn uniform_sibling_coverage_013_includes_zero_mass() {
let out = uniform_sibling_coverage(&[0, 1, 3]).unwrap();
assert_eq!(out, alloc::vec![r(1, 3), r(1, 3), r(1, 3)]);
}
#[test]
fn coverage_all_zero_refuses_with_zero_support() {
assert_eq!(
escort(ReferenceLens::Coverage, &[0, 0]),
Err(ReferenceEscortRefusal::ZeroSupport)
);
}
#[test]
fn uniform_sibling_coverage_all_zero_succeeds() {
let out = uniform_sibling_coverage(&[0, 0]).unwrap();
assert_eq!(out, alloc::vec![r(1, 2), r(1, 2)]);
}
#[test]
fn rare1_zero_mass_refuses() {
assert_eq!(
escort(ReferenceLens::RareOne, &[0, 1]),
Err(ReferenceEscortRefusal::ZeroMassUnderNegativeLens)
);
}
#[test]
fn rare2_zero_mass_refuses() {
assert_eq!(
escort(ReferenceLens::RareTwo, &[1, 0]),
Err(ReferenceEscortRefusal::ZeroMassUnderNegativeLens)
);
}
#[test]
fn proportional_all_zero_refuses_with_zero_partition_sum() {
assert_eq!(
escort(ReferenceLens::Proportional, &[0, 0]),
Err(ReferenceEscortRefusal::ZeroPartitionSum)
);
}
#[test]
fn empty_domain_refuses_at_every_lens() {
for lens in [
ReferenceLens::RareTwo,
ReferenceLens::RareOne,
ReferenceLens::Coverage,
ReferenceLens::Proportional,
ReferenceLens::ExploitTwo,
] {
assert_eq!(escort(lens, &[]), Err(ReferenceEscortRefusal::EmptyDomain));
}
}
#[test]
fn uniform_sibling_coverage_empty_refuses() {
assert_eq!(
uniform_sibling_coverage(&[]),
Err(ReferenceEscortRefusal::EmptyDomain)
);
}
#[test]
fn every_successful_escort_output_sums_to_exactly_one() {
for lens in [
ReferenceLens::RareTwo,
ReferenceLens::RareOne,
ReferenceLens::Coverage,
ReferenceLens::Proportional,
ReferenceLens::ExploitTwo,
] {
if let Ok(out) = escort(lens, &[1, 2, 3, 4, 5]) {
let mut sum = ExactRational::ZERO;
for w in out {
sum = sum.checked_add(w).unwrap();
}
assert_eq!(sum, ExactRational::ONE, "{lens:?}");
}
}
}
}