1
\$\begingroup\$

Question from Skiena's Programming Challenges. Getting WA (wrong answer) in Online Judge even though it's working for sample test cases. Can somebody find a case where it fails?

I tried the tricky case from this link and it gave the right answer-

"The Trip" challenge from Programming Challenges

Input

Standard input will contain the information for several trips. Each trip consists of a line containing a positive integer n denoting the number of students on the trip. This is followed by n lines of input, each containing the amount spent by a student in dollars and cents. There are no more than 1000 students and no student spent more than $10,000.00. A single line containing 0 follows the information for the last trip.

Output

For each trip, output a line stating the total amount of money, in dollars and cents, that must be exchanged to equalize the students’ costs.

Sample Input
3
10.00
20.00
30.00
4
15.00
15.01
3.00
3.01
0

Sample Output
$10.00
$11.99

#include <iostream>
#include <vector>
#include <sstream>
using namespace std;

int main()
{   vector <float> nums;
    int numStudents,loopVar1,pos;
    float amount,sum=0,roundAmt,ans;
    string strAns;
    stringstream ss;
    while(cin>>numStudents) {
        if(numStudents==0)
            break;
        ans=sum=0;
        nums.erase(nums.begin(),nums.end());
        for(loopVar1=0;loopVar1<numStudents;loopVar1++) {
            cin>>amount;
            nums.push_back(amount);
            sum+=amount;
        }
        sum/=numStudents;
        roundAmt=(int)(sum*100);
        roundAmt/=100.0f;
        //cout<<roundAmt<<"\n";
        for(loopVar1=0;loopVar1<numStudents;loopVar1++)
            if(nums[loopVar1]<roundAmt)
                ans+=(roundAmt-nums[loopVar1]);
        strAns="";
        ss.str("");
        ss<<ans;
        strAns=ss.str();
        pos=strAns.find('.');
        if(pos==-1)
            strAns+=".00";
        else
            strAns.erase(pos+3);
        cout<<'$'<<strAns<<"\n";
    }
    return 0;
}
\$\endgroup\$
5
  • \$\begingroup\$ Code Review is for improving code that your think works, not finding errors in your code. See the FAQ. \$\endgroup\$
    – svick
    Feb 4, 2013 at 16:07
  • \$\begingroup\$ @svick i had read the faq before posting and i think it comes in the "correctness in unanticipated cases" category. i just want help in finding a tricky test case. \$\endgroup\$
    – ofey
    Feb 4, 2013 at 17:12
  • \$\begingroup\$ I think that applies only when you think the code works, but want to make sure about it (see another line from the FAQ: “To the best of my knowledge, does the code work?”). But if others won't agree with me, your question won't be closed. \$\endgroup\$
    – svick
    Feb 4, 2013 at 17:17
  • \$\begingroup\$ The other problem is not closed, which could be a hint to let it open. I think your description improving code that your think works fits very well to this code (without the r). \$\endgroup\$
    – tb-
    Feb 4, 2013 at 19:26
  • \$\begingroup\$ Off topic (I believe), but: Use integers as much as possible. Only convert back to a float (better yet, a double) at the very last moment (to print). Money amounts are not real numbers (at least not in casual use). They are of a fixed precision. They just happen to have a decimal point in them. Just do all the calculating in cents. Also, it may help to add a small epsilon when converting to an int so things like 2.999999999997 go to 3 instead of 2: static_cast<int>(f + 1e-6) (or use a const double EPS = ...; type thing so you can change it easily in a centralized place). \$\endgroup\$
    – Corbin
    Feb 4, 2013 at 23:29

1 Answer 1

2
\$\begingroup\$

I did not run it (and I do not like to read it, too much abbreviations, wrong variable names, too less formatting), but what about this case:

3
1.01
0.99
0.99

sum will be 2.99 / 3 = 0.9966666... roundAmt will be 0.99
ans will be 0
Obviously, it should be 0.01 to fulfill the requirement "so that the net cost to each is the same, to within one cent"

Beside this, please consider the things I mentioned in the beginning. Some concrete examples:

sum/=numStudents;

This is not a sum anymore, it is the average.

loopVar1

Take i, this is expected for a loop variable

numStudents

Could be: number_of_students or numberOfStudents

for(loopVar1=0;loopVar1<numStudents;loopVar1++)

Could be: for (i = 0; i < number_of_students; ++i)

for(loopVar1=0;loopVar1<numStudents;loopVar1++)
            if(nums[loopVar1]<roundAmt)
                ans+=(roundAmt-nums[loopVar1]);

One could discuss if using the short form without brackets is ok for one line statements, but if it spans over multiple lines, please use brackets, even if it is syntactically ok.

what does roundAmt mean?

and so forth.

\$\endgroup\$
2
  • \$\begingroup\$ thanks, would be glad if you could also refer some resource for learning how to write cleaner code. \$\endgroup\$
    – ofey
    Feb 5, 2013 at 12:21
  • \$\begingroup\$ I do not have any references for C/C++, my personal opinion is that C/C++ is focused on hardware, not the programmer. For the basics, there are some online resources you can easily find with google and keywords like "best practices coding" "clean code" and so on. There is no whole book about the fundamentals I would explicitly recommend in C/C++. Perhaps ther users have different suggestions. \$\endgroup\$
    – tb-
    Feb 5, 2013 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.