optimizing a non recursive algorithm of an integer sequence - c++

In an recruiting test platform , I had the following integer sequence problem that I solve it without a recursive function to avoid Stack Overflow :
Here's a short description of the problem :
We have a mark and at each stage we will move forward or backward.
In stage 0 we are in position 0 (no steps)
In stage 1 we take one step forward (+1 step) => position 1
For stage 2 we take two steps backward (-2 steps) => position -1
For stage n : the number of steps we took on the previous stage minus the number of steps we took on the the second-last stage, so on stage 3, we will have to take 3 steps backwards (-2 - 1). => position -4
etc...
The goal is to write the function int getPos(int stage) to return the position at the indicated stage.
with a pen and a paper I found this formula :
position (n) = steps (n-1) - steps (n-2) + position (n-1)
adnd here's my solution
#include <iostream>
using namespace std;
int getPos(int stage)
{
if (stage < 2)
return stage;
if (stage == 2)
return -1;
int stepNMinus1 = -2;
int stepNMinus2 = 1;
int stepN = 0;
int posNMinus1 = -1;
int Res = 0;
while (stage-- > 2)
{
stepN = stepNMinus1 - stepNMinus2;
Res = stepN + posNMinus1;
stepNMinus2 = stepNMinus1;
stepNMinus1 = stepN;
posNMinus1 = Res;
}
return Res;
}
int main()
{
cout << "Pos at stage -1 = " << getPos(-1) << endl; // -1
cout << "Pos at stage 0 = " << getPos(0) << endl; // 0
cout << "Pos at stage 1 = " << getPos(1) << endl; // 1
cout << "Pos at stage 2 = " << getPos(2) << endl; //-1
cout << "Pos at stage 3 = " << getPos(3) << endl; // -4
cout << "Pos at stage 4 = " << getPos(4) << endl; // -5
cout << "Pos at stage 5 = " << getPos(5) << endl; // -3
cout << "Pos at stage 100000 = " << getPos(100000) << endl; // -5
cout << "Pos at stage 2147483647 = " << getPos(2147483647) << endl; // 1
}
After executing the test program via the platform test, the max value of an int case timed out the process and the test platform said that my solution is not optimized enough to handle some cases.
I tried the "register" keyword but it has no effect...
I'm really curious and I want to know how to write an optimized function .Should I change the algorithm (how ?) or use some compiler tunings ?

We will write the first stages
Stage | Step | Position
0 | 0 | 0
1. | 1 |1
2 |-2 | -1
3 |-3 |-4
4 |-1 |-5
5 |2 |-3
6 |3 |0
7 |1 |1
8 |-2 |-1
We can see that in the step 6 is equal to step 0, step 1 = step 7, step 2 = step 7,...
So, for the step x the answer is step (x%6)
You can do
cout << "Pos at stage x = " << getPos((x%6)) << endl;

Related

Where does the loop break?

