Manejo de cálculo temporal en linq.

Al resolver una pregunta de entrevista

Pregunta Se debe encontrar un número de seis dígitos de tal manera cuando se multiplica por un número entero entre 2 y 9 para obtener el número original de seis dígitos cuando sus dígitos se invierten.

Ejemplo:

Supongamos que multiplico 219978 * 4 obtengo 879912, cuando reverso 879912 obtendré 219978 de vuelta.

Lo resolví usando

for (long l = 100000; l < 999999; l++) { var num = l.ToString(); for (int i = 3; i < 9; i++) { var mul = l * i; string str = mul.ToString(); char[] splitDigits = str.ToCharArray(); string reversedDigit = new string(splitDigits.Reverse().ToArray()); if (reversedDigit.CompareTo(num) == 0) { Console.WriteLine("{0} * {1}= {2}, when multiplied {3} ", num, i, mul,reversedDigit); } } } 

La tarea original era resolverlo usando linq. Tengo un poco de confusión en el manejo de los cálculos de temperatura, por ejemplo

cuando uso

  var = from l in Enumerable.Range(100000,999999) from i in Enumerable.Range(3,9) 

¿Cuál es la manera de manejar cálculos temporales como var num = l.ToString (), etc. en linq? Me confundió mucho terminarla en Linq. Se agradece la ayuda.

Quieres let

  // NOTE: buggy; see below var qry = from l in Enumerable.Range(100000, 999999) from i in Enumerable.Range(3, 9) let s = l.ToString() let t = (l * i).ToString() where s.Reverse().SequenceEqual(t) select new { l, i }; var a = qry.First(); Console.WriteLine("an answer..."); Console.WriteLine("{0} x {1} = {2}", al, ai, al * ai); Console.WriteLine("all answers..."); foreach (var row in qry) { Console.WriteLine("{0} x {1} = {2}", row.l, row.i, row.l * row.i); } 

con la primera respuesta (tenga en cuenta que la inclusión de 9 se toma de su versión original del código, pero puede ser conveniente usar Range(3,8) lugar):

 109989 x 9 = 989901 

Versión optimizada (y rango correcto):

  var qry = from l in Enumerable.Range(100000, 999999 - 100000) let s = l.ToString() let sReversed = new string(s.Reverse().ToArray()) let wanted = int.Parse(sReversed) from i in Enumerable.Range(3, 8 - 3) where l * i == wanted select new { l, i }; 

Esto reduce el número de cadenas creadas, utiliza la igualdad de enteros y utiliza correctamente el rango (el segundo parámetro de Range es el conteo , no el final).

Aquí hay otra solución que coincide con la statement del problema con algunos métodos de ayuda para mayor claridad (que podrían trasladarse a la consulta linq original):

  private static IEnumerable SixDigitNumbers = Enumerable.Range(100000, (999999 - 100000)); private static IEnumerable Multipliers = Enumerable.Range(2, 8); static void Main(string[] args) { var Solutions = from OriginalNumber in SixDigitNumbers from Multiplier in Multipliers let MultipliedNumber = (OriginalNumber * Multiplier) where MultipliedNumber < 999999 && ResultIsNumericPalindrome(OriginalNumber, Multiplier) select new { MultipliedNumber, OriginalNumber, Multiplier }; var AllSolutions = Solutions.ToList(); } private static string Reverse(string Source) { return new String(Source.Reverse().ToArray()); } private static bool ResultIsNumericPalindrome(int Original, int Multiplier) { return (Original.ToString() == Reverse((Original * Multiplier).ToString())); } 

Aquí están TODAS las soluciones:

{MultipliedNumber = 989901, OriginalNumber = 109989, Multiplicador = 9}
{MultipliedNumber = 879912, OriginalNumber = 219978, Multiplicador = 4}

Tenga cuidado con Enumerable.Range: veo que una persona que responde a esta pregunta cometió el error de excluir dos números solicitados en la statement del problema.