print a series of numbers optimization part 1 - c++

lets say you want to make a program that will print the numbers 1-9 over and over again
123456789123456789123456789
i guess the most obvious way to do it would be to use a loop
int number = 1;
while(true)
{
print(number);
number = number + 1;
if(number > 9)
number = 1;
}
before i go any further, is this the best way to do this or is there a more common way of doing this?

Will this do?
while(true)
{
print("123456789");
}

Everyone using the % operator so far seems to be under the impression that ten values are involved. They also overlook the fact that their logic will sometimes generate 0. One way to do what you want is:
int i = 1;
while (true) {
print(i);
i = (i % 9) + 1;
}

The most obvious way would be this:
for (;;)
{
for (int i = 1; i < 10; ++i)
{
print(i);
}
}
Why you'd want to optifuscate it is beyond me. Output is going to so overwhelm the computation that any kind of optimization is irrelevant.

First off, why are you trying to "optimize" this? Are you optimizing for speed? Space? Readability or maintainability?
A "shorter" way to do this would be like so:
for (int i = 1; true; i++)
{
print(i);
i = (i + 1) % 10;
}
All I did was:
Convert the while loop to a for
loop
Convert increment +
conditional to increment + mod
operation.
This really is a case of micro-optimization.

My answer is based off Mike's answer but with further optimization:
for (int i = 1; true; i++)
{
std::cout << ('0' + i);
i = (i + 1) % 10;
}
Printing a number is way more expansive then printing a char and addition.

Related

C++ Function Gives "Not all Control Paths Return A Value" Error

