hacker rank Mini-Max Sum - c++

this problem
I normally erase the default code and start solving the whole thing myself. However, hackerrank test cases show a different output than the one that appears to me whenever i run against custom input. Why does it show different number?
Keep in mind I have tried different input sizes as float, long long int, int, and double;
#include <bits/stdc++.h>
using namespace std;
int main() {
long long int arr[5], neglect = 0, min = 9999999999999, max = 0, curr = 0;
for (int i = 0; i < 5; i++) {
cin >> arr[i];
}
while (neglect < 5) {
for (int i = 0; i < 5; i++) {
if (i == neglect) {i++;}
curr += arr[i];
}
if (curr < min) {min = curr;}
if (curr > max) {max = curr;}
//cout << curr << endl;
//cout << curr << " " << min << " " << max << endl;
curr = 0;
neglect++;
}
cout << min << " " << max;
}
All i wanted was to solve it in a way that tries all combinations then shows the least and maximum values. I know my code isn't the optimal way to solve it, I know i could just sort the array and exclude first and last elements, but please bear with me.
input: 1 2 3 4 5
claimed output: 11 4198826
but when i debugged it with the same custom input and the commented lines it showed:
14 14 14
13 13 14
12 12 14
11 11 14
10 10 14
10 14
Doesn't that mean that my code should be working?

When you are neglecting the last element you are doing an i++ and this will add the arr[5] to the curr value, but arr[5] is out of bound of the array, thus it can give segfault or unexpected result.
I would suggest that you should not increment the i in the for loop, instead you can use continue when you want to neglect the element.
for (int i = 0; i < 5; i++) {
if (i == neglect) {
continue;
}
curr += arr[i];
}
Also, you can replace the outer for loop with while loop so that you don't have to increment the neglect manually.

Related

Can't change a vector's element value at index i

In Stroustrup's Programming: Principles and Practice Using C++, chapter 4, exercise 13, I have to write a program to find all the prime numbers in a given range using the Sieve of Erathostenes.
So far, I have come up with this:
vector<int> values;
void initialize_values()
{
for (int i{0}; i < 100; ++i)
values.push_back(1);
}
void remove_composites(vector<int> values)
{
for(int i{2}; i * i < values.size(); ++i)
{
if (values[i] == 1)
{
for (int p{i + i}; p < values.size(); p += i)
values[p] = 0; //not working
}
}
}
int main()
{
initialize_values();
remove_composites(values);
for (int i{2}; i < values.size(); ++i)
{
if (values[i] == 1)
cout << i << " ";
}
cout << '\n';
return 0;
}
I create a vector with size 100 (in this first case) and initialize elements to 1. Then I check all indexes multiples of i while i * i < 100 and change the value at those indexes to 0 and finally print the indexes whose value is 1.
The problem is that values[p] = 0 is not assigning the value 0 to the element at index p and I don't really understad why.
EDIT So after reading comments and answers I decided to move all code under main(), because I don't know how to use references.
The goal of this exercises, according to the book, is to get used to processing user input, working with loops, iterations, etc. It's not intended to be professional nor expert at this point.
To all people with many years coding and answering questions here, remember you were once learners and beginners. Have some respect and don't turn this community into a toxic one.
Updated code:
int main()
{
vector<int> values;
for (int i{0}; i < 100; ++i)
values.push_back(1);
for(int i{2}; i * i < values.size(); ++i)
{
if (values[i] == 1)
{
for (int p{i + i}; p < values.size(); p += i)
{
//cout << p << " ";
values[p] = 0;
}
//cout << '\n';
}
}
for (int i{2}; i < values.size(); ++i)
{
if (values[i] == 1)
cout << i << " ";
}
cout << '\n';
return 0;
}
And works as expected:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Thanks everyone.
The problem is that values[p] = 0 is not assigning the value 0 to the element at index p
It is assigning it.
The problem is that you are operating on a copy of the original vector, and that copy is local to remove_composites, which is why the calling code doesn’t see the changes.
Change your function signature to use a reference type parameter: std::vector<int>&.
There are also some other issues with your code (using the wrong type, i.e. int instead of bool; inconsistent signatures; mutable global variables).

C++ position in index removal of hard coded list of numbers

