#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Tropical(pub u64);
impl Tropical {
pub const ZERO: Tropical = Tropical(u64::MAX);
pub const ONE: Tropical = Tropical(0);
pub const INF: Tropical = Tropical(u64::MAX);
#[inline]
pub const fn from_u64(v: u64) -> Self {
Tropical(v)
}
#[inline]
pub const fn as_u64(self) -> u64 {
self.0
}
#[inline]
pub const fn is_inf(self) -> bool {
self.0 == u64::MAX
}
#[inline]
pub const fn is_finite(self) -> bool {
self.0 != u64::MAX
}
#[inline]
pub const fn add(self, other: Tropical) -> Tropical {
if self.0 <= other.0 { self } else { other }
}
#[inline]
pub const fn mul(self, other: Tropical) -> Tropical {
if self.is_inf() || other.is_inf() {
Tropical::INF
} else {
let (sum, overflow) = self.0.overflowing_add(other.0);
if overflow || sum == u64::MAX {
Tropical::INF
} else {
Tropical(sum)
}
}
}
}
impl core::fmt::Display for Tropical {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
if self.is_inf() {
write!(f, "+inf")
} else {
write!(f, "{}", self.0)
}
}
}