Skip to content

Commit f4ba716

Browse files
Initial commit
1 parent 7a03395 commit f4ba716

5 files changed

Lines changed: 383 additions & 0 deletions

File tree

src/OneBitSoftware.Slovom.sln

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.13.35825.156 d17.13
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OneBitSoftware.Slovom", "OneBitSoftware.Slovom\OneBitSoftware.Slovom.csproj", "{EC525DA1-1FFE-47B4-98A5-AEE7D391957B}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{EED4ED6B-42C9-4F72-A8ED-48407B0714CB}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Release|Any CPU = Release|Any CPU
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{EC525DA1-1FFE-47B4-98A5-AEE7D391957B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{EC525DA1-1FFE-47B4-98A5-AEE7D391957B}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{EC525DA1-1FFE-47B4-98A5-AEE7D391957B}.Release|Any CPU.ActiveCfg = Release|Any CPU
19+
{EC525DA1-1FFE-47B4-98A5-AEE7D391957B}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{EED4ED6B-42C9-4F72-A8ED-48407B0714CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{EED4ED6B-42C9-4F72-A8ED-48407B0714CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{EED4ED6B-42C9-4F72-A8ED-48407B0714CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{EED4ED6B-42C9-4F72-A8ED-48407B0714CB}.Release|Any CPU.Build.0 = Release|Any CPU
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
GlobalSection(ExtensibilityGlobals) = postSolution
29+
SolutionGuid = {7C0F044E-99DA-4CC5-8AE8-D1763EE5030E}
30+
EndGlobalSection
31+
EndGlobal
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
namespace OneBitSoftware.Slovom
2+
{
3+
public static class NumbersToWords
4+
{
5+
static string[] under20 = { "нула", "един", "два", "три", "четири", "пет", "шест", "седем", "осем", "девет", "десет", "единадесет", "дванадесет", "тринадесет", "четиринадесет", "петнадесет", "шестнадесет", "седемнадесет", "осемнадесет", "деветнадесет" };
6+
static string[] units = { "нула", "едно", "две", "три", "четири", "пет", "шест", "седем", "осем", "девет" };
7+
static string[] teens = { "десет", "единадесет", "дванадесет", "тринадесет", "четиринадесет", "петнадесет", "шестнадесет", "седемнадесет", "осемнадесет", "деветнадесет" };
8+
static string[] tens = { "", "десет", "двадесет", "тридесет", "четиридесет", "петдесет", "шестдесет", "седемдесет", "осемдесет", "деветдесет" };
9+
static string[] hundreds = { "", "сто", "двеста", "триста", "четиристотин", "петстотин", "шестстотин", "седемстотин", "осемстотин", "деветстотин" };
10+
11+
static string AppendLvMale = " лев";
12+
static string AppendLvFemale = " лева";
13+
static string AppendStotinki = " стотинки";
14+
static string AppendStotinka = " стотинка";
15+
16+
static string ConvertWholeNumber(int n)
17+
{
18+
if (n < 10)
19+
return under20[n];
20+
else if (n < 100)
21+
return Tens(n);
22+
else if (n < 1000)
23+
return Hundreds(n);
24+
else if (n < 10000)
25+
return Thousands(n);
26+
else if (n < 100000)
27+
return TensOfThousands(n);
28+
else
29+
return "Числото е твърде голямо";
30+
}
31+
32+
private static string Tens(int n)
33+
{
34+
var i = n / 10;
35+
var d = n % 10;
36+
37+
if (n < 20)
38+
{
39+
return under20[n];
40+
}
41+
else
42+
{
43+
return tens[i] + (d == 0 ? "" : " и " + ConvertWholeNumber(d));
44+
}
45+
}
46+
47+
static string Hundreds(int n)
48+
{
49+
var i = n / 100;
50+
var d = n % 100;
51+
52+
if (n < 120)
53+
{
54+
return "сто и " + under20[d];
55+
}
56+
else if (n >= 120 && n < 200)
57+
{
58+
return "сто " + ConvertWholeNumber(d);
59+
}
60+
else
61+
{
62+
if (d < 20)
63+
return hundreds[i] + (d == 0 ? "" : " и " + ConvertWholeNumber(d));
64+
65+
return hundreds[i] + (d == 0 ? "" : " " + ConvertWholeNumber(d));
66+
}
67+
}
68+
69+
private static string Thousands(int n)
70+
{
71+
var i = n / 1000;
72+
var d = n % 1000;
73+
74+
if (n == 1000) return "хиляда";
75+
76+
if (n > 1000 && n < 1099)
77+
{
78+
return "хиляда и " + Tens(d);
79+
}
80+
81+
if (n > 1099 && n < 2000)
82+
{
83+
return "хиляда " + Hundreds(d);
84+
}
85+
86+
if (d == 0) // 2000,3000,4000, etc
87+
{
88+
return units[i] + " хиляди";
89+
}
90+
91+
if (d < 100)
92+
{
93+
return units[i] + " хиляди и " + Tens(d);
94+
}
95+
96+
return units[i] + " хиляди " + Hundreds(d);
97+
}
98+
99+
private static string TensOfThousands(int n)
100+
{
101+
var i = n / 10000;
102+
var d = n % 10000;
103+
var e = d % 1000;
104+
var j = d / 1000;
105+
var g = n / 1000;
106+
var h = n / 10;
107+
var f = g % 10;
108+
var r = e % 100;
109+
var t = r % 10;
110+
111+
//if (n == 10000) return "десет хиляди";
112+
113+
if (n > 10000 && n < 10099)
114+
{
115+
return tens[i] + " хиляди и " + Tens(d);
116+
}
117+
118+
if (n >= 10099 && n < 11000)
119+
{
120+
if (r == 0) // 10100, 10900, 10800 , etc
121+
{
122+
return tens[i] + " хиляди и " + Hundreds(d);
123+
}
124+
125+
return tens[i] + " хиляди " + Hundreds(d);
126+
}
127+
128+
if (n >= 11000 && n < 20000)
129+
{
130+
if (r == 0) // 11100, 11900, 11800 , etc
131+
{
132+
if (e == 0)
133+
{
134+
return teens[f] + " хиляди";
135+
}
136+
137+
return teens[f] + " хиляди и " + Hundreds(e);
138+
}
139+
140+
return teens[f] + " хиляди " + Hundreds(e);
141+
}
142+
143+
if (n > 20000 && n < 99999)
144+
{
145+
if (j == 1)
146+
{
147+
if (e < 100)
148+
{
149+
return tens[i] + " и една хиляди и " + Tens(e);
150+
}
151+
152+
if (t == 0)
153+
{
154+
return tens[i] + " и една хиляди и " + Hundreds(e);
155+
}
156+
157+
if (t > 0)
158+
{
159+
return tens[i] + " и една хиляди " + Hundreds(e);
160+
}
161+
}
162+
163+
if (j == 2)
164+
{
165+
if (e < 100)
166+
{
167+
return tens[i] + " и две хиляди и " + Tens(e);
168+
}
169+
170+
if (t == 0)
171+
{
172+
return tens[i] + " и две хиляди и " + Hundreds(e);
173+
}
174+
175+
if (t > 0)
176+
{
177+
return tens[i] + " и две хиляди " + Hundreds(e);
178+
}
179+
}
180+
181+
return Tens(g) + " хиляди и " + Hundreds(e);
182+
}
183+
184+
if (d == 0) // 10000,20000,30000, etc
185+
{
186+
return tens[i] + " хиляди";
187+
}
188+
189+
if (d < 100)
190+
{
191+
return tens[i] + " хиляди и " + Tens(r);
192+
}
193+
194+
return Tens(g) + " хиляди " + Hundreds(e);
195+
}
196+
197+
198+
public static string Convert(decimal number)
199+
{
200+
if (number == 0 || number == 0.0m)
201+
{
202+
return under20[0] + AppendLvFemale; // нула лева
203+
}
204+
205+
int leva = (int)number;
206+
int stotinki = (int)((number % 1.0m) * 100);
207+
208+
if (number == 1 && stotinki == 0)
209+
{
210+
return under20[leva] + AppendLvMale; // един лев
211+
}
212+
213+
string levaWords = leva != 1 ? ConvertWholeNumber(leva) + " лева" : "един лев";
214+
215+
string stotinkiWords;
216+
217+
if (leva == 0)
218+
{
219+
if (stotinki == 0) return "нула лева";
220+
if (stotinki == 1) return "една" + AppendStotinka;
221+
if (stotinki == 2) return "две" + AppendStotinki;
222+
if (stotinki == 10) return "десет" + AppendStotinki;
223+
if (stotinki < 20) return under20[stotinki] + AppendStotinki;
224+
225+
stotinkiWords = stotinki.ToString() + " ст.";
226+
}
227+
else
228+
{
229+
stotinkiWords = stotinki.ToString() + " ст.";
230+
}
231+
232+
if (leva == 0)
233+
return stotinkiWords;
234+
else if (stotinki == 0)
235+
return levaWords;
236+
else
237+
return levaWords + " и " + stotinkiWords;
238+
}
239+
}
240+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.7.0.110445">
11+
<PrivateAssets>all</PrivateAssets>
12+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
13+
</PackageReference>
14+
</ItemGroup>
15+
16+
</Project>

src/Tests/ConvertTests.cs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using Xunit;
2+
using OneBitSoftware.Slovom;
3+
4+
namespace Tests
5+
{
6+
public class ConvertTests
7+
{
8+
9+
[Theory]
10+
[InlineData(0, "нула лева")]
11+
[InlineData(1, "един лев")]
12+
[InlineData(2, "два лева")]
13+
[InlineData("2.0", "два лева")]
14+
[InlineData(9, "девет лева")]
15+
[InlineData(10, "десет лева")]
16+
[InlineData(11, "единадесет лева")]
17+
[InlineData(12, "дванадесет лева")]
18+
[InlineData(19, "деветнадесет лева")]
19+
[InlineData("0.0", "нула лева")]
20+
[InlineData("0.1", "десет стотинки")]
21+
[InlineData("1.20", "един лев и 20 ст.")]
22+
[InlineData("1.2", "един лев и 20 ст.")]
23+
[InlineData("1.3", "един лев и 30 ст.")]
24+
[InlineData("1.02", "един лев и 2 ст.")]
25+
[InlineData(118, "сто и осемнадесет лева")]
26+
[InlineData(123, "сто двадесет и три лева")]
27+
[InlineData(1000, "хиляда лева")]
28+
[InlineData(2000, "две хиляди лева")]
29+
[InlineData(3000, "три хиляди лева")]
30+
[InlineData(9000, "девет хиляди лева")]
31+
[InlineData("123.00", "сто двадесет и три лева")]
32+
[InlineData(1234, "хиляда двеста тридесет и четири лева")]
33+
[InlineData(1234.78, "хиляда двеста тридесет и четири лева и 78 ст.")]
34+
[InlineData(1019.78, "хиляда и деветнадесет лева и 78 ст.")]
35+
[InlineData(1109.78, "хиляда сто и девет лева и 78 ст.")]
36+
[InlineData(1119.78, "хиляда сто и деветнадесет лева и 78 ст.")]
37+
[InlineData(2014.78, "две хиляди и четиринадесет лева и 78 ст.")]
38+
[InlineData(4314.18, "четири хиляди триста и четиринадесет лева и 18 ст.")]
39+
[InlineData(123.45, "сто двадесет и три лева и 45 ст.")]
40+
[InlineData(0.01, "една стотинка")]
41+
[InlineData(0.10, "десет стотинки")]
42+
[InlineData(1.01, "един лев и 1 ст.")]
43+
[InlineData(1.10, "един лев и 10 ст.")]
44+
[InlineData(999.99, "деветстотин деветдесет и девет лева и 99 ст.")]
45+
[InlineData(9999.99, "девет хиляди деветстотин деветдесет и девет лева и 99 ст.")]
46+
[InlineData(10000, "десет хиляди лева")]
47+
[InlineData(10012, "десет хиляди и дванадесет лева")]
48+
[InlineData(10112, "десет хиляди сто и дванадесет лева")]
49+
[InlineData(10912, "десет хиляди деветстотин и дванадесет лева")]
50+
[InlineData(10900, "десет хиляди и деветстотин лева")]
51+
[InlineData(11900, "единадесет хиляди и деветстотин лева")]
52+
[InlineData(18900, "осемнадесет хиляди и деветстотин лева")]
53+
[InlineData(20900, "двадесет хиляди и деветстотин лева")]
54+
[InlineData(21900, "двадесет и една хиляди и деветстотин лева")]
55+
[InlineData(22900, "двадесет и две хиляди и деветстотин лева")]
56+
[InlineData(23901, "двадесет и три хиляди и деветстотин и един лева")]
57+
[InlineData(12000, "дванадесет хиляди лева")]
58+
[InlineData(11112, "единадесет хиляди сто и дванадесет лева")]
59+
[InlineData(32478.27, "тридесет и две хиляди четиристотин седемдесет и осем лева и 27 ст.")]
60+
[InlineData(32048.27, "тридесет и две хиляди и четиридесет и осем лева и 27 ст.")]
61+
[InlineData(32008.27, "тридесет и две хиляди и осем лева и 27 ст.")]
62+
[InlineData(99999.99, "деветдесет и девет хиляди деветстотин деветдесет и девет лева и 99 ст.")]
63+
[InlineData(999999.99, "деветстотин деветдесет и девет хиляди деветстотин деветдесет и девет лева и 99 ст.")]
64+
public void NumberToWordsBG_ShouldReturnCorrectWords(decimal number, string expected)
65+
{
66+
// Act
67+
string result = NumbersToWords.Convert(number);
68+
69+
// Assert
70+
Assert.Equal(expected, result);
71+
}
72+
73+
}
74+
}

src/Tests/Tests.csproj

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
11+
<PackageReference Include="xunit" Version="2.9.3" />
12+
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.2">
13+
<PrivateAssets>all</PrivateAssets>
14+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
15+
</PackageReference>
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<ProjectReference Include="..\OneBitSoftware.Slovom\OneBitSoftware.Slovom.csproj" />
20+
</ItemGroup>
21+
22+
</Project>

0 commit comments

Comments
 (0)