I have a pretty simple question. My goal for this short program is for it to display the set of numbers(which is hard coded), then have the user specify which index a number of the array should be deleted from. It then outputs the new array. This program works but has one major error. When I run it and choose position 2 for example, which should delete 45, instead deletes 34. The program outputs :
12
45
2
8
10
16
180
182
22
instead of :
12
34
2
8
10
16
180
182
22
notice that the number position I want removed instead removes in the position before the number I actually want removed, if you remember that lists start at 0. Thank you!
//This program demos basic arrays
#include <iostream>
using namespace std;
const int CAP = 10;
int main()
{
//read index from user, delete number in position of index they specify.
//when printing the list, number should be gone.
int size;
int list[CAP] = { 12, 34, 45, 2, 8, 10, 16, 180, 182, 22 };
size = 10;
int i, delIndex;
cout << "Your list is: " << endl;
for (i = 0; i < CAP; i++)
{
cout << list[i] << endl;
}
cout << "\nPlease enter index to delete from: ";
cin >> delIndex;
for (i = delIndex; i <= 10; i++)
{
list[i - 1] = list[i];
}
cout << "The index position you specified has been deleted." << endl;
cout << "The new array is: " << endl;
for (i = 0; i < (size - 1); i++)
{
cout << list[i] << endl;
}
return 0;
}
Replace this:
for (i = delIndex; i <= 10; i++)
{
list[i - 1] = list[i];
}
with that:
for (i = delIndex; i < size-1; i++)
{
list[i] = list[i+1];
}
Since you are with C++, why not just using a std vector?
#include <vector>
// Initialize
int vv[10] = { 12, 34, 45, 2, 8, 10, 16, 180, 182, 22 };
std::vector<int> myvector(&vv[0], &vv[0]+10);
There are other easier ways to initialize the vector depending on the compiler. See how to initialize a vector.
Then you can just use the erase method of the vector (here I assume the user knows the indexing starts with 0, otherwise you can just put delIndex-1):
myvector.erase (myvector.begin()+delIndex);
You can easily iterate over the vector to show its contents (there are easier ways of doing this depending on the compiler, use the auto keyword).
for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it)
std::cout << ' ' << *it;

I tried coding my own simple moving average in C++

I want a function that works.
I believe my logic is correct, thus my (vector out of range error) must be coming from the lack of familiarity and using the code correctly.
I do know that there is long code out there for this fairly simple algorithm.
Please help if you can.
Basically, I take the length as the "moving" window as it loops through j to the end of the size of the vector. This vector is filled with stock prices.
If the length equaled 2 for a 2 day moving average for numbers 1 2 3 4. I should be able to output 1.5, 2.5, and 3.5. However, I get an out of range error.
The logic is shown in the code. If an expert could help me with this simple moving average function that I am trying to create that would be great! Thanks.
void Analysis::SMA()
{
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
double a;
while (length >= 2){
vector<double>::iterator it;
for (int j = 0; j < close.size(); j++){
sum = vector1[length + j - 1] + vector1[length + j - 2];
a = sum / length;
vector2.push_back(a);
vector<double>::iterator g;
for (g = vector2.begin(); g != vector2.end(); ++g){
cout << "Your SMA: " << *g;
}
}
}
}
You don't need 3 loops to calculate a moving average over an array of data, you only need 1. You iterate over the array and keep track of the sum of the last n items, and then just adjust it for each new value, adding one value and removing one each time.
For example suppose you have a data set:
4 8 1 6 9
and you want to calculate a moving average with a window size of 3, then you keep a running total like this:
iteration add subtract running-total output average
0 4 - 4 - (not enough values yet)
1 8 - 12 -
2 1 - 13 13 / 3
3 6 4 15 15 / 3
4 9 8 16 16 / 3
Notice that we add each time, we start subtracting at iteration 3 (for a window size of 3) and start outputting the average at iteration 2 (window size minus 1).
So the code will be something like this:
double runningTotal = 0.0;
int windowSize = 3;
for(int i = 0; i < length; i++)
{
runningTotal += array[i]; // add
if(i >= windowSize)
runningTotal -= array[i - windowSize]; // subtract
if(i >= (windowSize - 1)) // output moving average
cout << "Your SMA: " << runningTotal / (double)windowSize;
}
You can adapt this to use your vector data structure.
Within your outermost while loop you never change length so your function will run forever.
Then, notice that if length is two and closes.size() is four, length + j - 1 will be 5, so my psychic debugging skills tell me your vector1 is too short and you index off the end.
This question has been answered but I thought I'd post complete code for people in the future seeking information.
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<double> vector1 { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
double length;
cout << "Enter number days for your Simple Moving Average:" << endl;
cin >> length;
double sum = 0;
int cnt = 0;
for (int i = 0; i < vector1.size(); i++) {
sum += vector1[i];
cnt++;
if (cnt >= length) {
cout << "Your SMA: " << (sum / (double) length) << endl;
sum -= vector1[cnt - length];
}
}
return 0;
}
This is slightly different than the answer. A 'cnt' variable in introduced to avoid an additional if statement.

Using char arrays to add together large numbers

