2009-08-24 15 views
5

Necesito agregar los dígitos en los lugares pares e impares en un número entero. Diga, Deje number = 1234567. incluso Suma de dígitos de las unidades = 2+4+6 = 12 Suma de los dígitos lugar extraño = 1+3+5+7 = 16Agregar dígitos en lugares pares e impares (C#)

Espere, no saltan por respuesta!

Estoy buscando códigos con líneas mínimas, preferiblemente códigos de una línea. Similar a lo que 'chaowman' ha publicado en el hilo Sum of digits in C#.

¿Alguien tiene algunos códigos geniales? Gracias.

+2

Solo una pregunta, ¿comenzamos a contar como impar/par desde la izquierda o desde la derecha? Esto marcará la diferencia si el número tiene un número par de dígitos. – erelender

Respuesta

9
bool odd = false; 

    int oddSum = 1234567.ToString().Sum(c => (odd = !odd) ? c - '0' : 0); 

    odd = false; 

    int evenSum = 1234567.ToString().Sum(c => (odd = !odd) ? 0 : c - '0'); 
+0

Hola, ese es un código genial Gracias por su trabajo Estoy tomando este código :-) – abhilashca

2

No es una sola línea, pero las siguientes obras:

int oddSum = 0, evenSum = 0; 
bool odd = true; 
while (n != 0) { 
    if (odd) 
     oddSum += n % 10; 
    else 
     evenSum += n % 10; 
    n /= 10; 
    odd = !odd; 
} 

EDIT:

Si desea que en una línea:

int oddSum = 0, evenSum = 0; bool odd = true; while (n != 0) { if (odd) oddSum += n % 10; else evenSum += n % 10; n /= 10; odd = !odd; } 
+0

@ThePower: Creo que tiene un malentendido. OP solicita las sumas de números en lugares pares e impares, no en dígitos pares e impares. – erelender

+0

