mercredi 4 mars 2015

can you think of a test which could make my program give wrong answers?

I am trying to solve this problem


http://ift.tt/1M61rSL


I've got my solution working on the provided test. When I submit my solution I get wrong answer on the 11th test. So, could you please think about such an input which can make my program give wrong answers?


P.S. the problem is not time or memory shortage. The time of executation is 0.015 s, and the memory used is 214 KB. I guess the test is quite short with reasonable numbers.



#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

typedef struct letter
{
int change; // amount of money spent or gained
int date; // packed date, I will never need the actual date, I will just need which date is earlier (smaller), and which is later (greater)
int sign : 1; // minus one for plus, zero for minus
int seen : 1; // minus one for seen, zero otherwise
} Letter;

int packDate(int, int, int, int); // we will not need to know the date, just their relation to each other
void printLetter(Letter *); // for debugging, not implemented
void getTime(int *, int *, int *, int *); // read time from input
void selectionSort(Letter *, int); // sort the letters by date, to get them in chronological order
void letterCopy(Letter *, Letter *, int); // copy one array of letters to another
long long check(Letter *, int); // evaluate the debt
int binSearch(int, Letter *, int); // find the index of letter with given date

int main()
{
int n;
scanf("%i", &n);
getchar();
Letter *pletters = (Letter *)malloc(sizeof(Letter) * n);
int i;
for (i = 0; i < n; ++i) { // read letters
char sign = getchar();
pletters[i].sign = sign == '+' ? 1 : 0;
scanf("%i", &pletters[i].change);
getchar();
int dd, MM, hh, mm;
getTime(&dd, &MM, &hh, &mm);
pletters[i].date = packDate(dd, MM, hh, mm);
pletters[i].seen = 0;
} // the letters are read
Letter *plSorted = (Letter *)malloc(sizeof(Letter) * n);
letterCopy(pletters, plSorted, n); // make a copy of the letters array
selectionSort(plSorted, n); // sort copy, to get in historical order
for (i = 0; i < n; ++i) { // evaluate each letter in original order
int si = binSearch(pletters[i].date, plSorted, n); // find the position of this letter in historical order
plSorted[si].seen = 1; // mark it in historical order as seen
printf("%li\n", check(plSorted, n)); // evaluate debt, based on all seen letters, and print it
}
return 0;
}

int binSearch(int d, Letter *l, int n)
{
int mid;
int low = 0;
int high = n - 1;
while (low <= high) {
mid = (low + high) / 2;
if (d < l[mid].date) {
high = mid - 1;
} else if (d > l[mid].date){
low = mid + 1;
} else {
return mid;
}
}
return -1;
}

long long check(Letter *s, int n)
{
int i;
long long cash, debt;
cash = debt = 0;
for (i = 0; i < n; ++i) {
if (s[i].seen) {
if (s[i].sign) {
cash += s[i].change; // if letter states +, then add amount to Zhenya's cash
} else {
cash -= s[i].change; // if he has money, he spends money from his cash
debt += cash < 0 ? cash : 0; // if he rans out of money, he will use credit card
cash = cash < 0 ? 0 : cash; // if he used credit card, his cash is empty
}
}
}
return debt;
}

void letterCopy(Letter *s, Letter *d, int n)
{
int i;
for (i = 0; i < n; ++i) {
d[i] = s[i];
}
}

void selectionSort(Letter *l, int n)
{
int i, j, min, mi;
for (i = 0; i < n; ++i) {
min = INT_MAX;
mi = i;
for (j = i; j < n; ++j) {
if (l[j].date < min) {
min = l[j].date;
mi = j;
}
}
Letter t = l[i];
l[i] = l[mi];
l[mi] = t;
}
}

void getTwoDigits(int *);

void getTime(int *dd, int *MM, int *hh, int *mm)
{
getTwoDigits(dd);
getTwoDigits(MM);
getTwoDigits(hh);
getTwoDigits(mm);
}

void getTwoDigits(int *n)
{
*n = 0;
*n += (getchar() - '0') * 10;
*n += getchar() - '0';
getchar();
}

int packDate(int dd, int MM, int hh, int mm)
{
mm += MM * 31 * 12 * 60 + dd * 12 * 60 + hh * 60;
return mm;
}


The code works fine on provided test, and on the test I found in the discussion section. I think I could try to generate all the tests for a specific n, then write a scipt to go over all of them, and then manually check all the answers, but before I start this, can anyone come up with a test? or with an idea how to do testing the most fast and efficient way? Thanks.


Aucun commentaire:

Enregistrer un commentaire