using System;
using System.Collections.Generic;
namespace LetrasANumeros
{
class Program
{
//Diccionarios de palabras que representan valores.
static String[] unidades = { "un", "uno", "dos", "tres", "cuatro", "cinco", "seis", "siete", "ocho", "nueve" };
static String[] valoresDiez = { "once", "doce", "trece", "catorce", "quince", "dieciseis", "diecisiete", "dieciocho", "diecinueve" };
static String[] decenas = { "diez", "veinte", "veinti", "treinta", "cuarenta", "cincuenta", "sesenta", "setenta", "ochenta", "noventa" };
static String[] centenas = { "cien", "ciento", "doscientos", "trescientos", "cuatrocientos", "quinientos", "seiscientos", "setecientos", "ochocientos", "novecientos" };
//Matriz con los cuatro diccionarios
static String[][] matrizValores = { unidades, valoresDiez, decenas, centenas };
static void Main(string[] args)
{
String repetir = "";
do
{
List<String> palabras = new List<string>();
Console.Write("Teclea con letras un número entre cero y un millon: ");
String numero = Console.ReadLine().ToLower();
numero = numero.Replace(" ", ""); //Eliminamos espacios en blanco
Console.Write("\nValor: ");
Console.ForegroundColor = ConsoleColor.Yellow;
//Descartamos primero los límites
if (numero.Equals("cero"))
Console.Write(0);
else if (numero.EndsWith("millon"))
Console.Write(1000000);
else
{
/*
* Buscamos palabras de nuestros diccionarios en el String mediante método buscaPalabras()
* Este método retorna true si encuentra una palabra reconocida o false si detecta una palabra
* que no está en nuestros diccionarios de valores, en cuyo caso pondremos fin al programa.
*
* Cada palabra encontrada, se restará del String.
* Por tanto, buscaremos mientras el String aún contenga texto
* o hasta que el método de buscar palabras retorne false.
*/
bool continuar = true;
while (numero.Length > 0 && continuar)
continuar = BuscaPalabras(ref palabras, ref numero);
if (!continuar)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Hay palabras desconocidas. No se puede analizar el valor introducido.");
}
else //Hemos encontrado y reconocido todas las palabras del String
{
int valor = 0;
//Analizaremos las palabras encontradas para decidir su valor, y si se suman a la siguiente o se multiplican
foreach (String palabra in palabras)
if (palabra.Equals("mil")) //Caso especial, se multiplica por el valor actual
valor *= 1000;
else
valor += CalcularValor(palabra);
//Mostramos el valor calculado
Console.WriteLine(valor);
}
Console.ResetColor();
Console.WriteLine("\n¿Repetir?(si/no)");
repetir = Console.ReadLine().ToLower();
}
} while (!repetir.Equals("no"));
}
static bool BuscaPalabras(ref List<String> palabras, ref String numero)
{
String palabraEncontrada = null;
if (numero.StartsWith("mil")) //mil es un caso especial
{
palabraEncontrada = "mil";
}
else if (numero.StartsWith("y"))//La conjunción "y" es otro caso especial
{
palabraEncontrada = "y";
}
else
{
//Buscamos en la matriz
for (int fila = 0; fila < matrizValores.Length; fila++)
for (int col = 0; col < matrizValores[fila].Length; col++)
if (numero.StartsWith(matrizValores[fila][col]))
palabraEncontrada = matrizValores[fila][col];
}
//Comprobamos si hemos encontrado una palabra reconocida.
if (palabraEncontrada == null)
return false; //Hay palabras que no reconocemos. No seguiremos adelante.
else if (palabraEncontrada.Equals("y"))
{
//La "y" no se contabiliza en el List de palabras porque no tiene valor numérico.
//Pero no la consideramos desconocida, así que la eliminamos
//y retornaremos true
numero = numero.Substring(1);
return true;
}
else
{
//Guardamos la palabra encontrada
palabras.Add(palabraEncontrada);
//Eliminamos la palabra encontrada del String original.
int indice = palabraEncontrada.Length;
numero = numero.Substring(indice);
return true; //Seguiremos buscando más palabras
}
}
static int CalcularValor(String palabra)
{
//Buscamos posicion en la matriz de valores
int fila = 0, col = 0;
for (int f = 0; f < matrizValores.Length; f++)
for (int c = 0; c < matrizValores[f].Length; c++)
if (palabra.Equals(matrizValores[f][c]))
{
fila = f;
col = c;
}
//Segun fila y columna, decidimos el valor de esta palabra
switch (fila)
{
case 0: //Unidades
if (col == 0) //Palabra es "un"
return 1;
else
return col; // El resto de valores, su valor coincide con su posición en la columna de la matriz
case 1: //ValoresDiez
return col + 11; //Su valor equivale a su posicion en la col + 11
case 2: //Decenas
if (col == 0) //Palabra es "diez"
return 10;
else if (col <= 2) //Palabras "veinte" y "veinti"
return 20;
else
return col * 10; //Resto de valores, su valor coincide con su posición en la columna de la matriz, multiplicado por 10
case 3: //Centenas
if (col == 0) //Cien
return 100;
else
return 100 * col; //Incrementos de cien, según posicion en columna
default: //Por si fila no es un valor entre 0 y 3, caso imposible, pero compilador obliga a contemplarlo como posibilidad
return 0;
}
}
}
}