Skip to content
This repository was archived by the owner on Aug 13, 2020. It is now read-only.

Add Lithuanian language #27

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion Numsense.UnitTests.CSharp/NumeralConverterProperties.cs
Original file line number Diff line number Diff line change
@@ -87,7 +87,11 @@ public static Arbitrary<ConverterPropertyGroup> Converter()
new ConverterPropertyGroup(
new RussianNumeralConverter(),
NumeralModule.toRussian,
NumeralModule.tryParseRussian)
NumeralModule.tryParseRussian),
new ConverterPropertyGroup(
new LithuanianNumeralConverter(),
NumeralModule.toLithuanian,
NumeralModule.tryParseLithuanian)
)
.ToArbitrary();
}
15 changes: 15 additions & 0 deletions Numsense.UnitTests.CSharp/NumeralTests.cs
Original file line number Diff line number Diff line change
@@ -79,5 +79,20 @@ public void RussianIsSingleton()
var actual = Numeral.Russian;
Assert.Same(expected, actual);
}

[Fact]
public void LithuanianIsCorrect()
{
var actual = Numeral.Lithuanian;
Assert.IsAssignableFrom<LithuanianNumeralConverter>(actual);
}

[Fact]
public void LithuanianIsSingleton()
{
var expected = Numeral.Lithuanian;
var actual = Numeral.Lithuanian;
Assert.Same(expected, actual);
}
}
}
4 changes: 2 additions & 2 deletions Numsense.UnitTests.CSharp/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.4.0.0")]
[assembly: AssemblyFileVersion("0.4.0.0")]
[assembly: AssemblyVersion("0.5.0.0")]
[assembly: AssemblyFileVersion("0.5.0.0")]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't change the version. There's no guarantee that the previous version is still 0.4.0 when this pull request is merged. It'll depend on which other changes were made before this happens.

I'll update the version number appropriately before releasing a new version.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your reason, fair enough. Issues fixed.

4 changes: 2 additions & 2 deletions Numsense.UnitTests/AssemblyInfo.fs
Original file line number Diff line number Diff line change
@@ -34,8 +34,8 @@ open System.Runtime.InteropServices
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [<assembly: AssemblyVersion("1.0.*")>]
[<assembly: AssemblyVersion("0.4.0.0")>]
[<assembly: AssemblyFileVersion("0.4.0.0")>]
[<assembly: AssemblyVersion("0.5.0.0")>]
[<assembly: AssemblyFileVersion("0.5.0.0")>]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't change the version. There's no guarantee that the previous version is still 0.4.0 when this pull request is merged. It'll depend on which other changes were made before this happens.

I'll update the version number appropriately before releasing a new version.


do
()
269 changes: 269 additions & 0 deletions Numsense.UnitTests/LithuanianExamples.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,269 @@
module Ploeh.Numsense.LithuanianExamples

open Xunit
open Swensen.Unquote

