Skip to content

Commit

Permalink
New language: Russian (#34)
Browse files Browse the repository at this point in the history
* refactoring

* added russian

* Revert "refactoring"

This reverts commit dee0e4b

* moved ru-ru to root

* removed vendor dir

* Revert "removed vendor dir"

This reverts commit 7d52791

* updated readme
  • Loading branch information
kulaginds authored and moul committed Mar 31, 2019
1 parent 5902d39 commit 12cc642
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Convert numbers to words.
* Turkish / Turkey [tr] 🇹🇷
* Portuguese / Portugal [pt-pt] 🇵🇹
* Polish / Poland [pl-pl] 🇵🇱
* Russian / Russia [ru-ru] 🇷🇺

* Roman Numbers
* Roman Numbers (with Unicode) Ⅷ
Expand Down
177 changes: 177 additions & 0 deletions ru-ru.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package ntw

import (
"strings"
)

func init() {
// register the language
Languages["ru-ru"] = Language{
Name: "Russian",
Aliases: []string{"ru", "rus", "ru_RU", "russian"},
Flag: "🇷🇺",

IntegerToWords: IntegerToRuRu,
}
}

func plural(n int, words []string) string {
index := 0

n %= 100

if n > 19 {
n %= 10
}

if n != 1 {
if n > 1 && n <= 4 {
index = 1
} else {
index = 2
}
}

return words[index]
}

// IntegerToRuRu converts an integer to Russian words
func IntegerToRuRu(input int) string {
var russianUnits = []string{
"",
"один",
"два",
"три",
"четыре",
"пять",
"шесть",
"семь",
"восемь",
"девять",
}
var russianTeens = []string{
"десять",
"одиннадцать",
"двенадцать",
"тринадцать",
"четырнадцать",
"пятнадцать",
"шестнадцать",
"семнадцать",
"восемнадцать",
"девятнадцать",
}
var russianTens = []string{
"",
"десять",
"двадцать",
"тридцать",
"сорок",
"пятьдесят",
"шестьдесят",
"семьдесят",
"восемьдесят",
"девяносто",
}
var russianHundreds = []string{
"",
"сто",
"двести",
"триста",
"четыреста",
"пятьсот",
"шестьсот",
"семьсот",
"восемьсот",
"девятьсот",
}
var russianMegas = [][]string{
{"", "", ""},
{"тысяча", "тысячи", "тысяч"}, // 10^3
{"миллион", "миллиона", "миллионов"}, // 10^6
{"миллиард", "миллиарда", "миллиардов"}, // 10^9
{"триллион", "триллиона", "триллионов"}, // 10^12
{"квадриллион", "квадриллиона", "квадриллионов"}, // 10^15
{"квинтиллион", "квинтиллиона", "квинтиллионов"}, // 10^18
{"секстиллион", "секстиллиона", "секстиллионов"}, // 10^21
{"септиллион", "септиллиона", "септиллионов"}, // 10^34
{"октиллион", "октиллиона", "октиллионов"}, // 10^27
{"нониллион", "нониллиона", "нониллионов"}, // 10^30
{"дециллион", "дециллиона", "дециллионов"}, // 10^33
{"ундециллион", "ундециллиона", "ундециллионов"}, // 10^36
}

var words []string

if input < 0 {
words = append(words, "минус")
input *= -1
}

// split integer in triplets
triplets := integerToTriplets(input)

// zero is a special case
if len(triplets) == 0 {
return "нуль"
}

// iterate over triplets
for idx := len(triplets) - 1; idx >= 0; idx-- {
triplet := triplets[idx]

// nothing todo for empty triplet
if triplet == 0 {
continue
}

// three-digits
hundreds := triplet / 100 % 10
tens := triplet / 10 % 10
units := triplet % 10

if hundreds > 0 {
words = append(words, russianHundreds[hundreds])
}

if tens > 0 || units > 0 {
switch tens {
case 0:
words = append(words, oneTwoUnitFix(units, idx, russianUnits))
case 1:
words = append(words, russianTeens[units])
break
default:
words = append(words, russianTens[tens])
if units > 0 {
words = append(words, oneTwoUnitFix(units, idx, russianUnits))
}
break
}
}

// mega
if idx >= 1 && idx < len(russianMegas) {
mega := russianMegas[idx]
tens = tens * 10 + units
if len(mega) > 0 {
words = append(words, plural(tens, mega))
}
}
}

return strings.Join(words, " ")
}

func oneTwoUnitFix(unit, idx int, arr []string) string {
if idx == 1 {
switch unit {
case 1:
return "одна"
case 2:
return "две"
}
}

return arr[unit]
}
83 changes: 83 additions & 0 deletions ru-ru_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package ntw

import (
"testing"

. "github.com/smartystreets/goconvey/convey"
)

func TestIntegerToRuRu(t *testing.T) {
Convey("Testing IntegerToRuRu()", t, FailureContinues, func() {
testCases := map[int]string{
0: "нуль",
1: "один",
9: "девять",
10: "десять",
11: "одиннадцать",
19: "девятнадцать",
20: "двадцать",
21: "двадцать один",
80: "восемьдесят",
90: "девяносто",
99: "девяносто девять",
100: "сто",
101: "сто один",
111: "сто одиннадцать",
120: "сто двадцать",
121: "сто двадцать один",
900: "девятьсот",
909: "девятьсот девять",
919: "девятьсот девятнадцать",
990: "девятьсот девяносто",
999: "девятьсот девяносто девять",
1000: "одна тысяча",
2000: "две тысячи",
4000: "четыре тысячи",
5000: "пять тысяч",
11000: "одиннадцать тысяч",
21000: "двадцать одна тысяча",
999000: "девятьсот девяносто девять тысяч",
999999: "девятьсот девяносто девять тысяч девятьсот девяносто девять",
1000000: "один миллион",
2000000: "два миллиона",
4000000: "четыре миллиона",
5000000: "пять миллионов",
100100100: "сто миллионов сто тысяч сто",
500500500: "пятьсот миллионов пятьсот тысяч пятьсот",
606606606: "шестьсот шесть миллионов шестьсот шесть тысяч шестьсот шесть",
999000000: "девятьсот девяносто девять миллионов",
999000999: "девятьсот девяносто девять миллионов девятьсот девяносто девять",
999999000: "девятьсот девяносто девять миллионов девятьсот девяносто девять тысяч",
999999999: "девятьсот девяносто девять миллионов девятьсот девяносто девять тысяч девятьсот девяносто девять",
1174315110: "один миллиард сто семьдесят четыре миллиона триста пятнадцать тысяч сто десять",
1174315119: "один миллиард сто семьдесят четыре миллиона триста пятнадцать тысяч сто девятнадцать",
15174315119: "пятнадцать миллиардов сто семьдесят четыре миллиона триста пятнадцать тысяч сто девятнадцать",
35174315119: "тридцать пять миллиардов сто семьдесят четыре миллиона триста пятнадцать тысяч сто девятнадцать",
935174315119: "девятьсот тридцать пять миллиардов сто семьдесят четыре миллиона триста пятнадцать тысяч сто девятнадцать",
2935174315119: "два триллиона девятьсот тридцать пять миллиардов сто семьдесят четыре миллиона триста пятнадцать тысяч сто девятнадцать",
3911760: "три миллиона девятьсот одиннадцать тысяч семьсот шестьдесят",
27: "двадцать семь",
95000001000: "девяносто пять миллиардов одна тысяча",
57482: "пятьдесят семь тысяч четыреста восемьдесят два",
5: "пять",
16: "шестнадцать",
30: "тридцать",
53: "пятьдесят три",
123: "сто двадцать три",
204: "двести четыре",
300: "триста",
1400: "одна тысяча четыреста",
83756: "восемьдесят три тысячи семьсот пятьдесят шесть",
293111: "двести девяносто три тысячи сто одиннадцать",
32001950: "тридцать два миллиона одна тысяча девятьсот пятьдесят",
2018: "две тысячи восемнадцать",
126682: "сто двадцать шесть тысяч шестьсот восемьдесят два",
}
for input, expectedOutput := range testCases {
So(IntegerToRuRu(input), ShouldEqual, expectedOutput)
}

// testCases negative values
So(IntegerToRuRu(-1), ShouldEqual, "минус один")
})
}

0 comments on commit 12cc642

Please sign in to comment.