I'm writing an algorithm to check if a given number is a power of two. I've found a solution online. It does this by continually dividing the number by 2. The solution works, but I don't understand why?
i = 32;
// keep dividing i if it is even
while (i % 2 == 0) {
cout << i << " is the current val of i\n";
cout << i%2 << " is current i mod 2\n*****\n";
i = i / 2;
// check if n is a power of 2
if (i == 1) {
cout << n << " is a power of 2";
OUTPUT:
32 is the current val of i
0 is current i mod 2
*****
16 is the current val of i
0 is current i mod 2
*****
8 is the current val of i
0 is current i mod 2
*****
4 is the current val of i
0 is current i mod 2
*****
2 is the current val of i
0 is current i mod 2
*****
32 is a power of 2
My question: I don't understand why it's not an infinite loop. Where does the loop break? Doesn't i % 2 == 0 always evaluate to 0?
Let's assume the complete program is as follows.
#include <iostream>
using namespace std;
int main()
{
int n = 32;
int i = n;
// keep dividing i if it is even
while (i % 2 == 0) {
cout << i << " is the current val of i\n";
cout << i % 2 << " is current i mod 2\n*****\n";
i = i / 2;
}
// check if n is a power of 2
if (i == 1) {
cout << n << " is a power of 2";
}
}
In the last iteration, i becomes 2 so i == 2/2 == 1 and i % 2 == 1, which breaks while loops.

How can I print the empty spaces with " | | " until the line ends [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
I am working with vectors and I wanna know how I can print the empty spaces in between until the line ends.
void print_vector(const std::vector < int > & v, int print_cols, int col_width) {
//dash
cout << string(print_cols * (col_width + 2) + 1, '-');
cout << endl;
//printing the vector in formated output
cout << "|";
for (size_t x = 0; x < v.size(); x++) {
cout << right << setw(col_width) << v[x] << " |";
//prints new line if it reaches limit of numbers per line
if ((x + 1) % print_cols == 0) cout << endl << "|";
}
//dash
cout << endl << string(print_cols * (col_width + 2) + 1, '-');
cout << endl;
}
this is my current output: my output so far and sorry I can't embed images yet it wont let me.
But this is the output that I want output needed
void print_vector(const std::vector < int > & v, int print_cols, int col_width) {
//dash
cout << string(print_cols * (col_width + 2) + 1, '-');
cout << endl;
//printing the vector in formated output
cout << "|";
size_t x = 0;
for (x = 0; x < v.size(); x++) {
cout << right << setw(col_width) << v[x] << " |";
//prints new line if it reaches limit of numbers per line
if (x < v.size() - 1) {
if ((x + 1) % print_cols == 0) {
cout << endl << "|";
}
}
}
size_t remain = print_cols - (x % print_cols);
for (size_t i = 0; (remain != print_cols) && i < remain; ++i) {
cout << right << setw(col_width) << " " << " |";
}
//dash
cout << endl << string(print_cols * (col_width + 2) + 1, '-');
cout << endl;
}
Sample outputs:
-------------------------------------------------
| 1 | 2 | 3 | 4 |
| 5 | 6 | 7 | 8 |
| 9 | | | |
-------------------------------------------------
-------------------------------------
| 1 | 2 | 3 |
| 4 | 5 | 6 |
| 7 | 8 | 9 |
-------------------------------------
You can add an extra loop after the one you have and before the bottom row of dashes:
The loop would print a given number of blank columns.
The number of blank columns can be computed as print_cols - v.size() % print_cols.
The loop should not be executed if the number of blank columns is equal to the total number of columns. That would print a full row of empty columns. That case happens when the vector you want to print has a number of elements that is an exact multiple of the number of columns.
Every iteration of the loop should print col_width + 1 blanks and a '|' (or if you prefer it, to make it more consistent with your other code, col_width blanks plus a " |").
Yet you should fix another issue with your code:
The check for reaching the end of the row (enabling the print of a new line and a '|') should be instead a check for starting a row.
 
If you do it at the end, for the case when the last element of the vector goes in the last column, you will unnecessarily add a new row.
 
Doing it at the beginning, since you know you have at least one more number to show, you can print "\n|" and then the number.
 
The check x % print_cols == 0 will tell you if x is the index of the first element of a row.
[Demo]
#include <iomanip> // setw
#include <iostream> // cout
#include <numeric> // iota
#include <string>
#include <vector>
void print_vector(const std::vector<int>& v, int print_cols, int col_width) {
// dash
std::cout << std::string(print_cols * (col_width + 2) + 1, '-');
// printing the vector in formated output
for (size_t x = 0; x < v.size(); x++) {
// prints new line if it is the first element of the line
if (x % print_cols == 0) {
std::cout << "\n|";
}
std::cout << std::right << std::setw(col_width) << v[x] << " |";
}
// prints last empty columns
if (int number_of_blank_columns = print_cols - v.size() % print_cols;
number_of_blank_columns != print_cols) {
for (int x = 0; x < number_of_blank_columns; x++) {
std::cout << std::string(col_width + 1, ' ') << "|";
}
}
// dash
std::cout << "\n" << std::string(print_cols * (col_width + 2) + 1, '-') << "\n";
}
int main() {
{
std::vector<int> v(8);
std::iota(std::begin(v), std::end(v), 100);
print_vector(v, 5, 4);
}
std::cout << "\n";
{
std::vector<int> v(10);
std::iota(std::begin(v), std::end(v), 100);
print_vector(v, 5, 4);
}
}
// Outputs:
//
// -------------------------------
// | 100 | 101 | 102 | 103 | 104 |
// | 105 | 106 | 107 | | |
// -------------------------------
//
// -------------------------------
// | 100 | 101 | 102 | 103 | 104 |
// | 105 | 106 | 107 | 108 | 109 |
// -------------------------------

Function: smallest positive integer

#include <iostream>
using namespace std;
int enough(int goal)
{
int C { };
int i { };
if (goal > 1)
{
while (((C += i) <= goal) && ((goal - i) <= (i + 1)))
{
i += 1;
}
}
else
{
i = 1;
}
return i;
}
int main()
{
cout << enough(21);
return 0;
}
So the purpose of this function is for it to return the smallest positive integer that can be summed consecutively from 1 before the cumulative sum becomes greater than the parameter "goal".
So, for example:
cout << enough(9) << endl;
will print 4 because 1+2+3+4 > 9 but 1+2+3<9
cout << enough(21) << endl;
will print 6 'cause 1+2+ . . .+6 > 21 but 1+2+ . . . 5<21
cout << enough(-7) << endl;
will print 1 because 1 > -7 and 1 is the smallest positive integer
cout << enough(1) << endl;
will print 1 because 1 = 1 and 1 is the smallest positive integer
My logic at first was using just while ((C += i) <= goal), but that went wrong, for example, for the parameter 21, where you get C = 20, which passes the test and ends up in i being augmented by 1 (resulting in the return value i = 7, which is clearly wrong).
Therefore I decided to create a test which tested both C and i, but that went wrong because the code isn't considering goal - i and i + 1 as separate tests for the while circuit, but I believe it is actually altering the value of ints goal and i, which screws everything up.
Any ideas where I went wrong?
Your approach is unnecessarily verbose. There is a closed-form (i.e. O(1)) solution for this.
The sum S of the arithmetic progression 1, 2, ..., n is
S = n * (n + 1) / 2
Rearranging this (completing the square), rejecting the spurious root, and rounding appropriately to fit the requirements of the question yields the result
n = std::ceil((-1 + std::sqrt(1 + 8 * S)) / 2)
This will not work for negative n, and possibly 0 too depending on the specific (and unspecified) requirements.
Or if you must use an O(N) approach, then
int enough(int goal){
int i = 0;
for (int total = 0; (total += ++i, total) < goal; );
return i;
}
will do it, which returns 1 for goal <= 1.
You could perhaps try to simplify your original O(N) approach by only having one condition in your while-loop, i.e., no &&:
#include <iostream>
using namespace std;
int enough(int goal)
{
if (goal <= 0)
{
return 1;
}
int total{};
int i{};
while (total < goal)
{
total += ++i;
}
return i;
}
int main()
{
cout << "enough(9): " << enough(9) << endl;
cout << "enough(21): " << enough(21) << endl;
cout << "enough(-7): " << enough(-7) << endl;
cout << "enough(1): " << enough(1) << endl;
cout << "enough(0): " << enough(0) << endl;
return 0;
}
Output:
enough(9): 4
enough(21): 6
enough(-7): 1
enough(1): 1
enough(0): 1

C++ EVP_EncriptUpdate rewriting stack?

I have this code
.....
const EVP_CIPHER * cipher = EVP_des_ecb();
uint8_t ot_byte,st_byte;
EVP_CIPHER_CTX ctx;
int trash;
EVP_EncryptInit(&ctx,cipher, key, iv);
cout << size - offset << endl;
int i=0;
for (; i < size - offset ;i++){
check = read(input_fd,&ot_byte,1);
cout << (i < size - offset) << " " << i << endl;
EVP_EncryptUpdate(&ctx, &st_byte, &trash, &ot_byte, 1);
check = write(output_fd,&st_byte,1);
}
cout << (i < size - offset) << " " << i << endl;
close(output_fd);
close(output_fd);
the output is
702000
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7
0 5019693
When I "comment off" the EVP update function, the loop goes through all 702000 iterations. Where is the mistake? Is there a possibility, that EVP somehow goes behind its buffer and corrupts stack data?
uint8_t type will be small, these functions return at least 8 bytes

I need to write a C++ program that shows the sum of 1 to n for every n from 1 to 50

I used the below code, but my numbers are incorrect & my instructor would rather I use a for loop. It also needs to print out:
The sum of "n" through "n" is " " (The sum of 1 through 1 is 1)
The sum of "n" through "n" is " " (The sum of 1 through 2 is 3)
I've tried using for loops, but can't seem to get the code right to print out the above. I'm lost!
#include "stdafx.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
const int NUM_LOOPS = 50;
int count = 0;
while (count < NUM_LOOPS)
{
cout << "Sum of 1 through " << count << " is " << (count * (++count)) / 2 << endl;
}
system("pause.exe");
return 0;
}
With a for loop it looks like this:
for (int i = 1; i <= NUM_LOOPS; i++)
{
cout << "Sum of 1 through " << i << " is " << i*(i+1)/2 << endl;
}
You could write it in a while loop just as easily if you wished.
Your problem was that you were initialising count to 0 rather than 1. Presumably to deal with the fact that you modified count in the middle of the long cout. The evaluation of the << operators are unsequenced relative to each other and your code exhibits undefined behaviour, as has been discussed here so many times before.
The bottom line with this is that the pre and post increment operators are dangerous in anything beyond the most simple expressions. Use the sparingly.
for (int count = 1; count <= NUM_LOOPS; ++count)
{
cout << "Sum of 1 through " << count << " is "
<< (count * (count+1)) / 2 << endl;
}
Don't do mix funny increments with mathematical formulas. Your future life will be happier.
I don't think it's a good way to calculate every summary. You just need to maintain one summary currently, and each time just add new value
Since multiple operation will cost more time than a single add.
const int NUM_LOOPS = 50;
int count = 0, sum = 0;
while ( count < NUM_LOOPS )
cout << "Sum of 1 through " << count << " is " << (sum+=(++count)) << endl;
My example is from 1 to 10
int sum=0;
for (int i = 1; i < 11; i++) {
for (int j = 1; j <= i; j++) {
cout << j;
sum=sum+j;
if(j != i){
cout << " + ";
}
}
cout << " = " << sum;
sum=0;
cout <<"\n";
}
Output is:
1 = 1
1 + 2 = 3
1 + 2 + 3 = 6
1 + 2 + 3 + 4 = 10
1 + 2 + 3 + 4 + 5 = 15
1 + 2 + 3 + 4 + 5 + 6 = 21
1 + 2 + 3 + 4 + 5 + 6 + 7 = 28
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 = 36
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 = 45
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 = 55