use crate::Result;
pub fn calculate_fair_division_equal_weights(values: &[i128]) -> Result<Vec<i128>> {
if values.is_empty() {
return Err(crate::Error::InvalidInput);
}
if values.len() < 2 {
return Err(crate::Error::NotEnoughParticipants);
}
let n = values.len() as i128;
let sum_v: i128 = values.iter().sum();
let mut max_v = values[0];
let mut max_index = 0;
for (i, &v) in values.iter().enumerate() {
if v > max_v {
max_v = v;
max_index = i;
}
}
let delta = (n * max_v - sum_v) / (n * n);
let mut allocation = Vec::with_capacity(values.len());
let mut sum_others = 0;
for (i, &v) in values.iter().enumerate() {
if i != max_index {
let share = v / n + delta;
allocation.push(share);
sum_others += share;
} else {
allocation.push(0);
}
}
allocation[max_index] = -sum_others;
Ok(allocation)
}
pub fn calculate_fair_division_weighted(values: &[i128], weights: &[i128]) -> Result<Vec<i128>> {
if values.is_empty() || weights.is_empty() || values.len() != weights.len() {
return Err(crate::Error::InvalidInput);
}
if values.len() < 2 {
return Err(crate::Error::NotEnoughParticipants);
}
for &weight in weights {
if weight <= 0 {
return Err(crate::Error::InvalidInput);
}
}
let total_weight: i128 = weights.iter().sum();
let n = total_weight;
let sum_v: i128 = values.iter().zip(weights.iter())
.map(|(&v, &w)| v * w)
.sum();
let mut max_v = values[0];
let mut max_index = 0;
for (i, &v) in values.iter().enumerate() {
if v > max_v {
max_v = v;
max_index = i;
}
}
let delta = (n * max_v - sum_v) / (n * n);
let mut allocation = Vec::with_capacity(values.len());
let mut sum_others = 0;
for (i, (&v, &weight)) in values.iter().zip(weights.iter()).enumerate() {
if i != max_index {
let share = (v / n + delta) * weight;
allocation.push(share);
sum_others += share;
} else {
allocation.push(0);
}
}
allocation[max_index] = -sum_others;
Ok(allocation)
}