0

I was trying to solve a simple question on a coding site. I must find how many pairs are there in an array that sumed up are divisible by a given integer k. The logic in the code below is bad, I've got 100p afterwards, but I found a strange bug in the bad code.

Here it is:

#include <bits/stdc++.h>

using namespace std;

string ltrim(const string &);
string rtrim(const string &);
vector<string> split(const string &);

int divisibleSumPairs(int n, int k, vector<int> ar) {
    int modK[k] = {0};
    for(int i = 0; i < n; ++i)
        ++modK[ar[i] % k];
    int cnt = 0;
    ///cout << modK[0] << '\n';  <- If I uncomment this, the output is 1
    cnt += modK[0] * ((modK[0]) - 1) / 2;
    
    if(k % 2 == 0)
        cnt += (modK[k / 2] * (modK[k / 2] - 1)) / 2;
    else
        for(int i = 0; i < k / 2; ++i)
            cnt += modK[i] * modK[k - i];
        
    return cnt;
}

int main()
{
    ofstream fout(getenv("OUTPUT_PATH"));

    string first_multiple_input_temp;
    getline(cin, first_multiple_input_temp);

    vector<string> first_multiple_input = split(rtrim(first_multiple_input_temp));

    int n = stoi(first_multiple_input[0]);

    int k = stoi(first_multiple_input[1]);

    string ar_temp_temp;
    getline(cin, ar_temp_temp);

    vector<string> ar_temp = split(rtrim(ar_temp_temp));

    vector<int> ar(n);

    for (int i = 0; i < n; i++) {
        int ar_item = stoi(ar_temp[i]);

        ar[i] = ar_item;
    }

    int result = divisibleSumPairs(n, k, ar);

    fout << result << "\n";

    fout.close();

    return 0;
}

string ltrim(const string &str) {
    string s(str);

    s.erase(
        s.begin(),
        find_if(s.begin(), s.end(), not1(ptr_fun<int, int>(isspace)))
    );

    return s;
}

string rtrim(const string &str) {
    string s(str);

    s.erase(
        find_if(s.rbegin(), s.rend(), not1(ptr_fun<int, int>(isspace))).base(),
        s.end()
    );

    return s;
}

vector<string> split(const string &str) {
    vector<string> tokens;

    string::size_type start = 0;
    string::size_type end = 0;

    while ((end = str.find(" ", start)) != string::npos) {
        tokens.push_back(str.substr(start, end - start));

        start = end + 1;
    }

    tokens.push_back(str.substr(start));

    return tokens;
}

If I comment out cout << modK[0] << '\n';, the ouput (in an out file, not on the screen) is 65141, If I don't it is 1. Why? This is the problem:

https://www.hackerrank.com/challenges/three-month-preparation-kit-divisible-sum-pairs/problem?h_l=interview&playlist_slugs%5B%5D=preparation-kits&playlist_slugs%5B%5D=three-month-preparation-kit&playlist_slugs%5B%5D=three-month-week-one

Ally
  • 15
  • 4
  • Please edit your question with the output from your debugging session. Which statement is causing the issue? What are the expected values of the variables and what are the actual values of the variables? – Thomas Matthews Oct 15 '21 at 18:16
  • 2
    `int modK[k]` is [not standard C++](https://stackoverflow.com/questions/1887097/) when `k` is not a compile-time constant, as in this case. Use `std::vector` instead – Remy Lebeau Oct 15 '21 at 18:17
  • IMHO, declarations should contain descriptive variable names and a header comment describing what the function does and any related variables or parameters. – Thomas Matthews Oct 15 '21 at 18:18
  • 3
    See [Why should I not #include ?](https://stackoverflow.com/q/31816095) and [Why using namespace std is bad practice](https://stackoverflow.com/questions/1452721). – prapin Oct 15 '21 at 18:18
  • 2
    *"If I comment out [a seemingly unrelated line], the [result changes]."* -- this is often indicative of undefined behavior, such as accessing an array out of bounds, say accessing element `modK[k-0]` when `modK` is an array containing `k` elements, indexed from `0` to `k-1`. (Just an example, of course.) – JaMiT Oct 15 '21 at 18:24
  • `int modK[k] = {0};` -- Your code has `vector`, but for some reason, you are not aware of what vector is used for. It is used for things like this. That is supposed to be a dynamic array, right? So that is the entire purpose of vector. Instead of the invalid C++ syntax, you should have simply used vector. – PaulMcKenzie Oct 15 '21 at 18:49

1 Answers1

2

The modK[k - i] accesses out of bounds when i is 0. This should probably be modK[k - i - 1].

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56