I have an assignment in which I am supposed to
1.) Read in 2 char arrays of numbers
2.) add together the arrays, performing carry addition, carrying the tens place
3.) print out the newly added array.
I am also supposed to print an error if I need to carry on the last digit of the array (overflow)
so something like 99999999999999999999 +
1 =
________________________
ERROR
That's the part I'm having trouble with.
The above outputs something like "99999999999999999:0" so I have no idea what's going wrong.
I'll post my code, but please be nice :( I know it certainly isn't the most efficient, but I'm just trying to lay things out in a way that is easy for my brain to understand right now.
And yes, I HAVE to use char arrays. I guess it's to help us understand the ascii table.
#include <iostream>
using namespace std;
void InitNumber(char[]);
int AddArrays(char first[], char second[], char combined[]);
void OutputNumber (char[]);
const int LENGTH = 20; // global variable
int main()
{
char set1[LENGTH];
char set2[LENGTH];
char sum[LENGTH];
InitNumber (set1);
InitNumber (set2);
if(AddArrays (set1, set2, sum)) {
cout << "overflow!" << endl;
}
OutputNumber(sum);
}
void InitNumber (char list[])
{
int numberOfDigits;
cout << "Please enter the number of digits in the number: ";
cin >> numberOfDigits;
cout << "Please enter the digits in the number with the LEAST significant first: ";
for (int i = 0; i < numberOfDigits; i++) {
cin >> list [i];
}
for (int l=(numberOfDigits); l < LENGTH; l++) {
list [l] = '0';
}
}
int AddArrays(char first[], char second[], char combined[])
{
for (int h = 0; h < LENGTH; h++)
combined[h]= '0';
int overflow = 0;
for (int i = 0; i < LENGTH; i++) {
int currentSum = (first[i]-'0' + second[i]-'0');
cout << "currentSum = " << currentSum << endl;
if(currentSum / 10 == 0 )
combined[i] += currentSum;
else if (currentSum/10 !=0) {
if (i == LENGTH-1 && currentSum/10 !=0){
overflow = 1;
}
else{
combined [i] += currentSum%10;
cout << "current i: " << combined[i] << endl;
combined [i+1] += currentSum/10;
cout << "current i+1: " << combined[i+1] << endl;
}
}
}
return overflow;
}
void OutputNumber(char arrayOut[])
{
for (int l=LENGTH - 1; l >= 0; l--)
cout << arrayOut[l];
}
working input
input
6
1 2 3 4 5 6
7
1 2 3 4 5 6 7
output
00000000000008308642
Not-working output
input
20
9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9
1
1
output
999999999999999999:0
I'm going to reproduce small parts of your inner loop where you are carrying out the addition, in order to explain why your overflow detection is broken.
for (int i = 0; i < LENGTH; i++) {
int currentSum = (first[i]-'0' + second[i]-'0');
if(currentSum / 10 == 0 )
combined[i] += currentSum;
Here you're adding the corresponding pair of digits from the two numbers you're adding, and checking (in your particular style) if they overflowed. Try to remember this part, it's important. In order to check for overflow, you're only checking the result of adding the pair of digits from the two large numbers you're adding.
else if (currentSum/10 !=0) {
This is a completely useless check. You can only get here if the division is known to produce a non-zero result. This if() can be removed completely. Now, the relevant part of your code is
combined [i] += currentSum%10;
combined [i+1] += currentSum/10;
Do you see the problem yet?
Your approach is, once overflow is detected, is to increment the next higher order digit in the result.
Unfortunately, on the next loop iteration, in order to check for carry over, you're just checking the sum of the next corresponding digit pair, from the two large numbers you're adding. The carry-over you're saving here is going to get completely ignored.
Say your numbers are two digits long max, rather than 20, and you entered the numbers 99 and 1.
On the first iteration, you'll add 9 and 1, save 0 as the first digit, and add 1 to the second digit in the sum.
On the second iteration, you'll add 9 and 0, and, given your logic above, conclude that nothing overflowed.

Vector giving inaccurate output

vector<int> vect;
vector<int> sorted;
vect.push_back(5);
vect.push_back(3);
vect.push_back(7);
vect.push_back(2);
vect.push_back(9);
vect.push_back(6);
//Print vector elements
for (int x=0; x<vect.size(); x++)
cout << vect[x] << endl;
int min = 99999, idx=0;
while (vect.size() > 0)
{
for (int x=0; x<vect.size(); x++)
{
if (vect[x] < min)
{
min = vect[x];
idx = x;
}
}
cout << "Min index: " << idx << endl;
sorted.push_back(vect[idx]);
vect.erase(vect.begin()+idx);
}
for (int x=0; x<sorted.size(); x++)
cout << sorted[x] << endl;
I wanted to sort the vector of integers by storing the sorted numbers into vector<int> sorted. But the program always got terminated half way after hitting some unknown program error.
The only output I get is:
5
3
7
2
9
6
Min Index: 3
Min Index: 3
Min Index: 3
Min Index: 3
<Program Terminated At This Point>
I've been working on this for hours and I don't know why I always get index 3 as the smallest number. What have I done incorrectly in my implementation?
I have been thinking on it for hours, and my logic seems correct?
On your first pass, it finds out min is 2.
It then erases 2, which is at index 3.
Then it goes through again, except nothing is smaller than 2.
So it still has index 3, and erases it.
This continues until you no longer have more than 3 items.
Then it fails, because the vector is too small to erase index 3.
Reset your min back to 99999 before your for loop.
As what user Blastfurnace had pointed out. I forgot to reset the Min.
This should solve it.
int idx=0;
while (vect.size() > 0)
{
int min = 99999;
for (int x=0; x<vect.size(); x++)
{
if (vect[x] < min)
{
min = vect[x];
idx = x;
}
}
cout << "Min index: " << idx << endl;
sorted.push_back(vect[idx]);
vect.erase(vect.begin()+idx);
}