Erroneous calculation method in C++ - c++

I am taking a beginners C++ course and I am struggling with an assignment right now. The assignment was:
A particular talent competition has 5 judges, each of whom awards a score between 0 and 10 to each performer. Write a program that uses these rules to calculate and display a contestant’s score. It should include the following functions:
• int getJudgeData() should ask the user for a judge’s score, store it in a reference parameter variable, and validate it. This function should be called by main once for each of the 5 judges.
• double calcScore() should calculate and return the average of the 3 scores that remain after dropping the highest and lowest scores the performer received. This function should be called just once by main and should be passed the 5 scores.
Two additional functions, described below, should be called by calcScore, which uses the returned information to determine which of the scores to drop.
• int findLowest() should find and return the lowest of the 5 scores passed to it.
• int findHighest() should find and return the highest of the 5 scores passed to it.
When testing my program it works properly if the score from judge one is the lowest but it will now work properly for any other judges being the lowest.
Ex: I will enter 2,1,5,4,3 so it should drop the 1 & 5 and come out with the avg of 3 but the result is 2.6667
the code I have for int findLowest() is:
int findLowest(int scoreOne,int scoreTwo,int scoreThree,int scoreFour,int scoreFive)
{
int lowest = scoreOne;
if ( scoreTwo < lowest )
lowest = scoreTwo;
if ( scoreThree < lowest )
lowest = scoreThree;
if ( scoreFour < lowest )
lowest = scoreFour;
if ( scoreFive < lowest )
lowest = scoreFive;
return lowest;
}
The int findHighest is similar but the less than symbols are switched obviously.
for the calcAverage() function I have:
double calcAverage(double OneScore,double twoScore,double threeScore, double fourScore,double fiveScore)
{
double lowest, highest, sum;
lowest=findLowest(OneScore,twoScore,threeScore,fourScore,fiveScore);
highest=findHighest(OneScore,twoScore,threeScore,fourScore,fiveScore);
sum = (OneScore + twoScore + threeScore + fourScore + fiveScore);
sum = sum - lowest;
sum = sum - highest;
sum = sum / 3;
cout<<"\nAfter droping highest and lowest scores\n";
cout<<"Your average score is "<<sum << endl;
return 0;
}
EDIT: I have put cout statements in the findHighest and findLowest functions to check what number it is determining is correct and each time it selects the correct highest number and for the lowest it will have 0
EDIT TWO: I have found that the program sets score one to 0 regardless of what is inputed. The program takes the correct input for the other scores.

After a quick look, the code you have should be working. Run through it again and make sure each if statement is consistent with what you want to do. If that doesn't work another way you could try is
double lowest = oneScore;
if (twoScore < lowest)
lowest = twoScore;
if(threeScore < lowest)
lowest = threeScore;
etc...
Your calcAverage() function is probably only failing because of the lowest() and hihgest() functions.
EDIT: If you have learned arrays, use it to declare an array of scores then use a for loop to iterate through, as Paul is hinting at in his comment

Related

Find the maximum score in a given array which can be found by either multiplying or adding

