algorithm - segun - Hacer representaciones legibles por humanos de un Entero
meme y memetica (6)
Aquí hay un problema de codificación para aquellos que les gusta este tipo de cosas. Veamos sus implementaciones (en el idioma de su elección, por supuesto) de una función que devuelve una representación en cadena legible para el ser humano de un entero especificado. Por ejemplo:
- humanReadable (1) devuelve "uno".
- humanReadable (53) devuelve "fifty-three".
- humanReadable (723603) devuelve "setecientos veintitrés mil seiscientos tres".
- humanReadable (1456376562) devuelve "un billón, cuatrocientos cincuenta y seis millones, trescientos setenta y seis mil quinientos sesenta y dos".
¡Puntos de bonificación para soluciones especialmente inteligentes / elegantes!
Puede parecer un ejercicio sin sentido, pero existen varias aplicaciones del mundo real para este tipo de algoritmo (aunque admitir números tan altos como mil millones puede ser excesivo :-)
Admite hasta 999 millones, pero no tiene números negativos:
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";
}
}
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
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();
}
}
}
Hay un gran problema sobre la implementación de esta función. Es su localización futura. Esa función, escrita por un hablante nativo de inglés, probablemente no funcionaría correctamente para ningún otro idioma que no sea el inglés. Es casi imposible escribir una función general fácil de localizar para cualquier dialecto del lenguaje humano en un mundo, a menos que realmente necesite mantenerlo en general. En realidad, en el mundo real no necesita operar con números enteros enormes, por lo que puede mantener todos los números en una matriz de cadenas grande (o incluso no tan grande).
acordó que hay una serie de aplicaciones del mundo real. como tal, ya hay una serie de implementaciones del mundo real.
ha sido parte de bsdgames desde casi siempre ...
> man number
Ya había una pregunta sobre esto: convertir números enteros a números escritos
La respuesta es para C #, pero creo que puedes resolverlo.