[<Theory>]
[<InlineData("nulis", 0)>]
[<InlineData(" nulis", 0)>]
[<InlineData("nulis ", 0)>]
[<InlineData(" nulis ", 0)>]
[<InlineData("Nulis", 0)>]
[<InlineData("NULIS", 0)>]
[<InlineData(" nULIs\t", 0)>]
[<InlineData("vienas", 1)>]
[<InlineData("VIENAS", 1)>]
[<InlineData("VIENA", 1)>]
[<InlineData("viENa", 1)>]
[<InlineData("du", 2)>]
[<InlineData(" du", 2)>]
[<InlineData(" dvi", 2)>]
[<InlineData("Dvi", 2)>]
[<InlineData("trys", 3)>]
[<InlineData("trys ", 3)>]
[<InlineData("keturi", 4)>]
[<InlineData(" keturi ", 4)>]
[<InlineData(" keturios ", 4)>]
[<InlineData("penki", 5)>]
[<InlineData("PenkI", 5)>]
[<InlineData("PenKios", 5)>]
[<InlineData("šeši", 6)>]
[<InlineData(" ŠEŠI ", 6)>]
[<InlineData("šešios", 6)>]
[<InlineData("septyni", 7)>]
[<InlineData(" sepTyni", 7)>]
[<InlineData("septynios", 7)>]
[<InlineData("aštuoni", 8)>]
[<InlineData("ašTUONI", 8)>]
[<InlineData("aštuonios", 8)>]
[<InlineData("devyni", 9)>]
[<InlineData("devyni ", 9)>]
[<InlineData("devynios", 9)>]
[<InlineData("dešimt", 10)>]
[<InlineData("vienuolika", 11)>]
[<InlineData("dvylika", 12)>]
[<InlineData("trylika", 13)>]
[<InlineData("keturiolika", 14)>]
[<InlineData("penkiolika", 15)>]
[<InlineData("šešiolika", 16)>]
[<InlineData("septyniolika", 17)>]
[<InlineData("aštuoniolika", 18)>]
[<InlineData("devyniolika", 19)>]
[<InlineData("dvidešimt", 20)>]
[<InlineData("dvidešimt vienas", 21)>]
[<InlineData("dvidešimt dvi", 22)>]
[<InlineData("dvidešimt vienas", 21)>]
[<InlineData("trisdešimt", 30)>]
[<InlineData("trisdešimt keturi", 34)>]
[<InlineData("trisdešimt keturios", 34)>]
[<InlineData("trisdešimt aštuoni", 38)>]
[<InlineData("keturiasdešimt", 40)>]
[<InlineData("keturiasdešimt vienas", 41)>]
[<InlineData("keturiasdešimt viena", 41)>]
[<InlineData("keturiasdešimt keturi", 44)>]
[<InlineData("penkiasdešimt", 50)>]
[<InlineData("penkiasdešimt septyni", 57)>]
[<InlineData("penkiasdešimt septynios", 57)>]
[<InlineData("šešiasdešimt", 60)>]
[<InlineData("šešiasdešimt penki", 65)>]
[<InlineData("šešiasdešimt penkios", 65)>]
[<InlineData("septyniasdešimt", 70)>]
[<InlineData("septyniasdešimt septyni", 77)>]
[<InlineData("septyniasdešimt septynios", 77)>]
[<InlineData("septyniasdešimt devyni", 79)>]
[<InlineData("septyniasdešimt devynios", 79)>]
[<InlineData("aštuoniasdešimt", 80)>]
[<InlineData("aštuoniasdešimt šeši", 86)>]
[<InlineData("aštuoniasdešimt šešios", 86)>]
[<InlineData("devyniasdešimt", 90)>]
[<InlineData("devyniasdešimt trys", 93)>]
[<InlineData("šimtas", 100)>]
[<InlineData("vienas šimtas", 100)>]
[<InlineData("šimtas vienas", 101)>]
[<InlineData("šimtas vienas", 101)>]
[<InlineData("šimtas viena", 101)>]
[<InlineData("vienas šimtas ir vienas", 101)>]
[<InlineData("vienas šimtas ir viena", 101)>]
[<InlineData("šimtas ir vienas", 101)>]
[<InlineData("du šimtai", 200)>]
[<InlineData("du šimtai trisdešimt septyni", 237)>]
[<InlineData("trys šimtai septyniasdešimt penki", 375)>]
[<InlineData("keturi šimtai devyniasdešimt", 490)>]
[<InlineData("penki šimtai šešiasdešimt trys", 563)>]
[<InlineData("šeši šimtai aštuoniolika", 618)>]
[<InlineData("septyni šimtai septyniasdešimt septyni", 777)>]
[<InlineData("septyni šimtai septyniasdešimt septynios", 777)>]
[<InlineData("aštuoni šimtai penki", 805)>]
[<InlineData("aštuoni šimtai ir šeši", 806)>]
[<InlineData("aštuoni šimtai ir septyni", 807)>]
[<InlineData("devyni šimtai penkiasdešimt devyni", 959)>]
[<InlineData("tūkstantis", 1000)>]
[<InlineData("vienas tūkstantis", 1000)>]
[<InlineData("tūkstantis vienas", 1001)>]
[<InlineData("tūkstantis ir viena", 1001)>]
[<InlineData("vienas tūkstantis du", 1002)>]
[<InlineData("vienas tūkstantis dvi", 1002)>]
[<InlineData("vienas tūkstantis šešiasdešimt keturi", 1064)>]
[<InlineData("du tūkstančiai", 2000)>]
[<InlineData("aštuoni tūkstančiai septyni šimtai dvidešimt vienas", 8721)>]
[<InlineData("devyni tūkstančiai šimtas dvidešimt trys", 9123)>]
[<InlineData("dešimt tūkstančių", 10000)>]
[<InlineData("dešimt tūkstančių vienas šimtas vienas", 10101)>]
[<InlineData("dešimt tūkstančių šimtas du", 10102)>]
[<InlineData("dvidešimt trys tūkstančiai penki šimtai šešiasdešimt keturi", 23564)>]
[<InlineData("aštuoniasdešimt tūkstančių dešimt", 80010)>]
[<InlineData("šimtas tūkstančių", 100000)>]
[<InlineData("vienas šimtas tūkstančių", 100000)>]
[<InlineData("šimtas tūkstančių vienas", 100001)>]
[<InlineData("trys šimtai devyniolika tūkstančių trys šimtai keturiasdešimt devyni", 319349)>]
[<InlineData("trys šimtai devyniolika tūkstančių trys šimtai keturiasdešimt devynios", 319349)>]
[<InlineData("vienas milijonas", 1000000)>]
[<InlineData("milijonas vienas", 1000001)>]
[<InlineData("du milijonai dešimt", 2000010)>]
[<InlineData("šeši milijonai trisdešimt tūkstančių", 6030000)>]
[<InlineData("devyni milijonai du šimtai vienas tūkstantis šeši šimtai aštuoniasdešimt", 9201680)>]
[<InlineData("dešimt milijonų", 10000000)>]
[<InlineData("dešimt milijonų devyni", 10000009)>]
[<InlineData("dvidešimt vienas milijonas", 21000000)>]
[<InlineData("keturiasdešimt septyni milijonai šeši šimtai šešiasdešimt vienas tūkstantis šešiasdešimt", 47661060)>]
[<InlineData("šimtas milijonų", 100000000)>]
[<InlineData("vienas šimtas milijonų", 100000000)>]
[<InlineData("du šimtai penki milijonai", 205000000)>]
[<InlineData("trys šimtai ir septyni milijonai", 307000000)>]
[<InlineData("keturi šimtai šešiasdešimt vienas milijonas šešiasdešimt tūkstančių šeši šimtai", 461060600)>]
[<InlineData("vienas milijardas", 1000000000)>]
[<InlineData("du milijardai", 2000000000)>]
[<InlineData("du milijardai keturiasdešimt devyni milijonai šeši šimtai penkiasdešimt tūkstančių", 2049650000)>]
[<InlineData(
"du milijardai vienas šimtas keturiasdešimt septyni milijonai keturi šimtai aštuoniasdešimt trys tūkstančiai šeši šimtai keturiasdešimt septyni",
System.Int32.MaxValue)>]
[<InlineData(
"du milijardai vienas šimtas keturiasdešimt septyni milijonai keturi šimtai aštuoniasdešimt trys tūkstančiai šeši šimtai keturiasdešimt septynios",
System.Int32.MaxValue)>]
let ``tryParseLithuanian returns correct result`` (lithuanian, expected) =
let actual = Numeral.tryParseLithuanian lithuanian
Some expected =! actual