Maldita sea, Patrick, me tomó demasiado tiempo eliminar los saltos de línea de tu publicación y para cuando mi publicación ya se había editado la tuya. :( – Imagist

+1

Me gusta su sentido del humor de una línea! Gracias – abhilashca

0

Realmente no sé C# pero aquí hay una línea que le puede parecer familiar a Patrick McDonald:

int oddSum = 0, evenSum = 0; bool odd = true; while (n != 0) { if (odd) oddSum += n % 10; else evenSum += n % 10; n /= 10; odd = !odd; } 
+1

Cada programa C# podría escribirse en una sola línea como la siguiente: P –

+0

Simplemente eliminar todas las líneas nuevas no lo convierte en un trazador de líneas ... http : //en.wikipedia.org/wiki/One-liner_program –

1

Si usted está buscando para la versión de LINQ trucos estúpidos inevitable, aquí está uno:

var result = 1234567 
    .ToString() 
    .Select((c, index) => new { IndexIsOdd = index % 2 == 1, ValueOfDigit = Char.GetNumericValue(c) }) 
    .GroupBy(d => d.IndexIsOdd) 
    .Select(g => new { OddColumns = g.Key, sum = g.Sum(item => item.ValueOfDigit) }); 
foreach(var r in result) 
    Console.WriteLine(r); 

Estoy seguro de que se puede mutar en una sola línea por alguien aburrido (y eliminar su conversión a una cadena como una forma de generar los dígitos).

EDIT: El uso de tuplas para que sea más corto (pero más confuso)

var result = 1234567 
    .ToString() 
    .Select((c, index) => Tuple.Create(index % 2 == 1, Char.GetNumericValue(c)) 
    .GroupBy(d=>d.Item1) 
    .Select(g => new { OddColumns = g.Key, Sum = g.Sum(item => item.Item2) }); 
foreach(var r in result) 
    Console.WriteLine(r); 
2

Si te gustó solución chaowmans a la otra pregunta, esta sería la extensión lógica incluso a/números impares:

int even = 17463.ToString().Where((c, i) => i%2==1).Sum(c => c - '0'); 
int odd = 17463.ToString().Where((c, i) => i%2==0).Sum(c => c - '0'); 

Un bucle podría ser más simple y más eficiente sin embargo:

for (odd = even = 0; n != 0; n /= 10) { 
    tmp = odd; 
    odd = even*10 + n%10; 
    even = tmp; 
} 

y tampoco es rea lly más largo o más complicado. Ambas versiones determinan la "rareza" de la izquierda del número.

0
int evenSum = 1234567.ToString().ToCharArray().Where((c, i) => (i % 2 == 0)).Sum(c => c - '0'); 
int oddSum = 1234567.ToString().ToCharArray().Where((c, i) => (i % 2 == 1)).Sum(c => c - '0'); 
0
int number = 1234567; 
int oddSum = 0; 
int evenSum = 0; 
while(number!=0) 
{ 
    if (n%2 == 0) evenSum += number % 10; 
    else oddSum += number % 10; 
    number /= 10; 
} 
2
"1234567".Where((ch, i) => i % 2 == 0).Sum(ch => ch - '0') 
0
int n = 1234567; 
int[] c = new int[2]; 
int p = 0; 
n.ToString().Select(ch => (int)ch - '0').ToList().ForEach(d => { c[p] += d; p ^= 1; }); 
Console.WriteLine("even sum = {0}, odd sum = {1}", c[0], c[1]);

más corto:

int n = 1234567, p = 0; 
int[] c = new int[2]; 
while (n > 0) { c[p] += n % 10; n /= 10; p ^= 1; }; 
Console.WriteLine("even sum = {0}, odd sum = {1}", c[p^1], c[p]);
0

Esto funciona si estás empezando desde la derecha. Al menos, funciona en C++. No sé C#, como dije. Espero que hayan eliminado algunas de estas tonterías en C#.

No es una sola línea, pero es una declaración si se descuenta la declaración (que creo que es justo):

int oddSum, evenSum; 
for(bool odd = ((oddSum = evenSum = 0) == 0); 
    n != 0; 
    odd = (!odd || (n /= 10) == n + (oddSum += (odd ? n % 10 : 0) - evenSum + (evenSum += (!odd ? n % 10 : 0))))) 
; 

de crédito Como adicional, aquí es un script en Python de una línea que va a convertir todo de sus soluciones de C# en frases únicas.

one_liner.py 
open(__import__('sys').argv[2]','w').write(open(__import__('sys').argv[1],'r').read().replace('\n','')) 

Uso:

python one_liner.py infile outfile 
1

versión de Ruben con la lógica Agrupación modificación:

bool isOdd = false; 
var sums = 1234567 
    .ToString() 
    .Select(x => Char.GetNumericValue(x)) 
    .GroupBy(x => isOdd = !isOdd) 
    .Select(x => new { IsOdd = x.Key, Sum = x.Sum() }); 

foreach (var x in sums) 
    Console.WriteLine("Sum of {0} is {1}", x.IsOdd ? "odd" : "even", x.Sum); 
+1

Bueno, pero en realidad no soy fanático del truco de bandera mutante [en ay de las versiones] - cada bucle sobre el enumerable se basará en el estado allí [e impedirá tener versiones intercaladas, etc.]. Pero mientras tratemos de hacer los trucos de codificación estúpida, entonces todo estará bien. –

1

Aquí está mi un palangrero usando LINQ que (a) calcula el par e impar totales en una sola línea, (b) no convierte el número original a un intermedio string, y (c) no tiene ningún efectos secundarios:

var totals = Enumerable.Range(0, 10) 
    .Select(x => (number/(int)Math.Pow(10, x)) % 10) 
    .Where(x => x > 0) 
    .Reverse() 
    .Select((x, i) => new { Even = x * (i % 2), Odd = x * ((i + 1) % 2) }) 
    .Aggregate((a, x) => new { Even = a.Even + x.Even, Odd = a.Odd + x.Odd }); 

Console.WriteLine(number);   // 1234567 
Console.WriteLine(totals.Even); // 12 
Console.WriteLine(totals.Odd);  // 16 

(El código anterior cuenta el impares incluso posiciones/de izquierda a derecha. Para contar de derecha a izquierda, solo elimine la llamada al Reverse. Cálculo de L a R dará resultados diferentes a R-to-L cuando number tiene un número par de dígitos.)

+0

Tenga en cuenta que no recomiendo este método: un ciclo estándar sería más corto, más rápido y más fácil de entender. ¡Esto es solo yo saltando a través de aros para responder a la solicitud de "preferiblemente una línea" en la pregunta! – LukeH

0

Esto funciona sin LINQ.

var r = new int[]{0,0}; for (int i=0; i<7; i++) r[i%2]+="1234567"[i]-48; 
System.Console.WriteLine("{0} {1}",r[0],r[1]); 
Cuestiones relacionadas