using System.Collections.Generic;
public int Thousands { get; set; }
public int Hundreds { get; set; }
public int Tens { get; set; }
public int Cents { get; set; }
public MoneyTypes(int thousands, int hundreds, int tens, int cents)
public class WordConversionService
public Dictionary<int, string> Singlular => new()
public Dictionary<int, string> DoubleUnderTwenty => new()
public Dictionary<int, string> MultipleOfTens => new()
public string Execute(decimal number)
if (number == decimal.Zero)
return "Error: Value too high, enter a value below 1000.";
var data = MoneyConversion(number);
return ConvertToWord(data);
private MoneyTypes MoneyConversion(decimal number)
var dollars = decimal.ToInt32(number);
var split = number.ToString()?.Split(".");
var centValue = split[1];
var singularLengthCent = centValue.Length == 1;
cents = singularLengthCent ? (int.Parse(centValue) * 10) : int.Parse(centValue.Substring(0,2));
var thousands = (dollars % 10000) / 1000;
var hundreds = (dollars % 1000) / 100;
var tens = (dollars % 100);
return new MoneyTypes(thousands, hundreds, tens, cents);
private string ConvertToWord(MoneyTypes moneyTypes)
var finalString = string.Empty;
if(moneyTypes.Thousands > 0){
var thousands = ConvertThousands(moneyTypes.Thousands);
finalString += thousands;
if (moneyTypes.Hundreds > 0)
var hundreds = ConvertHundreds(moneyTypes.Hundreds);
var tens = ConvertDoubleNumber(moneyTypes.Tens);
finalString += (finalString == string.Empty) ? tens : $" and {tens}";
finalString += Dollars(moneyTypes);
if (moneyTypes.Cents > 0 )
var cents = ConvertDoubleNumber(moneyTypes.Cents);
finalString += finalString == string.Empty ? cents : $" and {cents}";
finalString += Cents(moneyTypes.Cents);
private string ConvertDoubleNumber(int number)
var tens = (number % 100) / 10;
var singleValue = tens == 0;
if (singleValue) return ConvertSingleNumber(ones);
var underTwentyDoubles = tens == 1;
if (underTwentyDoubles) return ConvertDoubleStartingWithOnes(ones);
var oneWords = ones > 0 ? $" {ConvertSingleNumber(ones)}" : string.Empty;
return $"{MultipleOfTens[tens]}{oneWords}";
private string ConvertSingleNumber(int number) => Singlular[number];
private string ConvertDoubleStartingWithOnes(int number) => DoubleUnderTwenty[number];
private string ConvertThousands(int number) => $"{ConvertSingleNumber(number)} thousand";
private string ConvertHundreds(int number) => $"{ConvertSingleNumber(number)} hundred";
private string Dollars(MoneyTypes moneyType)
var totalAmount = moneyType.Thousands + moneyType.Hundreds + moneyType.Tens;
if (totalAmount == 1 && moneyType.Tens == 1) return " dollar";
if (totalAmount > 0) return " dollars";
private string Cents(int cents)
if (cents == 0) return string.Empty;
if (cents == 1) return " cent";
static string DollarsToWords(decimal value)
var wordConversionService = new WordConversionService();
var words = wordConversionService.Execute(value);
public static void Main()
Test(0.12m, "twelve cents");
Test(10.55m, "ten dollars and fifty five cents");
Test(120, "one hundred and twenty dollars");
Test(99, "ninety nine dollars");
Test(91, "ninety one dollars");
Test(0.99m, "ninety nine cents");
Test(1000, "one thousand dollars");
Test(901, "nine hundred and one dollars");
Test(10000, "Error: Value too high, enter a value below 1000.");
Test(0.10m, "ten cents");
Test(100, "one hundred dollars");
Test(110, "one hundred and ten dollars");
Test(111, "one hundred and eleven dollars");
Test(110.01m, "one hundred and ten dollars and one cent");
Test(110.10m, "one hundred and ten dollars and ten cents");
Test(0.12m, "twelve cents");
Test(0.09m, "nine cents");
Test(0.90m, "ninety cents");
Test(0.99m, "ninety nine cents");
Test(0.48m, "forty eight cents");
Test(25, "twenty five dollars");
Test(91, "ninety one dollars");
Test(99, "ninety nine dollars");
Test(120, "one hundred and twenty dollars");
Test(899, "eight hundred and ninety nine dollars");
Test(901, "nine hundred and one dollars");
Test(1.01m, "one dollar and one cent");
Test(1.55m, "one dollar and fifty five cents");
Test(1.63m, "one dollar and sixty three cents");
Test(10.55m, "ten dollars and fifty five cents");
Test(77.01m, "seventy seven dollars and one cent");
Test(70.40m, "seventy dollars and forty cents");
Test(500.55m, "five hundred dollars and fifty five cents");
Test(763.3m, "seven hundred and sixty three dollars and thirty cents");
Test(763.38m, "seven hundred and sixty three dollars and thirty eight cents");
Test(999.99m, "nine hundred and ninety nine dollars and ninety nine cents");
static void Test(decimal number, string expected)
var actual = DollarsToWords(number);
Console.WriteLine($"{number}: PASS");
Console.WriteLine($"{number}: FAIL");
Console.WriteLine($" Expected: {expected}");
Console.WriteLine($" Actual: {actual}");