[<Theory>]
[<InlineData(0, "nulis")>]
[<InlineData(1, "vienas")>]
[<InlineData(2, "du")>]
[<InlineData(3, "trys")>]
[<InlineData(4, "keturi")>]
[<InlineData(5, "penki")>]
[<InlineData(6, "šeši")>]
[<InlineData(7, "septyni")>]
[<InlineData(8, "aštuoni")>]
[<InlineData(9, "devyni")>]
[<InlineData(10, "dešimt")>]
[<InlineData(11, "vienuolika")>]
[<InlineData(12, "dvylika")>]
[<InlineData(13, "trylika")>]
[<InlineData(14, "keturiolika")>]
[<InlineData(15, "penkiolika")>]
[<InlineData(16, "šešiolika")>]
[<InlineData(17, "septyniolika")>]
[<InlineData(18, "aštuoniolika")>]
[<InlineData(19, "devyniolika")>]
[<InlineData(20, "dvidešimt")>]
[<InlineData(21, "dvidešimt vienas")>]
[<InlineData(30, "trisdešimt")>]
[<InlineData(34, "trisdešimt keturi")>]
[<InlineData(40, "keturiasdešimt")>]
[<InlineData(42, "keturiasdešimt du")>]
[<InlineData(50, "penkiasdešimt")>]
[<InlineData(58, "penkiasdešimt aštuoni")>]
[<InlineData(60, "šešiasdešimt")>]
[<InlineData(65, "šešiasdešimt penki")>]
[<InlineData(70, "septyniasdešimt")>]
[<InlineData(79, "septyniasdešimt devyni")>]
[<InlineData(80, "aštuoniasdešimt")>]
[<InlineData(86, "aštuoniasdešimt šeši")>]
[<InlineData(90, "devyniasdešimt")>]
[<InlineData(93, "devyniasdešimt trys")>]
[<InlineData(100, "šimtas")>]
[<InlineData(101, "šimtas vienas")>]
[<InlineData(110, "šimtas dešimt")>]
[<InlineData(114, "šimtas keturiolika")>]
[<InlineData(135, "šimtas trisdešimt penki")>]
[<InlineData(200, "du šimtai")>]
[<InlineData(282, "du šimtai aštuoniasdešimt du")>]
[<InlineData(331, "trys šimtai trisdešimt vienas")>]
[<InlineData(407, "keturi šimtai septyni")>]
[<InlineData(520, "penki šimtai dvidešimt")>]
[<InlineData(666, "šeši šimtai šešiasdešimt šeši")>]
[<InlineData(798, "septyni šimtai devyniasdešimt aštuoni")>]
[<InlineData(857, "aštuoni šimtai penkiasdešimt septyni")>]
[<InlineData(999, "devyni šimtai devyniasdešimt devyni")>]
[<InlineData(1000, "tūkstantis")>]
[<InlineData(1001, "tūkstantis vienas")>]
[<InlineData(1010, "tūkstantis dešimt")>]
[<InlineData(1066, "tūkstantis šešiasdešimt šeši")>]
[<InlineData(1337, "tūkstantis trys šimtai trisdešimt septyni")>]
[<InlineData(1984, "tūkstantis devyni šimtai aštuoniasdešimt keturi")>]
[<InlineData(2015, "du tūkstančiai penkiolika")>]
[<InlineData(3000, "trys tūkstančiai")>]
[<InlineData(3297, "trys tūkstančiai du šimtai devyniasdešimt septyni")>]
[<InlineData(4080, "keturi tūkstančiai aštuoniasdešimt")>]
[<InlineData(5011, "penki tūkstančiai vienuolika")>]
[<InlineData(6025, "šeši tūkstančiai dvidešimt penki")>]
[<InlineData(7441, "septyni tūkstančiai keturi šimtai keturiasdešimt vienas")>]
[<InlineData(8513, "aštuoni tūkstančiai penki šimtai trylika")>]
[<InlineData(9000, "devyni tūkstančiai")>]
[<InlineData(10000, "dešimt tūkstančių")>]
[<InlineData(12001, "dvylika tūkstančių vienas")>]
[<InlineData(23456, "dvidešimt trys tūkstančiai keturi šimtai penkiasdešimt šeši")>]
[<InlineData(32109, "trisdešimt du tūkstančiai šimtas devyni")>]
[<InlineData(40404, "keturiasdešimt tūkstančių keturi šimtai keturi")>]
[<InlineData(56789, "penkiasdešimt šeši tūkstančiai septyni šimtai aštuoniasdešimt devyni")>]
[<InlineData(60015, "šešiasdešimt tūkstančių penkiolika")>]
[<InlineData(71003, "septyniasdešimt vienas tūkstantis trys")>]
[<InlineData(80522, "aštuoniasdešimt tūkstančių penki šimtai dvidešimt du")>]
[<InlineData(98765, "devyniasdešimt aštuoni tūkstančiai septyni šimtai šešiasdešimt penki")>]
[<InlineData(100000, "šimtas tūkstančių")>]
[<InlineData(100001, "šimtas tūkstančių vienas")>]
[<InlineData(100010, "šimtas tūkstančių dešimt")>]
[<InlineData(101010, "šimtas vienas tūkstantis dešimt")>]
[<InlineData(200000, "du šimtai tūkstančių")>]
[<InlineData(321000, "trys šimtai dvidešimt vienas tūkstantis")>]
[<InlineData(411416, "keturi šimtai vienuolika tūkstančių keturi šimtai šešiolika")>]
[<InlineData(530121, "penki šimtai trisdešimt tūkstančių šimtas dvidešimt vienas")>]
[<InlineData(600000, "šeši šimtai tūkstančių")>]
[<InlineData(788000, "septyni šimtai aštuoniasdešimt aštuoni tūkstančiai")>]
[<InlineData(876540, "aštuoni šimtai septyniasdešimt šeši tūkstančiai penki šimtai keturiasdešimt")>]
[<InlineData(908077, "devyni šimtai aštuoni tūkstančiai septyniasdešimt septyni")>]
[<InlineData(1000000, "milijonas")>]
[<InlineData(2000002, "du milijonai du")>]
[<InlineData(3040506, "trys milijonai keturiasdešimt tūkstančių penki šimtai šeši")>]
[<InlineData(4321000, "keturi milijonai trys šimtai dvidešimt vienas tūkstantis")>]
[<InlineData(5004621, "penki milijonai keturi tūkstančiai šeši šimtai dvidešimt vienas")>]
[<InlineData(6982001, "šeši milijonai devyni šimtai aštuoniasdešimt du tūkstančiai vienas")>]
[<InlineData(7000000, "septyni milijonai")>]
[<InlineData(8000220, "aštuoni milijonai du šimtai dvidešimt")>]
[<InlineData(9099000, "devyni milijonai devyniasdešimt devyni tūkstančiai")>]
[<InlineData(10000000, "dešimt milijonų")>]
[<InlineData(24000000, "dvidešimt keturi milijonai")>]
[<InlineData(39020011, "trisdešimt devyni milijonai dvidešimt tūkstančių vienuolika")>]
[<InlineData(40606100, "keturiasdešimt milijonų šeši šimtai šeši tūkstančiai šimtas")>]
[<InlineData(53000000, "penkiasdešimt trys milijonai")>]
[<InlineData(64000098, "šešiasdešimt keturi milijonai devyniasdešimt aštuoni")>]
[<InlineData(70003190, "septyniasdešimt milijonų trys tūkstančiai šimtas devyniasdešimt")>]
[<InlineData(80000000, "aštuoniasdešimt milijonų")>]
[<InlineData(99000099, "devyniasdešimt devyni milijonai devyniasdešimt devyni")>]
[<InlineData(100000000, "šimtas milijonų")>]
[<InlineData(209000000, "du šimtai devyni milijonai")>]
[<InlineData(398000000, "trys šimtai devyniasdešimt aštuoni milijonai")>]
[<InlineData(439011000, "keturi šimtai trisdešimt devyni milijonai vienuolika tūkstančių")>]
[<InlineData(560400000, "penki šimtai šešiasdešimt milijonų keturi šimtai tūkstančių")>]
[<InlineData(600010900, "šeši šimtai milijonų dešimt tūkstančių devyni šimtai")>]
[<InlineData(700000000, "septyni šimtai milijonų")>]
[<InlineData(800116000, "aštuoni šimtai milijonų šimtas šešiolika tūkstančių")>]
[<InlineData(900800007, "devyni šimtai milijonų aštuoni šimtai tūkstančių septyni")>]
[<InlineData(1000000000, "milijardas")>]
[<InlineData(2110000000, "du milijardai šimtas dešimt milijonų")>]
[<InlineData(
System.Int32.MaxValue,
"du milijardai šimtas keturiasdešimt septyni milijonai keturi šimtai aštuoniasdešimt trys tūkstančiai šeši šimtai keturiasdešimt septyni")>]
let ``toLithuanian returns correct result`` (i, expected) =
let actual = Numeral.toLithuanian i
expected =! actual
15 changes: 15 additions & 0 deletions Numsense.UnitTests/NumeralProperties.fs
Original file line number Diff line number Diff line change
@@ -77,4 +77,19 @@ let ``negative Russian is the inverse of positive Russian`` x =
let actualInteger = Numeral.tryParseRussian actualRussian