You are given an array A of K integers where Ai denotes page number of a book. To compute the score, you can either add or multiply the last digit of the page numbers.
You have to find the maximum score you can get. Since the score can be quite large, output the score modulo 1000000007
Note: The book contains N pages. Also, you need to follow the order in which the page numbers are given in the array. Initially, your score is 0.
Input format :
First line: Two space seperated integers N and K.
Next line: K space seperated integers denoting the page numbers.
Output format :
Output the maximum score you can get. Print it modulo 1000000007
Input Constraints:
1<=N<=10^9
1<=k<=10^9
SAMPLE INPUT:
50 3
2 35 23
SAMPLE OUTPUT:
30
Explanation
Last digit of all page numbers are: 2, 5, and 3.
Initial score = 0
We add 2 to the score which now becomes 2, multiply with 5 making the score 10, finally we multiply with 3 making the score 30 which is the maximum score.
Output 30 % (10^9+7) = 30.
I encountered the same question in an online test I gave recently.
Instead N was the no of books and K is the size of the array.Both were given as inputs.
Here is what I did:
int main() {
long long n, k;
long long m = 1000000007;
cin >> n >> k;
vector<int> arr(k, 0);
for(int i = 0; i < k; i++){
cin >> arr[i];
}
long long prod = 1;
long long sum = 0;
for(int i = 0; i < k; i++){
if(arr[k] < n){
prod = ((prod % m) * (arr[k] % 10)) % m;
sum = ((sum% m) + (arr[k] % 10)) % m;
prod = max(prod, sum);
sum = max(prod, sum);
}
}
cout << prod % m << endl;
return 0;
}
As you can see instead of handling for 1 and 2, I am checking for max value of the product and sum at every iteration and updating both the product and sum with it.
I got two test cases passed and rest gave wrong answer.Why is it so?
Here is the question link, if anyone needs to give it a try.
The Book Game Problem
The problem asks you to add OR multiply the last digit of the page numbers to make the resultant score as large as possible.
In this case, you should add when the digit is 0 or 1, and multiply otherwise.
For example,
Let the last digit sequence be
[1 0 2 5 8 1]
'score' is initialized to be 0.
add 1 (score: 1)
add 0 (score: 1)
multiply by 2 (score: 2)
multiply by 5 (score: 10)
multiply by 8 (score: 80)
add 1 (score: 81)
and before submitting the answer, you need to modulo it by 1000000007.
so,
score %= 1000000007
in your code, you are calculating the prod and the sum separately, which is not what you are asked to do. Also, you are sumbitting only the 'prod' value, while it is not always the maximum value (consider multiplying some number by 0)
And additionally, you are modulo-ing the intermediate values (prod and sum) which can lead to wrong answer. The modulo should not be used to calculate the score, but to truncate the result of the score digits.
So, my answer is,
Calculate the intermediate values and assign it to one variable named 'score' (don't separate the product and the sum), and modulo the value just before printing the output (don't modulo it every time you add or multiply)
Thanks.

Using modulus to solve coin change question

I'm looking for a different way to solve coin change problem using modulus. Most solutions refer to use of dynamic memory to solve this.
Example:
You are given coins of different denominations and a total amount of
money amount. Write a function to compute the fewest number of coins
that you need to make up that amount. If that amount of money cannot be
made up by any combination of the coins, return -1.
Input: coins = [1, 2, 5], amount = 11
Output: 3
Explanation: 11 = 5 + 5 + 1
The goal is to create a solution using modulus instead.
Here is what I've tried so far. I'm wondering if my variable should be initialized to something other than 0 or I'm updating in the wrong part of the code block.
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
int pieces = 0;
int remainder = 0;
for(int i = coins.size()-1; i = 0; i--) {
if (amount % coins[i] == 0)
{
pieces += amount/coins[i];
} else {
pieces += amount/coins[i];
remainder = amount%coins[i];
amount = remainder;
}
}
return pieces;
}
}
I'm expecting the output as above. Stuck and not sure what else to try to get this to work.
I understand what you're trying to do, but your code isn't actually going to accomplish what you think it will. Here's a breakdown of your code:
int coinChange(vector<int>& coins, int amount) {
// Minimum number of coins to sum to 'amount'
int pieces = 0;
int remainder = 0;
// Assuming 'coins' is a non-decreasing vector of ints,
// iterate over all coins, starting from the larger ones,
// ending with the smaller ones. This makes sense, as it
// will use more coins of higher value, implying less
// coins being used
for(int i = coins.size()-1; i = 0; i--) {
// If what's left of the original amount is
// a multiple of the current coin, 'coins[i]',
if (amount % coins[i] == 0)
{
// Increase the number of pieces by the number
// of current coins that would satisfy it
pieces += amount/coins[i];
// ERROR: Why are you not updating the remaining amount?
} else {
// What's left of the original amount is NOT
// a multiple of the current coin, so account
// for as much as you can, and leave the remainder
pieces += amount/coins[i];
remainder = amount%coins[i];
amount = remainder;
}
}
// ERROR: What if amount != 0? Should return -1
return pieces;
}
If you fixed the ERRORs I mentioned above, the function would work ASSUMING that all ints in coins behave as the following:
If a coin, s, is smaller than another coin, l, then l must be a multiple of s.
Every coin has to be >= 1.
Proof of 1:
If a coin, s, is smaller than another coin, l, but l is not a multiple of s, using l as one of the coins in your solution might be a bad idea. Let's consider an example, where coins = [4, 7], and amount = 8. You will iterate over coins in non-increasing order, starting with 7. 7 fits into 8, so you will say that pieces = 1, and amount = 1 remains. Now, 4 doesn't fit into amount, so you don't add it. Now the for-loop is over, amount != 0, so you fail the function. However, a working solution would have been two coins of 4, so returning pieces = 2.
Proof of 2:
If a coin, c is < 1, it can be 0 or less. If c is 0, you will divide by 0 and throw an error. Even more confusingly, if you changed your code you could add an infinite amount of coins valued 0.
If c is negative, you will divide by a negative, resulting in a negative amount, breaking your logic.

