#include using namespace std; string ltrim(const string &); string rtrim(const string &); vector split(const string &); enum struct OutputMode { HackerRank, Linux }; OutputMode outputMode = OutputMode::Linux; map> testCases = { // test values freqs expected result // ---- ------------------ ------------ --------------- { "6", {"6 12 8 10 20 16", "5 4 3 2 1 5", "9.0"}}, }; map>::const_iterator testCase = testCases.find("6"); /* * Complete the 'interQuartile' function below. * * The function accepts following parameters: * 1. INTEGER_ARRAY values * 2. INTEGER_ARRAY freqs */ void interQuartile(vector values, vector freqs) { // Print your answer to 1 decimal place within this function cerr << "values: "; for (auto i: values) { cerr << i << " "; } cerr << endl; cerr << "freqs: "; for (auto i: freqs) { cerr << i << " "; } cerr << endl; // First, we create data set S containing the data from set values // at the respective frequencies specified by freqs vector S; for (size_t i = 0; i < freqs.size(); i++) { int freq = freqs[i]; while (freq-- > 0) S.push_back(values[i]); } sort(S.begin(), S.end()); cerr << "S: "; for (auto i: S) { cerr << i << " "; } cerr << endl; vector lower, upper; double Q1, Q3; size_t index, index1, index2; //********************************************************************* auto calcQ1Q3 =[&]() { if (lower.size() % 2 == 0) // even, average middle elements { index1 = lower.size()/2; index2 = index1 - 1; Q1 = (lower[index1] + lower[index2])/double(2); index1 = upper.size()/2; index2 = index1 - 1; Q3 = (upper[index1] + upper[index2])/double(2); } else // Q1 is lower midpoint, Q3 is upper midpoint { index = floor(lower.size()/2); Q1 = lower[index]; index = floor(upper.size()/2); Q3 = upper[index]; } }; //********************************************************************* if (S.size() % 2 == 0) // array size even, split data set in half { size_t index = S.size()/2; for (size_t i = 0; i < index; i++) lower.push_back(S[i]); for (size_t i = index; i < S.size(); i++) upper.push_back(S[i]); cerr << "lower: "; for (auto i: lower) { cerr << i << " "; } cerr << endl; cerr << "upper: "; for (auto i: upper) { cerr << i << " "; } cerr << endl; calcQ1Q3(); } //********************************************************************* else // array size odd, split data set around midpoint { size_t index = (int)floor(S.size()/2); for (size_t i = 0; i < index; i++) lower.push_back(S[i]); for (size_t i = index + 1; i < S.size(); i++) upper.push_back(S[i]); for (auto &i: lower) { cerr << i << " "; } cerr << endl; for (auto &i: upper) { cerr << i << " "; } cerr << endl; calcQ1Q3(); } double result = Q3 - Q1; cerr << "expected: " << get<2>(testCase->second) << " actual: " << fixed << setprecision(1) << result << endl; cout << fixed << setprecision(1) << result << endl; } int main() { string n_temp; if (outputMode == OutputMode::HackerRank) getline(cin, n_temp); else n_temp = testCase->first; int n = stoi(ltrim(rtrim(n_temp))); string val_temp_temp; if (outputMode == OutputMode::HackerRank) getline(cin, val_temp_temp); else val_temp_temp = get<0>(testCase->second); vector val_temp = split(rtrim(val_temp_temp)); vector val(n); for (int i = 0; i < n; i++) { int val_item = stoi(val_temp[i]); val[i] = val_item; } string freq_temp_temp; if (outputMode == OutputMode::HackerRank) getline(cin, freq_temp_temp); else freq_temp_temp = get<1>(testCase->second); vector freq_temp = split(rtrim(freq_temp_temp)); vector freq(n); for (int i = 0; i < n; i++) { int freq_item = stoi(freq_temp[i]); freq[i] = freq_item; } interQuartile(val, freq); return 0; } std::function f_isspace = [](int x){ return isspace(x); }; string ltrim(const string &str) { string s(str); s.erase( s.begin(), find_if(s.begin(), s.end(), not_fn(f_isspace)) ); return s; } string rtrim(const string &str) { string s(str); s.erase( find_if(s.rbegin(), s.rend(), not_fn(f_isspace)).base(), s.end() ); return s; } vector split(const string &str) { vector 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; }