sprintf "минус %s" (Numeral.toRussian x) =! actualRussian
Some -x =! actualInteger

[<Property(QuietOnSuccess = true)>]
let ``tryParseLithuanian is the inverse of toLithuanian`` x =
test <@ Some x = (x |> Numeral.toLithuanian |> Numeral.tryParseLithuanian) @>

[<Property(QuietOnSuccess = true)>]
let ``negative Lithuanian is the inverse of positive Lithuanian`` x =
x <> 0 ==> lazy
let x = abs x

let actualLithuanian = Numeral.toLithuanian -x
let actualInteger = Numeral.tryParseLithuanian actualLithuanian

sprintf "minus %s" (Numeral.toLithuanian x) =! actualLithuanian
Some -x =! actualInteger
1 change: 1 addition & 0 deletions Numsense.UnitTests/Numsense.UnitTests.fsproj
Original file line number Diff line number Diff line change
@@ -58,6 +58,7 @@
<Compile Include="PolishExamples.fs" />
<Compile Include="DutchExamples.fs" />
<Compile Include="RussianExamples.fs" />
<Compile Include="LithuanianExamples.fs" />
<Compile Include="Demo.fs" />
<Content Include="packages.config" />
<Content Include="App.config" />
4 changes: 2 additions & 2 deletions Numsense/AssemblyInfo.fs
Original file line number Diff line number Diff line change
@@ -34,8 +34,8 @@ open System.Runtime.InteropServices
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [<assembly: AssemblyVersion("1.0.*")>]
[<assembly: AssemblyVersion("0.4.0.0")>]
[<assembly: AssemblyFileVersion("0.4.0.0")>]
[<assembly: AssemblyVersion("0.5.0.0")>]
[<assembly: AssemblyFileVersion("0.5.0.0")>]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't change the version. There's no guarantee that the previous version is still 0.4.0 when this pull request is merged. It'll depend on which other changes were made before this happens.