Multiple Constrain Knapsack

I'm trying to solve the following problem:
INPUT:
An array of items, each item has 3 different weights (integers), a value and the amount available of this type of item.
A maximum for each type of weight
OUTPUT:
An array that tells how many of each item to take in order to achieve the maximum value. The sum of each of the weights of every item must not exceed the maximum allowed and you may not take more of an item of what is available.
Example output: {3,0,2,1} means 3 of item1, 0 of item2, 2 of item3, and 1 of item4.
Example scenario:
In case I wasn't very clear with the explanation, imagine it's about putting food on a backpack. Each type of food has a weight, a volume, a number of calories and a value and there's a certain amount of each type of food available. The objective would be to maximize the value of the food in the backpack without exceeding a certain maximum amount of weight, volume and calories.
On this scenario the INPUT could be:
Array<Food>:
Burger (Weight 2, Volume 2, Calories 5, Value 5$, number of Burgers 3)
Pizza (Weight 3, Volume 7, Calories 6, Value 8$, number of Pizzas 2)
Hot Dog (Weight 1, Volume 1, Calories 3, Value 2$, number of Hot Dogs 6)
int MaxWeight = 10; int MaxVolume = 15; int MaxCalories = 10;
My Attempt
Since the data set is quite small (say 7 types of items and there's no more than 15 pieces of each item available), I thought of a brute force search:
Keep track of the best set found so far (Most value and doesn't
exceed any limits), call best set B
Have a recursive function R(s) which takes a set (array of how many of each item) as input, if the input is invalid, it returns. If the input is valid it first updates B (in case s better than B) and then calls R(s + p_i) for every product p_i
The idea is to first call R(s) with s = empty set (0 for every product) and every possible branch will be created while the branches that exceed the weights are ignored.
This obviously didn't work cause the amount of branches that have to be checked is huge even for only as few as 7 items
Any help is much appreciated!
You have to consider each type of weight in your DP method. I'll write the implementation in C++:
vector<Food> Array;
int memo[MAX_ITEM][MAX_WEIGHT1][MAX_WEIGHT2][MAX_WEIGHT3];
int f(int ind, int weight1, int weight2, int weight3){
if(weight1<0 || weight2<0 || weight3<0) return -INF;
if(ind == Array.size()) return 0;
int &ret= memo[ind][weight1][weight2][weight3];
if(ret>0) return ret;
int res = 0;
for(int i=0;i<=Array[ind].maxOfType;i++)
res = max(res, i * Array[ind].value + f(ind+1, weight1-i*Array[ind].weight1, weight2-i*Array[ind].weight2, weight3-i*Array[ind].weight3));
return ret = res;
}
The DP function is recursive and we use memoization to optimize it. It returns the maximum value we can get. you can call it by:
f(0,MaxWeight1, MaxWeight2, MaxWeight3);
After that we have to track and see which items leads to maximum value. The Next method will print what you want:
void printResult(int ind, int weight1, int weight2, int weight3){
if(ind == Array.size()) return;
int maxi = memo[ind][weight1][weight2][weight3];
for(int i=0;i<=Array[ind].maxOfType;i++){
int cur = i * Array[ind].value + f(ind+1, weight1-i*Array[ind].weight1, weight2-i*Array[ind].weight2, weight3-i*Array[ind].weight3);
if(cur == maxi){
cout<<i<<", ";
printResult(ind+1, weight1-i*Array[ind].weight1, weight2-i*Array[ind].weight2, weight3-i*Array[ind].weight3);
break;
}
}
}
All codes are tested and works well.

C++ array (Beginner)

I misstook arrays for vectors, Sorry (array is vektor in swedish)
I would need some help with a program I'm making. It is a assignment so I really need to understand how I do this and not just get the code :P
I need to make a array containing 10 "numbers" (I would like to make them editable when the program is running).
After I'v done this I need to make the program calculate the "average value" of all the numbers "/
Would be pretty neat if you could pick how many numbers you wanted the average value of as well, if anyone could share some knowledge in how I should to that :P
Anyways, I'v tried some code to make the vector that didn't work, I might as well add it here:
int vector[10];
and
vector[0] "number 1: ";
and so on for the input of numbers in the vector.
int sum = vector[0] + vector[1] + ...
cout << "average value is: " << sum/5;
should work for getting the average value though (right?)
I should allso add:
float average(int v[], int n)
to this thing as well, can't really se how though.
Any help/knowledge at all would be awesome! Cheers.
To pick how many numbers you wanted to average:
Native: (G++/Clang) only, not "legal" C++
cin >> num;
int vector[num];
"Correct" native (pointers):
int *vector = new int [num];
"Proper" C++:
#include <vector>
std::vector<int> v(num);
A function like following would work for computing average of an array containing n elements.
float average(int v[], int n)
{
float sum = 0;
for(int i = 0 ; i < n ; i++)
{
sum += v[i]; //sum all the numbers in the vector v
}
return sum / n;
}
You can declare your array as you have done however i do recommend you to name it something else then vector to avoid confusion. About tour issue with changing the numbers in the array you can do this by for example maning a loop going from one to 10 and then make the user enter values for all the fields.
Vektor på svenska = array på engelska (vector är något annat :))
If you want exactly 10 numbers, you can eliminate a lot of overhead by simply using an array. However, assuming you want to use a vector, you can easily find the average taking advantage of its "size" member, as such:
float average(std::vector<int> nums)
{
int sum = 0;
for (unsigned int i = 0; i < nums.size(); i++)
sum += nums[i];
return sum / nums.size();
}
Note that this does assume the sum won't be higher than 2^31-1, IE the highest number a signed integer can represent. To be safer you could use an unsigned and/or 64 bit int for sum, or some arbitrary precision library like gmp, but I'd assume that is all outside the scope of your assignment.
You must declare and array of size 10, which you have done.
Use a loop to get ten inputs from the user.
(for or while loops would do)
Use another loop to calculate the sum of all ten numbers and store it in a variable.
Divide the variable by ten.
This is what you need to do essentially. But, to make your driver program prettier, you can define the following functions:
void GetInput(int *A); //put the input loop here
You can also write any one of the given two functions:
long Sum(int * A) //put the summing loop here
double Average(int * A) //put the summing loop here AND divide the sum by ten
Since you are a beginner I feel obliged to tell you that you don't need to return an array since it isalways passed as a reference parameter. I did not bother to pass the array size as a parameter to any functions because that is fixed and known to be 10 but it will be good practice to do that.

