147 lines
3.3 KiB
Go
147 lines
3.3 KiB
Go
package slownie
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"strings"
|
|
)
|
|
|
|
var _smallNumbers = []string{
|
|
"zero", "jeden", "dwa", "trzy", "cztery", "pięć", "sześć", "siedem",
|
|
"osiem", "dziewięć", "dziesięć", "jedenaście", "dwanaście",
|
|
"trzynaście", "czternaście", "piętnaście", "szesnaście",
|
|
"siedemnaście", "osiemnaście", "dziewiętnaście"}
|
|
|
|
var _tens = []string{
|
|
"", "", "dwadzieścia", "trzydzieści", "czterdzieści",
|
|
"pięćdziesiąt", "sześćdziesiąt", "siedemdziesiąt",
|
|
"osiemdziesiąt", "dziewięćdziesiąt"}
|
|
|
|
var _hundrets = []string{
|
|
"", "sto", "dwieście", "trzysta", "czterysta",
|
|
"pięćset", "sześćset", "siedemset", "osiemset",
|
|
"dziewięćset"}
|
|
|
|
var _bigones = [][]string{
|
|
{"", "", ""},
|
|
{"tysiąc", "tysiące", "tysięcy"},
|
|
{"milion", "miliony", "milionów"},
|
|
{"miliard", "miliardy", "miliardów"},
|
|
{"bilion", "biliony", "bilionów"},
|
|
}
|
|
|
|
var _zlotyWord = []string{"złoty", "złote", "złotych"}
|
|
|
|
var _groszyWord = []string{"grosz", "grosze", "groszy"}
|
|
|
|
func round(num float64) int {
|
|
return int(num + math.Copysign(0.5, num))
|
|
}
|
|
|
|
func toFixed(num float64, precision int) float64 {
|
|
output := math.Pow(10, float64(precision))
|
|
return float64(round(num*output)) / output
|
|
}
|
|
|
|
func split(value float64) (int64, int64) {
|
|
pre := int64(value)
|
|
// post := int32((value - float64(pre)) * 100)
|
|
post := int64((round(value*100) % 100))
|
|
return pre, post
|
|
}
|
|
|
|
func caseWord(value int) int32 {
|
|
single := value % 10
|
|
tens := (value / 10) % 10
|
|
var caseWord int32
|
|
if value == 1 {
|
|
caseWord = 0
|
|
} else if tens == 1 && single > 1 {
|
|
caseWord = 2
|
|
} else if 2 <= single && single <= 4 {
|
|
caseWord = 1
|
|
} else {
|
|
caseWord = 2
|
|
}
|
|
return caseWord
|
|
}
|
|
|
|
func threeNumberWord(value int32) string {
|
|
single := value % 10
|
|
tens := (value / 10) % 10
|
|
hundrets := (value / 100) % 10
|
|
|
|
var words []string
|
|
if hundrets > 0 {
|
|
words = append(words, _hundrets[hundrets])
|
|
}
|
|
if tens == 1 {
|
|
words = append(words, _smallNumbers[single+10])
|
|
} else {
|
|
if tens > 0 {
|
|
words = append(words, _tens[tens])
|
|
}
|
|
if single > 0 {
|
|
words = append(words, _smallNumbers[single])
|
|
}
|
|
}
|
|
return strings.Join(words, " ")
|
|
}
|
|
|
|
func slownie(value int64) string {
|
|
var threePairs []int32
|
|
if value == 0 {
|
|
return "zero"
|
|
}
|
|
for value > 0 {
|
|
threePairs = append(threePairs, int32(value%1000))
|
|
value = value / 1000
|
|
}
|
|
|
|
var words []string
|
|
|
|
for i, n := range threePairs {
|
|
if n > 0 {
|
|
if i > 0 {
|
|
words = append(words, threeNumberWord(n)+" "+_bigones[i][caseWord(int(n))])
|
|
} else {
|
|
words = append(words, threeNumberWord(n))
|
|
}
|
|
}
|
|
}
|
|
|
|
//reverse
|
|
for i := len(words)/2 - 1; i >= 0; i-- {
|
|
opp := len(words) - 1 - i
|
|
words[i], words[opp] = words[opp], words[i]
|
|
}
|
|
|
|
return strings.Join(words, " ")
|
|
}
|
|
|
|
func someSlownie(value int64, some []string) string {
|
|
return slownie(value) + " " + some[caseWord(int(value))]
|
|
}
|
|
|
|
// KwotaSlownie - return value in words of zloty and groszy
|
|
func KwotaSlownie(input float64, numbers bool) (output string, err error) {
|
|
input = toFixed(input, 2)
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
err = errors.New("too big number")
|
|
}
|
|
}()
|
|
var minusword = ""
|
|
if input < 0 {
|
|
minusword = "minus "
|
|
input = -input
|
|
}
|
|
zloty, grosze := split(input)
|
|
if numbers {
|
|
return minusword + someSlownie(zloty, _zlotyWord) + fmt.Sprintf(" %02d/100", grosze), nil
|
|
}
|
|
return minusword + someSlownie(zloty, _zlotyWord) + " " + someSlownie(grosze, _groszyWord), nil
|
|
|
|
}
|