-1

I was trying to solve this problem on hackerrank.

You are given four integers: N,S,P,Q. You will use them in order to create the sequence with the following pseudo-code.

a[0] = S (modulo 2^31)
for i = 1 to N-1
a[i] = a[i-1]*P+Q (modulo 2^31) 

Your task is to calculate the number of distinct integers in the sequence .

Sample Input

3 1 1 1 
Sample Output

3

Constraints

1<= N <= 10^8
0<= S,P,Q < 2^31

And this was my solution in c++.. Most of the times I was getting segmentation faults.. I know this was supposed to be solved using bit arrays.. but wanted to know why this wasnt working.

#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;


int main() {
unsigned long long n,s,p,q;

cin >> n >> s >> p >> q;

//declaring array to hold sequence
unsigned long long a[n];

// for loop termination
bool termination_check = true;

//initializing sequence
//s<2^31 hence, s modulo 2^31 is always s
a[0] = s;

//creating sequence
for(int i=1;i<n;i++){

    //calculating next term of sequence..
    a[i] = (a[i-1]*p)+q;

    //since a[i] modulo 2^31 is a[i] when a[i] < 2^31
    if(a[i]>=pow(2,31)){
       a[i] = a[i]%31;

        //when the current term matches with any of previous terms of sequence, then the
        //terms just repeat after that (since p and q are constants)
        for(int j=0;j<i;j++){
            if(a[i]==a[j]){
                cout <<i << endl;

                //i was trying to use break but dont know why, it did not work
                termination_check = false;
                break;
                break;
            }
        }
    }
}

//if there was no termination of loop then all the terms are distinct
if(termination_check){
printf("%llu \n", n);
}

/* Enter your code here. Read input from STDIN. Print output to STDOUT */   
return 0;
}
manji369
  • 136
  • 2
  • 13

2 Answers2

0

This answer was for the previous version of code. The code has now been edited inside the question(j = i and i = n replaced by two breaks)

See what happends when you encounter the case

a[i] == a[j]

you set j to i, then i to n. But i is smaller than n, so the statement j<i remains true. Your for loop then keeps runing, so your programm tries to evaluates

a[i] == a[j]

with the new values you assigned, you are actually asking if

a[n] == a[i]

but if your array a was an array of size n, this leads to an undefined behaviour.

Irminsul
  • 73
  • 9
  • Thank u. But now I tried placing i = n out of the for loop with j. Same segmentation fault shows up for most of the test cases. – manji369 Jun 27 '16 at 14:57
  • I don't see why.. Did you try with a debugger ? And why do you abstain from using a break in your for loop, and even better creating a Bool method, returning False when you encounter the case which interests you, and returning True otherwise ? – Irminsul Jun 27 '16 at 15:44
  • As i have mentioned in the comment I tried using break.. but didn't work so I tried this. Nevertheless, I have a feeling that the problem is with size of unsigned long long array especially when the array size is larger. Wanted to know what exactly it was. – manji369 Jun 27 '16 at 16:08
  • 1
    This is not a "memory leak". The code accesses the array past its end, which leads to undefined behavior. A memory leak is found when some memory was not reclaimed (and so is wasted), but in such case the behavior is still defined. – chi Jun 27 '16 at 17:11
  • As I said.. I also tried using break.. but still got the same segmentation fault. Anyways I have now edited the code in question with two breaks. So no confusion – manji369 Jun 28 '16 at 06:45
0

Yes, you can have unsigned long long arrays in C++. But what you have isn't an array: unsigned long long a[n]; requires n to be a constant. (This would be different in C, but you're writing C++).

That it still runs is a compiler extension which lets you mix C and C++, but the behavior isn't defined. Error handling in particular seems to be lacking.

MSalters
  • 159,923
  • 8
  • 140
  • 320
  • If it is not an array, what is it ? – Irminsul Jun 28 '16 at 07:20
  • Ok.. now i get it.. "This isn't C." By saying its not an array, he means we cant use variable Length Arrays http://stackoverflow.com/questions/5368531/why-cant-i-create-an-array-of-size-n – manji369 Jun 28 '16 at 07:45
  • Well, the term "Variable Length Arrays" has no well-defined meaning in C++. There's `std::vector` which does have a variable length , and it's laid out as an array, but it not the same as a VLA in C. – MSalters Jun 28 '16 at 09:00
  • Wow I did not even notice that the length of the array was depending on the user input. Got it – Irminsul Jun 28 '16 at 10:21