The structure is given:
struct Date {
int day, month, year;
};
struct Subject {
int id;
char name_of_subject[100];
double ects;
};
struct Grade {
char namesurname[100];
int grade_value;
struct Subject subject;
struct Date date;
};
It is necessary to write a function digits_in_date that receives struct array of grades. For all students who have a total of 30 or more ECTS credits in the subjects they have passed (they have a grade of 6 or higher), it is necessary to exclude from the array (without changing the order!) those grades whose date contains the minimum number of different digits. Eg the date 20 February 2020 contains only two different digits (2 and 0). If they have more than one grade whose dates have the same (minimum) number of digits, all such grades should be dropped from the array. You can find out that the grades belong to the same student based on the name and surname (assume that if two students have the same name and surname, then it is the same student). Assume that the data is valid (valid dates, valid grades, ects credits are not negative, etc.) Auxiliary arrays are not allowed. Only allowed auxiliary array is when making histogram.
EXAMPLE:
struct Grade arr[3] = {
{"Luc Manning", 10, {1, "Physics", 25}, {19, 1, 2020}},
{"Kaia Feeney", 8, {1, "Math", 25}, {19, 1, 2020}},
{"Luc Manning", 7, {2, "Linear Algebra", 10}, {11, 1, 2020}}};
EXPLANATION:
Sum of Luc Manning ECTS points is 35, so we check how many different digits are there in his subjects dates. Physics has 4, and Linear Algebra has 3 different digits in dates, so Linear Algebra should be removed. Sum of Kaia Feeney ECTS points is 25, so we don't check anything.
OUTPUT would be:
Luc Manning - Physics
Kaia Feeney - Math
INSTRUCTION: Create an auxiliary function that determines the number of different digits in the date using a histogram. Then the auxiliary function that calculates the number of ECTS credits and finally the ejection function. This will make your task drastically easier.
The only problem I have in code is that my program removes wrong subjects, and algorithms for the rest of task are correct. Half of the code are just autotests :) The code is not so long.
EDIT: after @pm100 made a function that would save 400 lines of code, and with my modification of original code, now the code is:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
struct Date {
int day, month, year;
};
struct Subject {
int id;
char name_of_subject[100];
double ects;
};
struct Grade {
char namesurname[100];
int grade_value;
struct Subject subject;
struct Date date;
};
int num_digit(int n) {
int num = 0;
while (n != 0) {
num++;
n /= 10;
}
return num;
}
int check_digits(int d, int m, int y) {
char dateStr[10];
sprintf(dateStr, "%02d%02d%04d", d, m, y);
int count[10] = {0};
for (int i = 0; i < strlen(dateStr); i++) {
char ch = dateStr[i];
count[ch - '0']++;
}
int num = 0;
for (int i = 0; i < 10; i++) {
if (count[i] > 0)
num++;
}
return num;
}
double credits(struct Grade arr[], int n, int i) {
int j;
double sum = arr[i].subject.ects;
for (j = i + 1; j < n; j++)
if (strcmp(arr[j].namesurname, arr[i].namesurname) == 0)
sum += arr[j].subject.ects;
return sum;
}
int find_min(struct Grade arr[], int n, int i) {
int j,
min = check_digits(arr[i].date.day, arr[i].date.month, arr[i].date.year);
for (j = i + 1; j < n; j++)
if (strcmp(arr[j].namesurname, arr[i].namesurname) == 0)
if (check_digits(arr[j].date.day, arr[j].date.month, arr[j].date.year) <
min)
min = j;
return min;
}
int digits_in_date(struct Grade arr[], int n) {
int i, j, k, min;
double sum_ects;
for (i = 0; i < n; i++) {
sum_ects = credits(arr, n, i);
if (sum_ects >= 30) {
min = find_min(arr, n, i);
for (j = 0; j < n; j++)
if (strcmp(arr[j].subject.name_of_subject,
arr[min].subject.name_of_subject) == 0) {
for (k = j + 1; k < n; k++)
arr[k - 1] = arr[k];
j--;
n--;
}
}
}
return n;
}
int main() {
int i, s;
printf("\nAT1: Trivial case\n");
struct Grade arr1[3] = {
{"Luc Manning", 10, {1, "Physics", 25}, {19, 1, 2020}},
{"Kaia Feeney", 8, {1, "Math", 25}, {19, 1, 2020}},
{"Luc Manning", 7, {2, "Linear Algebra", 10}, {11, 1, 2020}}};
s = digits_in_date(arr1, 3);
for (i = 0; i < s; i++)
printf("%s - %s\n", arr1[i].namesurname, arr1[i].subject.name_of_subject);
printf("\nAT2: We must not observe the same student more than once\n");
struct Grade arr2[4] = {
{"Mujo Suljic", 10, {1, "Uvod u programiranje", 25}, {19, 1, 2020}},
{"Fata Fatic", 8, {1, "Uvod u programiranje", 25}, {19, 1, 2020}},
{"Mujo Suljic", 7, {2, "Inzenjerska fizika", 10}, {11, 1, 2020}},
{"Mujo Suljic", 10, {3, "Inzenjerska matematika", 6}, {1, 9, 2020}}};
s = digits_in_date(arr2, 4);
for (i = 0; i < s; i++)
printf("%s - %s\n", arr2[i].namesurname, arr2[i].subject.name_of_subject);
printf("CORRECT:\nMujo Suljic - Uvod u programiranje\nFata Fatic - Uvod u programiranje\nMujo Suljic - Inzenjerska matematika\n");
printf("\nAT3: Multiple successive ejections\n");
struct Grade arr3[6] = {
{"Mujo Suljic", 10, {1, "Uvod u programiranje", 25}, {2, 2, 2020}},
{"Mujo Suljic", 6, {5, "Osnove elektrotehnike", 25}, {20, 2, 2022}},
{"Fata Fatic", 8, {1, "Uvod u programiranje", 25}, {19, 1, 2020}},
{"Mujo Suljic", 7, {2, "Inzenjerska fizika", 10}, {11, 1, 2020}},
{"Mujo Suljic", 10, {3, "Inzenjerska matematika", 6}, {20, 1, 2020}},
{"Fata Fatic", 8, {4, "Inzenjerska matematika", 25}, {9, 9, 2021}}};
s = digits_in_date(arr3, 6);
for (i = 0; i < s; i++)
printf("%s - %s %g\n", arr3[i].namesurname, arr3[i].subject.name_of_subject,
arr3[i].subject.ects);
printf("CORRECT:\nMujo Suljic - Inzenjerska fizika 10\nMujo Suljic - Inzenjerska matematika 6\n");
printf("\nAT4: Array with one element\n");
struct Grade arr4[1] = {
{"John Smith", 10, {1, "Subject 1", 29}, {19, 11, 1991}}};
s = digits_in_date(arr4, 1);
printf("%d ", s);
arr4[0].subject.ects = 31;
s = digits_in_date(arr4, 1);
printf("%d\n", s);
printf("CORRECT:\n1 0\n");
printf(
"\nAT5: We don't eject anything out, no one has 30 credits in total\n");
struct Grade arr5[6] = {
{"Mujo Suljic", 10, {1, "Uvod u programiranje", 25}, {20, 2, 2020}},
{"Pero Peric", 6, {5, "Osnove elektrotehnike", 25}, {20, 2, 2020}},
{"Fata Fatic", 8, {1, "Uvod u programiranje", 25}, {19, 1, 2020}},
{"Mujo Suljic", 7, {2, "Inzenjerska fizika", 1}, {11, 1, 2020}},
{"Mujo Suljic", 10, {3, "Inzenjerska matematika", 2}, {20, 1, 2020}},
{"Fata Fatic", 8, {4, "Inzenjerska matematika", 2}, {19, 1, 2020}}};
s = digits_in_date(arr5, 6);
printf("s: %d\n", s);
printf("AT5 again: Inzenjerska fizika now carries 4 ECTS credits so Mujo has "
"the required number of credits\n");
arr5[3].subject.ects = 4;
s = digits_in_date(arr5, 6);
for (i = 0; i < s; i++)
printf("%s - %s %g\n", arr5[i].namesurname, arr5[i].subject.name_of_subject,
arr5[i].subject.ects);
printf("CORRECT:\ns: 6\nAT5 again: Inzenjerska fizika now carries 4 ECTS credits so Mujo has "
"the required number of credits\nPero Peric - Osnove elektrotehnike 25\nFata Fatic - Uvod u programiranje 25\nMujo Suljic - Inzenjerska fizika 4\n"
"Mujo Suljic - Inzenjerska matematika 2\nFata Fatic - Inzenjerska matematika 2\n");
//
printf("\nAT6: Mujo Suljic did not pass Injzenjerska fizika, he does not "
"have 30 ECTS credits\n");
struct Grade arr6[6] = {
{"Mujo Suljic", 10, {1, "Uvod u programiranje", 25}, {20, 2, 2020}},
{"Pero Peric", 6, {5, "Osnove elektrotehnike", 25}, {20, 2, 2020}},
{"Fata Fatic", 8, {1, "Uvod u programiranje", 25}, {19, 1, 2020}},
{"Mujo Suljic", 5, {2, "Inzenjerska fizika", 10}, {11, 1, 2020}},
{"Mujo Suljic", 10, {3, "Inzenjerska matematika", 4}, {20, 1, 2020}},
{"Fata Fatic", 8, {4, "Inzenjerska matematika", 25}, {19, 1, 2020}}};
s = digits_in_date(arr6, 6);
for (i = 0; i < s; i++)
printf("%s - %s %g\n", arr6[i].namesurname, arr6[i].subject.name_of_subject,
arr6[i].subject.ects);
printf("CORRECT:\nMujo Suljic - Uvod u programiranje 25\nPero Peric - Osnove elektrotehnike 25\n"
"Mujo Suljic - Inzenjerska fizika 10\nMujo Suljic - Inzenjerska matematika 4\n");
return 0;
}
I only get correct output for AutoTest1 - AT1 (which is the same as example), and the rest AT are wrong. Could you help me modify this to work properly?