Creating Human-Readable Integer Views

Here's a coding problem for those who like these things. Let's look at your implementations (of course, in your choice language) of a function that returns a human readable representation of a String of the specified Integer. For instance:

  • humanReadable (1) returns "one".
  • humanReadable (53) returns "fifty three".
  • humanReadable (723603) returns "seven hundred twenty three thousand six hundred and three."
  • humanReadable (1456376562) returns "one billion, four hundred fifty six million three hundred seventy six thousand five hundred sixty two."

Bonus points for particularly smart / elegant solutions!

This may seem like a pointless exercise, but for this type of algorithm there are many real-world applications (although supporting numbers up to a billion can be excessive :-)

+4
source share
6 answers

There was already a question: Converting integers to written numbers

The answer is in C #, but I think you can figure it out.

+8
source
import math def encodeOnesDigit(num): return ['', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'][num] def encodeTensDigit(num): return ['twenty', 'thirty', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'][num-2] def encodeTeens(num): if num < 10: return encodeOnesDigit(num) else: return ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'][num-10] def encodeTriplet(num): if num == 0: return '' str = '' if num >= 100: str = encodeOnesDigit(num / 100) + ' hundred' tens = num % 100 if tens >= 20: if str != '': str += ' ' str += encodeTensDigit(tens / 10) if tens % 10 > 0: str += '-' + encodeOnesDigit(tens % 10) elif tens != 0: if str != '': str += ' ' str += encodeTeens(tens) return str def zipNumbers(numList): if len(numList) == 1: return numList[0] strList = ['', ' thousand', ' million', ' billion'] # Add more as needed strList = strList[:len(numList)] strList.reverse() joinedList = zip(numList, strList) joinedList = [item for item in joinedList if item[0] != ''] return ', '.join(''.join(item) for item in joinedList) def humanReadable(num): if num == 0: return 'zero' negative = False if num < 0: num *= -1 negative = True numString = str(num) tripletCount = int(math.ceil(len(numString) / 3.0)) numString = numString.zfill(tripletCount * 3) tripletList = [int(numString[i*3:i*3+3]) for i in range(tripletCount)] readableList = [encodeTriplet(num) for num in tripletList] readableStr = zipNumbers(readableList) return 'negative ' + readableStr if negative else readableStr 
+3
source

Supports up to 999 million, but not negative numbers:

 String humanReadable(int inputNumber) { if (inputNumber == -1) { return ""; } int remainder; int quotient; quotient = inputNumber / 1000000; remainder = inputNumber % 1000000; if (quotient > 0) { return humanReadable(quotient) + " million, " + humanReadable(remainder); } quotient = inputNumber / 1000; remainder = inputNumber % 1000; if (quotient > 0) { return humanReadable(quotient) + " thousand, " + humanReadable(remainder); } quotient = inputNumber / 100; remainder = inputNumber % 100; if (quotient > 0) { return humanReadable(quotient) + " hundred, " + humanReadable(remainder); } quotient = inputNumber / 10; remainder = inputNumber % 10; if (remainder == 0) { //hackish way to flag the algorithm to not output something like "twenty zero" remainder = -1; } if (quotient == 1) { switch(inputNumber) { case 10: return "ten"; case 11: return "eleven"; case 12: return "twelve"; case 13: return "thirteen"; case 14: return "fourteen"; case 15: return "fifteen"; case 16: return "sixteen"; case 17: return "seventeen"; case 18: return "eighteen"; case 19: return "nineteen"; } } switch(quotient) { case 2: return "twenty " + humanReadable(remainder); case 3: return "thirty " + humanReadable(remainder); case 4: return "forty " + humanReadable(remainder); case 5: return "fifty " + humanReadable(remainder); case 6: return "sixty " + humanReadable(remainder); case 7: return "seventy " + humanReadable(remainder); case 8: return "eighty " + humanReadable(remainder); case 9: return "ninety " + humanReadable(remainder); } switch(inputNumber) { case 0: return "zero"; case 1: return "one"; case 2: return "two"; case 3: return "three"; case 4: return "four"; case 5: return "five"; case 6: return "six"; case 7: return "seven"; case 8: return "eight"; case 9: return "nine"; } } 
+1
source
 using System; namespace HumanReadable { public static class HumanReadableExt { private static readonly string[] _digits = { "", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" }; private static readonly string[] _teens = { "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" }; private static readonly string[] _illions = { "", "thousand", "million", "billion", "trillion" }; private static string Seg(int number) { var work = string.Empty; if (number >= 100) work += _digits[number / 100] + " hundred "; if ((number % 100) < 20) work += _digits[number % 100]; else work += _teens[(number % 100) / 10] + "-" + _digits[number % 10]; return work; } public static string HumanReadable(this int number) { if (number == 0) return "zero"; var work = string.Empty; var parts = new string[_illions.Length]; for (var ind = 0; ind < parts.Length; ind++) parts[ind] = Seg((int) (number % Math.Pow(1000, ind + 1) / Math.Pow(1000, ind))); for (var ind = 0; ind < parts.Length; ind++) if (!string.IsNullOrEmpty(parts[ind])) work = parts[ind] + " " + _illions[ind] + ", " + work; work = work.TrimEnd(',', ' '); var lastSpace = work.LastIndexOf(' '); if (lastSpace >= 0) work = work.Substring(0, lastSpace) + " and" + work.Substring(lastSpace); return work; } } class Program { static void Main(string[] args) { Console.WriteLine(1.HumanReadable()); Console.WriteLine(53.HumanReadable()); Console.WriteLine(723603.HumanReadable()); Console.WriteLine(1456376562.HumanReadable()); Console.ReadLine(); } } } 
+1
source

There is one huge problem in implementing this feature. This is future localization. This feature, written by an English native speaker, will most likely not work in any language other than English. It is almost impossible to write a common easily localized function for any dialect of the human language in the world, unless you really need to keep it in common. In fact, in the real world you do not need to work with huge integers, so you can just save all the numbers in a large (or even not very large) string array.

0
source

agreed that there are a number of real-world applications. as such, a number of real-world realities already exist.

he has been part of bsdgames since forever ...

 > man number 
0
source

Source: https://habr.com/ru/post/1276336/


All Articles