I'll update the version number appropriately before releasing a new version.


do
()
134 changes: 134 additions & 0 deletions Numsense/Lithuanian.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
module internal Ploeh.Numsense.Lithuanian

open Ploeh.Numsense.InternalDsl

let rec internal toLithuanianImp x =

let simplify prefix factor x =
let remainder = x % factor
if remainder = 0
then prefix
else sprintf "%s %s" prefix (toLithuanianImp (remainder))

let formatNumeral suffix factor x =
let prefix = sprintf "%s%s" (toLithuanianImp (x / factor)) suffix
simplify prefix factor x

let formatNoun suffix factor x =
let factored = x /factor
let prefix =
match factored with
| 1 -> sprintf "%s" (suffix factored)
| _ -> sprintf "%s %s" (toLithuanianImp factored) (suffix factored)
simplify prefix factor x

let (|Singular|Paucal|Plural|) x =
let units = x % 10
let tens = x / 10 % 10
match tens, units with
| 1, _
| _, 0 -> Plural
| _, 1 -> Singular
| _ -> Paucal

let thousand =
function
| Singular -> "tūkstantis"
| Paucal -> "tūkstančiai"
| Plural -> "tūkstančių"

let million =
function
| Singular -> "milijonas"
| Paucal -> "milijonai"
| Plural -> "milijonų"