I am working on a function called add(BigDecimals c) which keeps getting an error that not all control paths are returning a value:
BigDecimal BigDecimal::add(BigDecimal c)
{
string fFirst = to_string(this->fraction()); //fraction part of the first number
string fSecond = to_string(c.fraction()); //fraction part of the second number
if (fFirst.length() < fSecond.length()) //fraction part of first/second number
{
string str(this->toString()); //convert fraction to string
for (unsigned int i = 0; i < fFirst.length() - fSecond.length(); i++) //difference between first and second
{
str += "0"; //pad in the 0's
}
this->equals(str); //call the equals function
}
if (fSecond.length() < fFirst.length()) //flip numbers around, second < first
{
string str(this->toString()); //convert fraction to string
for (unsigned int i = 0; i < fSecond.length() - fFirst.length(); i++) //difference between second and first
{
str += "0"; //pad in the 0's
}
this->equals(str); //call the equals function
}
for (unsigned int i = fSecond.length(); i > 0; i++)
{
int carryFlag = 0; //carry flag set to 0
int sum = carryFlag + stoi(this->at(i).toString()) + stoi(c.at(i).toString());
if (sum >= 10) //greater than 10
{
carryFlag = 1;
sum = sum % 10;
}
else //less than 10
{
carryFlag = 0; //set carry flag to 0
}
return BigDecimal(to_string(sum)); //this is the only thing I want to
//return
}
//It wants to return something here, but I am not sure what.
}
I have tried to fix this by replacing if statements with else statements, but nothing really works. I have no idea how to fix this error, so any help is appreciated!
Your logic is flawed (and the error message and the fact you don't know what to do about it is a good indication of that).
Your code will always return on the first iteration of the loop. Clearly what you want to do is accumulate a digit string one digit at a time, but that's not what the code you've written does.
This is something more like what you want. However I think you have other errors to do with the padding of numbers, so this code isn't going to work, but hopefully will give you some idea.
string result = "";
int carryFlag = 0; //carry flag set to 0
for (unsigned int i = fSecond.length(); i > 0; i--)
{
int sum = carryFlag + stoi(this->at(i).toString()) + stoi(c.at(i).toString());
if (sum >= 10) //greater than 10
{
carryFlag = 1;
sum = sum % 10;
}
else //less than 10
{
carryFlag = 0; //set carry flag to 0
}
result = to_string(sum) + result;
}
if (carryflag)
result = "1" + result;
return BigDecimal(result);
Notice the return is only after the loop has finished, and a new variable called result accumulates the digit generated each time round the loop.
Also notice the carryflag variable has been moved outside of the loop. The whole point of the carry is to hold the carry from one iteration of the loop to the next, so it can't be inside the loop. Also if there is a carry left over after all the digits have been added, you need to add a one digit to the beginning of the result.
Also I've changed i++ to i-- in the loop. You are iterating backwards through the strings you are adding so you need i--. It's an improvment but as I said before I still think this loop is wrong.
Clearly you understand how to do long addition, but what you haven't mastered yet is how to translate that into code. You have to think very carefully and precisely about what you are asking the computer to do.

Is there any method to organize "cycling" (looping) numbers in c++?

I need to have a cycle of limited number (0 to 3) in an infinite loop. So I use this code:
int moveOp = 0;
while (1) {
//some operations with moveOp here
moveOp++;
if(moveOp>3) {
moveOp = 0;
}
}
But maybe there is a method to have a data type with which increment operator jumps to zero without hand written condition?
This would work:
moveOp = (moveOp + 1) % N;
if your NUM is power of 2 you can use the bitfields as well
struct {
unsigned moveOp:2;
}m;
m.moveOp++;
for(int i = 0; ; i = (i + 1) % 4) {
// your code goes here
}
I think Modulus operator is what you are looking for.
Following is the sample how you can use it:
int moveOp = 0;
int Num = 4;
while (1) {
++moveOp;
moveOp = moveOp%Num;
}

I need help compressing this IF statment down as much as possible in C++

I have several IF statements that I would like to compress as much as possible so that each time in the array that the number 1 appears it will add 1 to the Ones INT.
if (Dice[1] == 1)
{
Ones ++;
}
if (Dice[2] == 1)
{
Ones ++;
}
if (Dice[3] == 1)
{
Ones ++;
}
if (Dice[4] == 1)
{
Ones ++;
}
if (Dice[5] == 1)
{
Ones ++;
}
You're counting 1 values in a sequence and there's a standard library algorithm for that. It takes two iterators and I'm giving it pointers in this case.
Ones += std::count(&Dice[1], &Dice[6], 1);
This does the same thing and some people might prefer this form.
Ones += std::count(Dice + 1, Dice + 6, 1);
Like this:
for (int i = 1; i < 6; ++i) if (Dice[i] == 1) Ones++;
Or if you prefer a little less straighforward approach that saves a few characters:
for (int i = 1; i < 6; ++i) Ones += (Dice[i] == 1);
Would also seem to fit your needs.
Is this any use?
for (int i = 1; i < 6; i++)
{
if(Dice[i]==1)
Ones++;
}

Recursive function that takes the sum of odd integers

The program runs but it also spews out some other stuff and I am not too sure why. The very first output is correct but from there I am not sure what happens. Here is my code:
#include <iostream>
using namespace std;
const int MAX = 10;
int sum(int arrayNum[], int n)
{
int total = 0;
if (n <= 0)
return 0;
else
for(int i = 0; i < MAX; i ++)
{
if(arrayNum[i] % 2 != 0)
total += arrayNum[i];
}
cout << "Sum of odd integers in the array: " << total << endl;
return arrayNum[0] + sum(arrayNum+1,n-1);
}
int main()
{
int x[MAX] = {13,14,8,7,45,89,22,18,6,10};
sum(x,MAX);
system("pause");
return 0;
}
The term recursion means (in the simplest variation) solving a problem by reducing it to a simpler version of the same problem until becomes trivial. In your example...
To compute the num of the odd values in an array of n elements we have these cases:
the array is empty: the result is trivially 0
the first element is even: the result will be the sum of odd elements of the rest of the array
the first element is odd: the result will be this element added to the sum of odd elements of the rest of the array
In this problem the trivial case is computing the result for an empty array and the simpler version of the problem is working on a smaller array. It is important to understand that the simpler version must be "closer" to a trivial case for recursion to work.
Once the algorithm is clear translation to code is simple:
// Returns the sums of all odd numbers in
// the sequence of n elements pointed by p
int oddSum(int *p, int n) {
if (n == 0) {
// case 1
return 0;
} else if (p[0] % 2 == 0) {
// case 2
return oddSum(p + 1, n - 1);
} else {
// case 3
return p[0] + oddSum(p + 1, n - 1);
}
}
Recursion is a powerful tool to know and you should try to understand this example until it's 100% clear how it works. Try starting rewriting it from scratch (I'm not saying you should memorize it, just try rewriting it once you read and you think you understood the solution) and then try to solve small variations of this problem.
No amount of reading can compensate for writing code.
You are passing updated n to recursive function as argument but not using it inside.
change MAX to n in this statement
for(int i = 0; i < n; i ++)
so this doesnt really answer your question but it should help.
So, your code is not really recursive. If we run through your function
int total = 0; //Start a tally, good.
if (n <= 0)
return 0; //Check that we are not violating the array, good.
else
for(int i = 0; i < MAX; i ++)
{
if(arrayNum[i] % 2 != 0) //THIS PART IS WIERD
total += arrayNum[i];
}
And the reason it is wierd is because you are solving the problem right there. That for loop will run through the list and add all the odd numbers up anyway.
What you are doing by recursing could be to do this:
What is the sum of odd numbers in:
13,14,8,7,45,89,22,18,6,10
+
14,8,7,45,89,22,18,6
+
8,7,45,89,22,18
+
7,45,89,22 ... etc
And if so then you only need to change:
for(int i = 0; i < MAX; i ++)
to
for(int i = 0; i < n; i ++)
But otherwise you really need to rethink your approach to this problem.
It's not recursion if you use a loop.
It's also generally a good idea to separate computation and output.
int sum(int arrayNum[], int n)
{
if (n <= 0) // Base case: the sum of an empty array is 0.
return 0;
// Recursive case: If the first number is odd, add it to the sum of the rest of the array.
// Otherwise just return the sum of the rest of the array.
if(arrayNum[0] % 2 != 0)
return arrayNum[0] + sum(arrayNum + 1, n - 1);
else
return sum(arrayNum + 1, n - 1);
}
int main()
{
int x[MAX] = {13,14,8,7,45,89,22,18,6,10};
cout << sum(x,MAX);
}

