2009-08-24 25 views
5

Ho bisogno di aggiungere le cifre sui punti pari e dispari in un numero intero. Dì, Let number = 1234567. Somma delle cifre anche posto = 2+4+6 = 12 Somma delle cifre posto strano = 1+3+5+7 = 16Aggiunta di cifre in luoghi pari e dispari (C#)

Aspetta, non saltare per una risposta!

Sto cercando codici con linee minime, preferibilmente codici a una riga. Simile a ciò che 'chaowman' ha pubblicato nella discussione Sum of digits in C#.

Qualcuno ha dei codici interessanti. Grazie.

+2

Solo una domanda, iniziamo a contare come pari/dispari da sinistra o da destra? Questo farà la differenza se il numero ha un numero pari di cifre. – erelender

risposta

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

Ehi questo è un bel codice Grazie per il tuo lavoro Sto prendendo questo codice :-) – abhilashca

2

Non è una battuta, ma le seguenti opere:

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:

Se si desidera su una sola riga:

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: Penso che tu abbia un malinteso. OP chiede le somme di numeri in posti pari e dispari, non in cifre pari e dispari. – erelender

+0

Dannazione, Patrick, mi ci è voluto troppo tempo per rimuovere le interruzioni di riga dal tuo post e quando il mio post è salito tu avevi già modificato il tuo. :( – Imagist

+1

Mi piace il tuo humor sense one-liner Grazie. – abhilashca

0

io non so davvero C# ma qui c'è una frase che potrebbe sembrare un po 'familiare 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

Ogni programma C# potrebbe essere scritto su una singola riga del genere: P –

+0

Semplicemente rimuovendo tutte le newline non è sufficiente renderlo un one-liner ... http : //en.wikipedia.org/wiki/One-liner_program –

1

Se siete alla ricerca per l'inevitabile stupido versione trucchi LINQ, eccone 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); 

Sono sicuro che può essere trasformato in una battuta da qualcuno annoiato (e rimuovere convertendolo a una stringa come metodo per generare le cifre).

EDIT: Utilizzo Tuples per renderlo più breve (ma più confusa)

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

Se ti è piaciuto soluzione chaowmans all'altra domanda, questa sarebbe la logica estensione a pari/dispari:

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 ciclo potrebbe essere più semplice e più efficiente, anche se:

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

e non è anche rea più lungo o più complicato. Entrambe le versioni determinano la "stranezza" dalla sinistra del numero.

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]);

più 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

Questo funziona se stai partendo da destra. Almeno, funziona in C++. Non so C#, come ho detto. Spero che abbiano rimosso alcune di queste sciocchezze in C#.

Non è una battuta, ma è una dichiarazione se lo sconto della dichiarazione (che credo sia giusto):

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))))) 
; 

di credito come extra, ecco uno script Python di una sola riga che trasformerà tutto delle tue soluzioni C# in one-liner.

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

Usage:

python one_liner.py infile outfile 
1

versione di Ruben con la logica di raggruppamento modificata:

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

Bello, ma non sono un vero fan del trucco della bandiera mutante [in una delle versioni] - ogni loop sull'enumerabile si baserà sullo stato in là [e precluderà l'uso di versioni interlacciate ecc.]. Ma fino a quando stiamo cercando di fare Stupid Coding Tricks, allora è tutto bello e dandy. –

1

Ecco il mio one-lungo-liner utilizzando LINQ che (a) calcola il pari e dispari totali in una singola riga, (b) non converte il numero originale in intermedio string, e (c) non hai alcun effetto collaterale:

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 

(Il codice sopra conta il pari/dispari posizioni da sinistra a destra. Per contare da destra verso sinistra invece basta rimuovere la chiamata a Reverse. Il calcolo da L a R produce risultati diversi da R a L quando number ha un numero pari di cifre.)

+0

Si noti che non sto raccomandando questo metodo: un ciclo standard sarebbe più breve, più veloce e più facile da capire. Questo è solo il mio modo di saltare i cerchi per rispondere alla richiesta "preferibilmente una linea" nella domanda! – LukeH

0

Questo funziona senza 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]); 
Problemi correlati