let billion =
function
| Singular -> "milijardas"
| Paucal -> "milijardai"
| Plural -> "milijardų"

match x with
| x when x < 0 -> sprintf "minus %s" (toLithuanianImp -x)
| 0 -> "nulis"
| 1 -> "vienas"
| 2 -> "du"
| 3 -> "trys"
| 4 -> "keturi"
| 5 -> "penki"
| 6 -> "šeši"
| 7 -> "septyni"
| 8 -> "aštuoni"
| 9 -> "devyni"
| 10 -> "dešimt"
| 11 -> "vienuolika"
| 12 -> "dvylika"
| 13 -> "trylika"
| 14 -> "keturiolika"
| 15 -> "penkiolika"
| 16 -> "šešiolika"
| 17 -> "septyniolika"
| 18 -> "aštuoniolika"
| 19 -> "devyniolika"
| Between 20 30 x -> simplify "dvidešimt" 10 x
| Between 30 40 x -> simplify "trisdešimt" 10 x
| Between 40 100 x -> formatNumeral "asdešimt" 10 x
| Between 100 200 x -> simplify "šimtas" 100 x
| Between 200 1000 x -> formatNumeral " šimtai" 100 x
| Between 1000 1000000 x -> formatNoun thousand 1000 x
| Between 1000000 1000000000 x -> formatNoun million 1000000 x
| _ -> formatNoun billion 1000000000 x

