RosettaCodeData/Task/Tropical-algebra-overloading/Go/tropical-algebra-overloading.go
2023-07-01 13:44:08 -04:00

94 lines
2.1 KiB
Go

package main
import (
"fmt"
"log"
"math"
)
var MinusInf = math.Inf(-1)
type MaxTropical struct{ r float64 }
func newMaxTropical(r float64) MaxTropical {
if math.IsInf(r, 1) || math.IsNaN(r) {
log.Fatal("Argument must be a real number or negative infinity.")
}
return MaxTropical{r}
}
func (t MaxTropical) eq(other MaxTropical) bool {
return t.r == other.r
}
// equivalent to ⊕ operator
func (t MaxTropical) add(other MaxTropical) MaxTropical {
if t.r == MinusInf {
return other
}
if other.r == MinusInf {
return t
}
return newMaxTropical(math.Max(t.r, other.r))
}
// equivalent to ⊗ operator
func (t MaxTropical) mul(other MaxTropical) MaxTropical {
if t.r == 0 {
return other
}
if other.r == 0 {
return t
}
return newMaxTropical(t.r + other.r)
}
// exponentiation function
func (t MaxTropical) pow(e int) MaxTropical {
if e < 1 {
log.Fatal("Exponent must be a positive integer.")
}
if e == 1 {
return t
}
p := t
for i := 2; i <= e; i++ {
p = p.mul(t)
}
return p
}
func (t MaxTropical) String() string {
return fmt.Sprintf("%g", t.r)
}
func main() {
// 0 denotes ⊕ and 1 denotes ⊗
data := [][]float64{
{2, -2, 1},
{-0.001, MinusInf, 0},
{0, MinusInf, 1},
{1.5, -1, 0},
{-0.5, 0, 1},
}
for _, d := range data {
a := newMaxTropical(d[0])
b := newMaxTropical(d[1])
if d[2] == 0 {
fmt.Printf("%s ⊕ %s = %s\n", a, b, a.add(b))
} else {
fmt.Printf("%s ⊗ %s = %s\n", a, b, a.mul(b))
}
}
c := newMaxTropical(5)
fmt.Printf("%s ^ 7 = %s\n", c, c.pow(7))
d := newMaxTropical(8)
e := newMaxTropical(7)
f := c.mul(d.add(e))
g := c.mul(d).add(c.mul(e))
fmt.Printf("%s ⊗ (%s ⊕ %s) = %s\n", c, d, e, f)
fmt.Printf("%s ⊗ %s ⊕ %s ⊗ %s = %s\n", c, d, c, e, g)
fmt.Printf("%s ⊗ (%s ⊕ %s) == %s ⊗ %s ⊕ %s ⊗ %s is %t\n", c, d, e, c, d, c, e, f.eq(g))
}