Simple C++ Design Question for Numerology App

Started by
13 comments, last by Xai 10 years, 7 months ago

Interesting material, thanks for sharing!

Advertisement

Finding if a number is divisible by nine has NOTHING to do with the OPs purposes.

In numerology - one of the most important "values" of a number is the sum of its digits (although there are special cases for certain numbers like 11 and 22, which are NOT usually reduced.

There is NO SUCH THING as a way to compute this without a loop or recursion. Frob's post is almost exactly what the OP needs for a primary function. But anyway, here's some code.

int SumOfDigits_SinglePass(int input)
{
  if(input > 10)
    return SumOfDigits_SinglePass(input / 10) + (input % 10);
  else
    return input;
}
 
int SumOfDigits_MultiPass(int input)
{
  int newValue = input;
  while(newValue > 10)
  {
    newValue = SumOfDigits_SinlgePass(newValue);
  }
  return newValue;
}

Obviously adding tests to stop reducing 11 and 22 if desired would be fairly easy. Another function you would want to write would be one that accepts a list (or vector) of integers and sums them into 1 integer ... this would be used to take things like 3, 13, 1998 and sum them into 1 integer, which you would them feed into the above functions. I'll leave that as an exercise to the OP so you get some fun yourself.

Finding if a number is divisible by nine has NOTHING to do with the OPs purposes.

In numerology - one of the most important "values" of a number is the sum of its digits (although there are special cases for certain numbers like 11 and 22, which are NOT usually reduced.

There is NO SUCH THING as a way to compute this without a loop or recursion. Frob's post is almost exactly what the OP needs for a primary function. But anyway, here's some code.

The theory of divisibility by nine has everything to do with why Álvaro's code works, which is a single non-iterative expression that returns the sum of all digits.


int SumOfDigits_SinglePass(int input)
{
  if(input > 10)
    return SumOfDigits_SinglePass(input / 10) + (input % 10);
  else
    return input;
}
 
int SumOfDigits_MultiPass(int input)
{
  int newValue = input;
  while(newValue > 10)
  {
    newValue = SumOfDigits_SinlgePass(newValue);
  }
  return newValue;
}

Obviously adding tests to stop reducing 11 and 22 if desired would be fairly easy. Another function you would want to write would be one that accepts a list (or vector) of integers and sums them into 1 integer ... this would be used to take things like 3, 13, 1998 and sum them into 1 integer, which you would them feed into the above functions. I'll leave that as an exercise to the OP so you get some fun yourself.

You may want to change the while-loops to >= 10 insetad to ensure that the value is reduced to a single digit; your code treats 10 as a single digit.

Thanks BrotherBob for pointing out the error in the code. Yes, that should be >= 10.

Also, I want to say I was wrong, Alvaro's post is correct, there is a constant time solution and that is it - and it works for all numbers >= 1 (make sure and trap 0 as the only special case that adds to 0).

I was erroneously thinking that an inheirantly loop-base operation cannot be condensed to constant time, but the fact is, the divide and modulous operators and not "constant time" in the simple sense. They have circuitry added for each digit of support, so the "loop-based" aspect is being played out in parallel in the modulus operator - very neat indead.

I was also erroneously thinking that that range 1-9 couldn't be correct, because there is no 0 ... but I forgot to account for the fact that it is supposed to be that way for any number >0. 9 = 9, 10 = 1, 11 = 2 ... I don't know why I lost sight of that in my argument.

Sorry for the confusion.

This topic is closed to new replies.

Advertisement