// Package allyourbase converts numbers between various bases.
package allyourbase
import (
"fmt"
"math"
)
// ConvertToBase converts ibase based input to obase based output.
func ConvertToBase(ibase int, input []int, obase int) ([]int, error) {
if ibase < 2 {
return nil, fmt.Errorf("input base must be >= 2")
}
if obase < 2 {
return nil, fmt.Errorf("output base must be >= 2")
}
value, err := countValue(ibase, input)
if err != nil {
return nil, err
}
return createValue(value, obase), nil
}
func countValue(ibase int, input []int) (int, error) {
value := 0
for i, v := range input {
if v < 0 || v >= ibase {
return 0, fmt.Errorf("all digits must satisfy 0 <= d < input base")
}
value += v * int(math.Pow(float64(ibase), float64(len(input)-1-i)))
}
return value, nil
}
func createValue(value, obase int) []int {
// calculate maximal place value needed for representing value
var p int
for sum := 0; sum <= value; p++ {
sum += (obase - 1) * int(math.Pow(float64(obase), float64(p)))
}
// generate obase representation of value
out := make([]int, p)
for i := p - 1; value != 0; i-- {
for j := obase - 1; j >= 0; j-- {
cand := j * int(math.Pow(float64(obase), float64(i)))
if cand <= value {
value -= cand
out[len(out)-1-i] = j
break
}
}
}
return out
}