Skip to content

Commit c248a70

Browse files
authored
Merge pull request #75 from semargal/feature/add_uk_ua_lang
2 parents 6dc5ad4 + 7b03537 commit c248a70

File tree

3 files changed

+245
-0
lines changed

3 files changed

+245
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
| `id`, `id-id` | 🇮🇩 | Indonesian | Indonesia | empat puluh dua |
3333
| `jp`, `ja-jp` | 🇯🇵 | Japanese | Japan | 四十二 |
3434
| `fr-be` | 🇧🇪 | Belgian French, Français (Belge) | Belgium | quarante-deux |
35+
| `uk`, `uk-ua` | 🇺🇦 | Ukrainian | Ukraine | сорок два |
3536
| `roman` | | Roman Numbers | | XLII |
3637
| `roman-unicode` | | Roman (with Unicode) | | ⅩⅬⅡ |
3738
| `aegean` | | Aegean Numerals | | 𐄓𐄈 |

uk-ua.go

+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package ntw
2+
3+
import (
4+
"strings"
5+
)
6+
7+
func init() {
8+
// register the language
9+
Languages["uk-ua"] = Language{
10+
Name: "Ukrainian",
11+
Aliases: []string{"uk", "uk-ua", "uk_UA", "ukrainian"},
12+
Flag: "🇺🇦",
13+
14+
IntegerToWords: IntegerToUkUa,
15+
}
16+
}
17+
18+
func ukPlural(n int, words []string) string {
19+
return plural(n, words)
20+
}
21+
22+
// IntegerToUkUa converts an integer to UK words
23+
func IntegerToUkUa(input int) string {
24+
var ukUnits = []string{
25+
"",
26+
"один",
27+
"два",
28+
"три",
29+
"чотири",
30+
"п'ять",
31+
"шість",
32+
"сім",
33+
"вісім",
34+
"дев'ять",
35+
}
36+
var ukTeens = []string{
37+
"десять",
38+
"одинадцять",
39+
"дванадцять",
40+
"тринадцять",
41+
"чотирнадцять",
42+
"п'ятнадцять",
43+
"шістнадцять",
44+
"сімнадцять",
45+
"вісімнадцять",
46+
"дев'ятнадцять",
47+
}
48+
var ukTens = []string{
49+
"",
50+
"десять",
51+
"двадцять",
52+
"тридцять",
53+
"сорок",
54+
"п'ятдесят",
55+
"шістдесят",
56+
"сімдесят",
57+
"вісімдесят",
58+
"дев'яносто",
59+
}
60+
var ukHundreds = []string{
61+
"",
62+
"сто",
63+
"двісті",
64+
"триста",
65+
"чотириста",
66+
"п'ятсот",
67+
"шістсот",
68+
"сімсот",
69+
"вісімсот",
70+
"дев'ятсот",
71+
}
72+
var ukMegas = [][]string{
73+
{"", "", ""},
74+
{"тисяча", "тисячі", "тисяч"}, // 10^3
75+
{"мільйон", "мільйона", "мільйонів"}, // 10^6
76+
{"мільярд", "мільярда", "мільярдів"}, // 10^9
77+
{"трильйон", "трильйона", "трильйонів"}, // 10^12
78+
{"квадрильйон", "квадрильйона", "квадрильйонів"}, // 10^15
79+
{"квінтильйон", "квінтильйона", "квінтильйонів"}, // 10^18
80+
{"секстильйон", "секстильйона", "секстильйонів"}, // 10^21
81+
{"септильйон", "септильйона", "септильйонів"}, // 10^34
82+
{"октильйон", "октильйона", "октильйонів"}, // 10^27
83+
}
84+
85+
var words []string
86+
87+
if input < 0 {
88+
words = append(words, "мінус")
89+
input *= -1
90+
}
91+
92+
// split integer in triplets
93+
triplets := integerToTriplets(input)
94+
95+
// zero is a special case
96+
if len(triplets) == 0 {
97+
return "нуль"
98+
}
99+
100+
// iterate over triplets
101+
for idx := len(triplets) - 1; idx >= 0; idx-- {
102+
triplet := triplets[idx]
103+
104+
// nothing todo for empty triplet
105+
if triplet == 0 {
106+
continue
107+
}
108+
109+
// three-digits
110+
hundreds := triplet / 100 % 10
111+
tens := triplet / 10 % 10
112+
units := triplet % 10
113+
114+
if hundreds > 0 {
115+
words = append(words, ukHundreds[hundreds])
116+
}
117+
118+
if tens > 0 || units > 0 {
119+
switch tens {
120+
case 0:
121+
words = append(words, ukOneTwoUnitFix(units, idx, ukUnits))
122+
case 1:
123+
words = append(words, ukTeens[units])
124+
break
125+
default:
126+
words = append(words, ukTens[tens])
127+
if units > 0 {
128+
words = append(words, ukOneTwoUnitFix(units, idx, ukUnits))
129+
}
130+
break
131+
}
132+
}
133+
134+
// mega
135+
if idx >= 1 && idx < len(ukMegas) {
136+
mega := ukMegas[idx]
137+
tens = tens*10 + units
138+
if len(mega) > 0 {
139+
words = append(words, ukPlural(tens, mega))
140+
}
141+
}
142+
}
143+
144+
return strings.Join(words, " ")
145+
}
146+
147+
func ukOneTwoUnitFix(unit, idx int, arr []string) string {
148+
if idx == 1 {
149+
switch unit {
150+
case 1:
151+
return "одна"
152+
case 2:
153+
return "дві"
154+
}
155+
}
156+
157+
return arr[unit]
158+
}

