Irreducible Sum of Rationals in Golang


The challenge

You will have a list of rationals in the form:

lst = [ [numer_1, denom_1] , ... , [numer_n, denom_n] ]

where all numbers are positive integers. You have to produce their sum N / D in an irreducible form: this means that N and D have only 1 as a common divisor.

Return the result in the form: "N/D"

If the result is an integer (D evenly divides N) return: "n"

If the input list is empty, return: "0"

Examples:

[ [1, 2], [1, 3], [1, 4] ]  -->  [13, 12]
1/2  +  1/3  +  1/4     =      13/12

The solution in Golang

Option 1:

package solution
import"fmt"
func SumFracts(arr[][]int) string {
  a,b:= 0,1
  for _,v:=range arr{
    c,d:=v[0],v[1]
    k:=gcd(b,d)
    a,b=(a*d+b*c)/k,b*d/k
  }
  k:=gcd(a,b)
  a,b=a/k,b/k
  if b==1 {return fmt.Sprintf("%d",a)}
  return fmt.Sprintf("%d/%d",a,b)
}
func gcd(a, b int) int {
  for b != 0 {
    a, b = b, a%b
  }
  return a
}

Option 2:

package solution
import "math/big"
func SumFracts(arr [][]int) string {
  result := new(big.Rat).SetFloat64(0)
  for _, v := range(arr) {
    rat := big.NewRat(int64(v[0]), int64(v[1]))
    result.Add(result, rat)
  }
  return result.RatString()
}

Option 3:

package solution
import "math/big"
func SumFracts(arr [][]int) string {
  sum := big.NewRat(0,1)
  for _, f := range arr {
    sum.Add(sum, big.NewRat(int64(f[0]), int64(f[1])))
  }
  if sum.Denom().Cmp(big.NewInt(1)) == 0 {
    return sum.Num().String()
  }
  return sum.String()
}

Test cases to validate our solution

package solution_test
import (
  . "github.com/onsi/ginkgo"
  . "github.com/onsi/gomega"
)
func dotest(arr [][]int, exp string) {
    var ans = SumFracts(arr)
    Expect(ans).To(Equal(exp))
}
var _ = Describe("Tests SumFracts", func() {
    It("should handle basic cases", func() {
        dotest([][]int{{1, 2}, {1, 3}, {1, 4}}, "13/12")
        dotest([][]int{{1, 3}, {5, 3}}, "2")
    })      
})