tags:

views:

763

answers:

14

I need to add the digits on the even and odd places in an integer. Say, Let number be = 1234567 Sum of even place digits = 2+4+6 = 12 Sum of odd place digits = 1+3+5+7 = 16

Wait, dont jump for an answer!

I'm looking for codes with minimal lines, preferably one-line codes. Similar to what 'chaowman' has posted in the thread (http://stackoverflow.com/questions/478968/sum-of-digits-in-c).

Does anyone has some cool codes. Thanks.

+2  A: 

It's not a one-liner, but the following works:

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:

If you want it on one line:

int oddSum = 0, evenSum = 0; bool odd = true; while (n != 0) { if (odd) oddSum += n % 10; else evenSum += n % 10; n /= 10; odd = !odd; }
Patrick McDonald
@ThePower: I think you have a misunderstanding. OP asks for the sums of numbers at even and odd places, not even and odd digits.
erelender
Damn, Patrick, it took me too long to remove the line breaks from your post and by the time my post went up you had already edited yours. :(
Imagist
I like your one-liner Humor Sense!Thanks.
abhilashca
A: 

I don't really know C# but here's a one-liner that may look a bit familiar to 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; }
Imagist
Every C# program could be written on a single line like that :P
Cecil Has a Name
Simply removing all the newlines doesn't quite make it a one-liner... http://en.wikipedia.org/wiki/One-liner_program
Banang
+9  A: 
    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' );
Ed Guiness
Hey thats a cool code.Thanks for your work.I'm taking this code.:-)
abhilashca
+1  A: 

If you're looking for the inevitable stupid LINQ tricks version, here's one:-

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

I'm sure that can be mutated into a one-liner by someone bored [and remove converting it to a string as a way of generating the digits].

Ruben Bartelink
+1  A: 

If you liked chaowmans solution to the other question, this would be the logical extension to even/odd numbers:

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

A loop might be simpler and more efficient though:

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

And it's also not really longer or more complicated. Both versions determine the "oddness" from the left of the number.

sth
A: 
 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');
Preetum Nakkiran
A: 
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;
}
Inge Henriksen
+2  A: 
"1234567".Where((ch, i) => i % 2 == 0).Sum(ch => ch - '0')
Lloyd
A: 
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]);

Shorter one:

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

This works if you're starting from the right. At least, it works in C++. I don't know C#, as I said. I kind of hope they removed some of this nonsense in C#.

It's not a one-liner, but it's one statement if you discount the declaration (which I think is fair):

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

As extra credit, here's a one-line Python script that will turn all of your C# solutions into one-liners.

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
Imagist
+1  A: 

Ruben's version with modified Grouping logic:

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);
Matajon
Nice, but I'm really not a fan of the mutating flag trick [in ay of the versions] - each loop over the enumerable will rely on the state in there [and will preclude having interleaved versions etc.]. But then as long as we're trying to do Stupid Coding Tricks, then that's all fine and dandy.
Ruben Bartelink
A: 

Here's my one-long-liner using LINQ that (a) calculates the odd and even totals in a single line, (b) doesn't convert the original number to an intermediate string, and (c) doesn't have any side-effects:

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

(The code above counts the odd/even positions from left-to-right. To count from right-to-left instead just remove the call to Reverse. Calculating from L-to-R will give different results than R-to-L when number has an even number of digits.)

LukeH
Note that I'm not recommending this method: A standard loop would be shorter, faster and easier to understand. This is just me jumping through hoops to answer the "preferably one line" request in the question!
LukeH
A: 

This works without 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]);
Sklivvz
+1  A: 

You guys are all dumbasses.

asd