Task: Tropical algebra overloading


C++: #include <iostream>
#include <optional>

using namespace std;

class TropicalAlgebra
{
    
    optional<double> m_value;
    
public:
    friend std::ostream& operator<<(std::ostream&, const TropicalAlgebra&);
    friend TropicalAlgebra pow(const TropicalAlgebra& base, unsigned int exponent) noexcept;
    
    
    TropicalAlgebra() = default;

    
    explicit TropicalAlgebra(double value) noexcept
        : m_value{value} {}

    
    
    TropicalAlgebra& operator+=(const TropicalAlgebra& rhs) noexcept
    {
        if(!m_value)
        {
            
            *this = rhs;
        }
        else if (!rhs.m_value)
        {
            
        }
        else
        {
            
            *m_value = max(*rhs.m_value, *m_value);
        }

        return *this;
    }
    
    
    TropicalAlgebra& operator*=(const TropicalAlgebra& rhs) noexcept
    {
        if(!m_value)
        {
            
            
        }
        else if (!rhs.m_value)
        {
            
            *this = rhs;
        }
        else
        {
            *m_value += *rhs.m_value;
        }

        return *this;
    }
};


inline TropicalAlgebra operator+(TropicalAlgebra lhs, const TropicalAlgebra& rhs) noexcept
{
    
    lhs += rhs;
    return lhs;
}


inline TropicalAlgebra operator*(TropicalAlgebra lhs, const TropicalAlgebra&  rhs) noexcept
{
    lhs *= rhs;
    return lhs;
}


inline TropicalAlgebra pow(const TropicalAlgebra& base, unsigned int exponent) noexcept
{
    auto result = base;
    for(unsigned int i = 1; i < exponent; i++)
    {
        
        result *= base;
    }
    return result;
}


ostream& operator<<(ostream& os, const TropicalAlgebra& pt)
{
    if(!pt.m_value) cout << "-Inf\n";
    else cout << *pt.m_value << "\n";
    return os;
}

int main(void) {
    const TropicalAlgebra a(-2);
    const TropicalAlgebra b(-1);
    const TropicalAlgebra c(-0.5);
    const TropicalAlgebra d(-0.001);
    const TropicalAlgebra e(0);
    const TropicalAlgebra h(1.5);
    const TropicalAlgebra i(2);
    const TropicalAlgebra j(5);
    const TropicalAlgebra k(7);
    const TropicalAlgebra l(8);
    const TropicalAlgebra m; 
    
    cout << "2 * -2 == " << i * a;
    cout << "-0.001 + -Inf == " << d + m;
    cout << "0 * -Inf == " << e * m;
    cout << "1.5 + -1 == " << h + b;
    cout << "-0.5 * 0 == " << c * e;
    cout << "pow(5, 7) == " << pow(j, 7);
    cout << "5 * (8 + 7)) == " << j * (l + k);
    cout << "5 * 8 + 5 * 7 == " << j * l + j * k;
}






Python: from numpy import Inf

class MaxTropical:
    
    def __init__(self, x=0):
        self.x = x

    def __str__(self):
        return str(self.x)

    def __add__(self, other):
        return MaxTropical(max(self.x, other.x))

    def __mul__(self, other):
        return MaxTropical(self.x + other.x)

    def __pow__(self, other):
        assert other.x // 1 == other.x and other.x > 0, "Invalid Operation" 
        return MaxTropical(self.x * other.x)

    def __eq__(self, other):
        return self.x == other.x


if __name__ == "__main__":
    a = MaxTropical(-2)
    b = MaxTropical(-1)
    c = MaxTropical(-0.5)
    d = MaxTropical(-0.001)
    e = MaxTropical(0)
    f = MaxTropical(0.5)
    g = MaxTropical(1)
    h = MaxTropical(1.5)
    i = MaxTropical(2)
    j = MaxTropical(5)
    k = MaxTropical(7)
    l = MaxTropical(8)
    m = MaxTropical(-Inf)

    print("2 * -2 == ", i * a)
    print("-0.001 + -Inf == ", d + m)
    print("0 * -Inf == ", e * m)
    print("1.5 + -1 == ", h + b)
    print("-0.5 * 0 == ", c * e)
    print("5**7 == ", j**k)
    print("5 * (8 + 7)) == ", j * (l + k))
    print("5 * 8 + 5 * 7 == ", j * l + j * k)
    print("5 * (8 + 7) == 5 * 8 + 5 * 7", j * (l + k) == j * l + j * k)