uk-ua_test.go

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package ntw
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestIntegerToUkUa(t *testing.T) {
11+
t.Parallel()
12+
13+
tests := map[int]string{
14+
-1: "мінус один",
15+
0: "нуль",
16+
1: "один",
17+
9: "дев'ять",
18+
10: "десять",
19+
11: "одинадцять",
20+
19: "дев'ятнадцять",
21+
20: "двадцять",
22+
21: "двадцять один",
23+
80: "вісімдесят",
24+
90: "дев'яносто",
25+
99: "дев'яносто дев'ять",
26+
100: "сто",
27+
101: "сто один",
28+
111: "сто одинадцять",
29+
120: "сто двадцять",
30+
121: "сто двадцять один",
31+
900: "дев'ятсот",
32+
909: "дев'ятсот дев'ять",
33+
919: "дев'ятсот дев'ятнадцять",
34+
990: "дев'ятсот дев'яносто",
35+
999: "дев'ятсот дев'яносто дев'ять",
36+
1000: "одна тисяча",
37+
2000: "дві тисячі",
38+
4000: "чотири тисячі",
39+
5000: "п'ять тисяч",
40+
11000: "одинадцять тисяч",
41+
21000: "двадцять одна тисяча",
42+
999000: "дев'ятсот дев'яносто дев'ять тисяч",
43+
999999: "дев'ятсот дев'яносто дев'ять тисяч дев'ятсот дев'яносто дев'ять",
44+
1000000: "один мільйон",
45+
2000000: "два мільйона",
46+
4000000: "чотири мільйона",
47+
5000000: "п'ять мільйонів",
48+
100100100: "сто мільйонів сто тисяч сто",
49+
500500500: "п'ятсот мільйонів п'ятсот тисяч п'ятсот",
50+
606606606: "шістсот шість мільйонів шістсот шість тисяч шістсот шість",
51+
999000000: "дев'ятсот дев'яносто дев'ять мільйонів",
52+
999000999: "дев'ятсот дев'яносто дев'ять мільйонів дев'ятсот дев'яносто дев'ять",
53+
999999000: "дев'ятсот дев'яносто дев'ять мільйонів дев'ятсот дев'яносто дев'ять тисяч",
54+
999999999: "дев'ятсот дев'яносто дев'ять мільйонів дев'ятсот дев'яносто дев'ять тисяч дев'ятсот дев'яносто дев'ять",
55+
1174315110: "один мільярд сто сімдесят чотири мільйона триста п'ятнадцять тисяч сто десять",
56+
1174315119: "один мільярд сто сімдесят чотири мільйона триста п'ятнадцять тисяч сто дев'ятнадцять",
57+
15174315119: "п'ятнадцять мільярдів сто сімдесят чотири мільйона триста п'ятнадцять тисяч сто дев'ятнадцять",
58+
35174315119: "тридцять п'ять мільярдів сто сімдесят чотири мільйона триста п'ятнадцять тисяч сто дев'ятнадцять",
59+
935174315119: "дев'ятсот тридцять п'ять мільярдів сто сімдесят чотири мільйона триста п'ятнадцять тисяч сто дев'ятнадцять",
60+
2935174315119: "два трильйона дев'ятсот тридцять п'ять мільярдів сто сімдесят чотири мільйона триста п'ятнадцять тисяч сто дев'ятнадцять",
61+
3911760: "три мільйона дев'ятсот одинадцять тисяч сімсот шістдесят",
62+
27: "двадцять сім",
63+
95000001000: "дев'яносто п'ять мільярдів одна тисяча",
64+
57482: "п'ятдесят сім тисяч чотириста вісімдесят два",
65+
5: "п'ять",
66+
16: "шістнадцять",
67+
30: "тридцять",
68+
53: "п'ятдесят три",
69+
123: "сто двадцять три",
70+
204: "двісті чотири",
71+
300: "триста",
72+
1400: "одна тисяча чотириста",
73+
83756: "вісімдесят три тисячі сімсот п'ятдесят шість",
74+
293111: "двісті дев'яносто три тисячі сто одинадцять",
75+
32001950: "тридцять два мільйона одна тисяча дев'ятсот п'ятдесят",
76+
2018: "дві тисячі вісімнадцять",
77+
126682: "сто двадцять шість тисяч шістсот вісімдесят два",
78+
}
79+
80+
for input, expectedOutput := range tests {
81+
name := fmt.Sprintf("%d", input)
82+
t.Run(name, func(t *testing.T) {
83+
assert.Equal(t, expectedOutput, IntegerToUkUa(input))
84+
})
85+
}
86+
}

0 commit comments

Comments
 (0)