let internal tryParseLithuanianImp (x : string) =
let rec conv acc candidate =
match candidate with
| "" -> Some acc
| StartsWith " " t
| StartsWith "IR" t -> conv acc t
| StartsWith "NULIS" t -> conv (0 + acc) t
| StartsWith "VIENAS" t
| StartsWith "VIENA" t -> conv (1 + acc) t
| StartsWith "DVIDEŠIMT" t -> conv (20 + acc) t
| StartsWith "DVI" t
| StartsWith "DU" t -> conv (2 + acc) t
| StartsWith "TRYS" t -> conv (3 + acc) t
| StartsWith "KETURIOS" t
| StartsWith "KETURI" t -> conv (4 + acc) t
| StartsWith "PENKIOS" t
| StartsWith "PENKI" t -> conv (5 + acc) t
| StartsWith "ŠEŠIOS" t
| StartsWith "ŠEŠI" t -> conv (6 + acc) t
| StartsWith "SEPTYNIOS" t
| StartsWith "SEPTYNI" t -> conv (7 + acc) t
| StartsWith "AŠTUONIOS" t
| StartsWith "AŠTUONI" t -> conv (8 + acc) t
| StartsWith "DEVYNIOS" t
| StartsWith "DEVYNI" t -> conv (9 + acc) t
| StartsWith "DEŠIMT" t -> conv (10 + acc) t
| StartsWith "VIENUOLIKA" t -> conv (11 + acc) t
| StartsWith "DVYLIKA" t -> conv (12 + acc) t
| StartsWith "TRYLIKA" t -> conv (13 + acc) t
| StartsWith "OLIKA" t -> conv (10 + acc) t
| StartsWith "TRISDEŠIMT" t -> conv (30 + acc) t
| StartsWith "ASDEŠIMT" t -> conv (10 %* acc) t
| StartsWith "ŠIMTAS" t ->
conv (if acc % 10 = 0 then 100 + acc else 100 %* acc) t
| StartsWith "ŠIMTAI" t -> conv (100 %* acc) t
| StartsWith "TŪKSTANTIS" t ->
conv (if acc % 10 = 0 then 1000 + acc else 1000 %* acc) t
| StartsWith "TŪKSTANČIAI" t
| StartsWith "TŪKSTANČIŲ" t -> conv (1000 %* acc) t
| StartsWith "MILIJONAS" t ->
conv (if acc % 10 = 0 then 1000000 + acc else 1000000 %* acc) t
| StartsWith "MILIJONAI" t
| StartsWith "MILIJONŲ" t -> conv (1000000 %* acc) t
| StartsWith "MILIJARDAS" t -> conv 1000000000 t
| StartsWith "MILIJARDAI" t
| StartsWith "MILIJARDŲ" t -> conv (1000000000 %* acc) t
| _ -> None