Computing avg test scores using a while loop

Ok so, I am trying to write a program using a 'while' loop to compute the the average of a certain # of test scores. My 1st input is the amount of tests, and every input afterwards is a set of scores (so say 1st input is 5, then the next 5 inputs are 5 different test scores). I have to input all the variables at once in order to find the sum of all the test scores and then the computed average.
I am completely stuck on how to do this and don't even know where to start.
Some pseudocode
total <- 0
N <- input number of tests
i <- 1
while i <= N
data[i] <- input data
total <- total + data[i]
i <- i + 1
avg <- total / N
To get you started but not give too much away...
To do this the way I think you want to do this:
First take input for the # of tests.
Cin >> test_amt;
Okay, so now you know how many tests there are. Great! So now you should use a while loop to go through each test and take in input for the score! I would use a for loop here, but if you want to use a while loop, then sure.
counter = 0;
while(counter != test_amt-1)
{
cin >> score;
//I would use a vector to store each score.
//this way, you easily know which score matches up with which test
score = 0;
counter++;
}
I hope this can get you started. If not, just let me know and I would be glad to help more.
You can store scores in a std::vector and calculate the sum with std::accumulate.
Take all the scores in a single variable by adding them one after other and finally get the average. Below I have given a hint that will help you to use while loop. But you can use your own logic for it:
int test_amount, counter = 0, total = 0, score;
int avg;
cout<<"Enter test amount"<<endl;
cin>>test_amount;
while(counter < (test_amount-1))
{
cout<<"Enter the test score"<<endl;
cin>>score;
total=total+score;
counter++;
}
avg = total/test_amount;
If you wish to store the scores as well you may think of vector or array. As the number of 'test amount' is not fixed, you can also go for dynamic array, linked list etc. Think about other approaches, post your own code and Google is also there with all kind of help.