Prevent the risk when using decrement/increment postfix operator in C++?

Recently I found the risk when using st like this:
int i = 10;
int sum = 0;
while ( i-- ){
sum = sum + i;
It actually get sum = 9 + 8 + 7 + .. + 1. So it lacks 10 in total. But I prefer this way of coding, it's fast and professional. Is there any advice to prevent from the risk and still have concise code?
You have a counter, a stop-condition and a decrement operation, so use a for loop - it's a much better fit than while:
int sum = 0;
for (int i = 10; i > 0; --i) {
sum += i;
}
"Professional", concise and risk-free :)
Edit: Or if you want to be really concise:
int sum = 55;
At least for this specific type of series (sum from 1..N) you can just do N*(N+1)/2. 10*11/2 = 55.
Postfix increment/decrement can be pretty nasty. I recommend not using it. Your example isn't even the worst of it. It's behaving pretty well: you're actually getting sum = 9+8+7+...+1+0; So you are going through the loop 10 times as one would think.
As mentioned in comment, use a for-loop.
int sum=0;
for (int i=10;i;--i) sum+=i;
The prefix operator is much less confusing, and in some cases, makes faster code.
Use do-while instead of while.
No idea what you mean by "risk" and "professional" way of coding, this code is just wrong. If you want it to look "similar" to what you wrote
int i = 10;
int sum = i;
while ( i-- ){
sum = sum + i;
or
int i = 10;
int sum = 0;
do {
sum += i;
} while (--i);