let canonicalized = x.Trim().ToUpper(System.Globalization.CultureInfo "lt")
match canonicalized with
| StartsWith "MINUS" t -> conv 0 (t.Trim ()) |> Option.map ((*)-1)
| _ -> conv 0 canonicalized
5 changes: 4 additions & 1 deletion Numsense/Numeral.fs
Original file line number Diff line number Diff line change
@@ -14,4 +14,7 @@ let toDutch = Dutch.toDutchImp
let tryParseDutch = Dutch.tryParseDutchImp

let toRussian = Russian.toRussianImp Russian.Masculine
let tryParseRussian = Russian.tryParseRussianImp
let tryParseRussian = Russian.tryParseRussianImp

let toLithuanian = Lithuanian.toLithuanianImp
let tryParseLithuanian = Lithuanian.tryParseLithuanianImp
1 change: 1 addition & 0 deletions Numsense/Numsense.fsproj
Original file line number Diff line number Diff line change
@@ -59,6 +59,7 @@
<Compile Include="Polish.fs" />
<Compile Include="Dutch.fs" />
<Compile Include="Russian.fs" />
<Compile Include="Lithuanian.fs" />
<Compile Include="Numeral.fs" />
<Compile Include="ObjectOriented.fs" />
<Content Include="packages.config" />
9 changes: 8 additions & 1 deletion Numsense/ObjectOriented.fs
Original file line number Diff line number Diff line change
@@ -43,10 +43,17 @@ type RussianNumeralConverter () =
member this.ToNumeral number = Numeral.toRussian number
member this.TryParse (s, result) =
Helper.tryParse Numeral.tryParseRussian (s, &result)

type LithuanianNumeralConverter () =
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the Devil's Advocate review technique, if I remove this type, then all tests still pass.

interface INumeralConverter with
member this.ToNumeral number = Numeral.toLithuanian number
member this.TryParse (s, result) =
Helper.tryParse Numeral.tryParseLithuanian (s, &result)

type Numeral private () =
static member val English = EnglishNumeralConverter () :> INumeralConverter
static member val Danish = DanishNumeralConverter () :> INumeralConverter
static member val Polish = PolishNumeralConverter () :> INumeralConverter
static member val Dutch = DutchNumeralConverter () :> INumeralConverter
static member val Russian = RussianNumeralConverter () :> INumeralConverter
static member val Russian = RussianNumeralConverter () :> INumeralConverter
static member val Lithuanian = LithuanianNumeralConverter () :> INumeralConverter
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the Devil's Advocate review technique, if I remove this member, then all tests still pass.