Skip to content

Instantly share code, notes, and snippets.

@pikoslav
Created March 25, 2022 13:06
Show Gist options
  • Save pikoslav/d9f4f23ecc440a8bb14c3f9e56bf0b5d to your computer and use it in GitHub Desktop.
Save pikoslav/d9f4f23ecc440a8bb14c3f9e56bf0b5d to your computer and use it in GitHub Desktop.
using System;
namespace Utils;
public static class SlovenianNumberToWords
{
public enum Gender
{
Masculine,
Feminine,
}
public static String Masculine(this Int64 value) => ToWords(value, Gender.Masculine);
public static String Feminine(this Int64 value) => ToWords(value, Gender.Feminine);
public static String ToWords(this Int64 value, Gender gender)
{
if (value <= - 1_000_000_000_000 || value >= 1_000_000_000_000) throw new ArgumentOutOfRangeException(nameof(value));
return Convert(value, gender).Trim();
}
//
private static String Convert(Int64 value, Gender gender)
{
if (value < 0) return "minus " + Convert(-value, gender);
if (value > 999_999_999_999) throw new ArgumentOutOfRangeException(nameof(value));
if (value == 0) return "nič";
var parts = new List<String>();
var milliards = value / 1_000_000_000;
value %= 1_000_000_000;
if (milliards > 0)
{
var n = milliards == 1 ? String.Empty : Convert_999(milliards, Gender.Feminine);
var m = (milliards % 10) switch
{
1 => "milijarda",
2 => "milijardi",
3 => "milijarde",
4 => "milijarde",
_ => "milijard",
};
parts.Add($"{n} {m}");
}
var millions = value / 1_000_000;
value %= 1_000_000;
if (millions > 0)
{
var n = millions == 1 ? "" : Convert_999(millions, parts.Count > 0 ? Gender.Feminine : Gender.Masculine);
var m = (millions % 10) switch
{
1 => "milijon",
2 => "milijona",
3 => parts.Count > 0 ? "milijone" : "milijoni",
4 => "milijoni",
_ => "milijonov",
};
parts.Add($"{n} {m}");
}
var thousands = value / 1_000;
value %= 1_000;
if (thousands > 0)
{
parts.Add(thousands switch
{
1 => "tisoč",
2 => "dva tisoč",
3 => "tri tisoč",
4 => "štiri tisoč",
_ => Convert_999(thousands, thousands % 10 == 3 ? Gender.Feminine : Gender.Masculine) + " tisoč",
});
}
parts.Add(Convert_999(value, gender));
return String.Join(" ", parts.ToArray());
}
private static String Convert_999(Int64 value, Gender gender)
{
// 0
if (value == 0) return "";
// 1-19
if (value <= 19)
{
return value switch
{
01 => gender == Gender.Masculine ? "en" : "ena",
02 => gender == Gender.Masculine ? "dva" : "dve",
03 => gender == Gender.Masculine ? "trije" : "tri",
04 => gender == Gender.Masculine ? "štirje" : "štiri",
05 => "pet",
06 => "šest",
07 => "sedem",
08 => "osem",
09 => "devet",
10 => "deset",
11 => "enajst",
12 => "dvanajst",
_ => Convert_999(value - 10, Gender.Feminine) + "najst",
};
}
// 20-99
if (value <= 99)
{
var tens = value / 10;
var ones = value % 10;
var result = tens == 2 ? "dvajset" : Convert(tens, Gender.Feminine) + "deset";
if (ones == 0) return result;
if (ones == 1) return $"enain{result}";
if (ones == 2) return $"dvain{result}";
return $"{Convert_999(ones, Gender.Feminine)}in{result}";
}
// 100-999
if (value <= 999)
{
return ((value / 100) switch
{
1 => "sto " + Convert_999(value % 100, gender),
2 => "dvesto " + Convert_999(value % 100, gender),
3 => "tristo " + Convert_999(value % 100, gender),
4 => "štiristo " + Convert_999(value % 100, gender),
_ => Convert_999(value / 100, Gender.Masculine) + "sto " + Convert_999(value % 100, gender),
}).TrimEnd();
}
throw new ArgumentOutOfRangeException(nameof(value));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment