#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* qsort C-string comparison function from qsort(3) man-page */
static int
cmpstringp(const void *p1, const void *p2)
{
/* The actual arguments to this function are "pointers to
pointers to char", but strcmp(3) arguments are "pointers
to char", hence the following cast plus dereference */
return strcmp(* (char * const *) p1
, * (char * const *) p2
); }
static double
get_score(int scores) {
size_t sum = 0, nscores = 0;
for ( ; scores > 0; scores /= 10) {
sum += scores % 10;
++nscores;
}
return (double)sum / nscores; /*XXX remove /nscore to get mere sum */
}
int main(void) {
const char* student_list[] = {
/* группа | фио | оценки */
"4272 Галкин Г. А. 5445",
"4273 Константинопольский А. А. 4333",
"4273 Курочкин А. А. 3433",
"4272 Козлов И. И. 4443"
};
const size_t n = sizeof(student_list) / sizeof(student_list[0]);
const char* *pstudent = NULL;
int last_group = -1;
double group_score = 0;
size_t group_count = 0;
qsort(student_list
, n
, sizeof(student_list
[0]), cmpstringp
);
for (pstudent = student_list; pstudent != &student_list[n]; ++pstudent) {
int group = -1, scores = -1;
char *name = NULL;
errno = 0;
if (sscanf(*pstudent
, "%d %m[^0-9] %d", &group
, &name
, &scores
) != 3) { fprintf(stderr
, "error: can't parse '%s'\n", *pstudent
); }
if (group != last_group) {
if (group_count > 0) /* print the last group average score */
printf("%d %f\n", last_group
, (double)group_score
/group_count
);
group_score = 0; /* start new group */
group_count = 0;
last_group = group;
}
++group_count;
group_score += get_score(scores);
}
if (group_count > 0) /* print the last group average score */
printf("%d %f\n", last_group
, (double)group_score
/group_count
); return 0;
}
I2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCi8qIHFzb3J0IEMtc3RyaW5nIGNvbXBhcmlzb24gZnVuY3Rpb24gZnJvbSBxc29ydCgzKSBtYW4tcGFnZSAqLwpzdGF0aWMgaW50CmNtcHN0cmluZ3AoY29uc3Qgdm9pZCAqcDEsIGNvbnN0IHZvaWQgKnAyKQp7CiAgLyogVGhlIGFjdHVhbCBhcmd1bWVudHMgdG8gdGhpcyBmdW5jdGlvbiBhcmUgInBvaW50ZXJzIHRvCiAgICAgcG9pbnRlcnMgdG8gY2hhciIsIGJ1dCBzdHJjbXAoMykgYXJndW1lbnRzIGFyZSAicG9pbnRlcnMKICAgICB0byBjaGFyIiwgaGVuY2UgdGhlIGZvbGxvd2luZyBjYXN0IHBsdXMgZGVyZWZlcmVuY2UgKi8KCiAgcmV0dXJuIHN0cmNtcCgqIChjaGFyICogY29uc3QgKikgcDEsICogKGNoYXIgKiBjb25zdCAqKSBwMik7Cn0KCnN0YXRpYyBkb3VibGUKZ2V0X3Njb3JlKGludCBzY29yZXMpIHsKICBzaXplX3Qgc3VtID0gMCwgbnNjb3JlcyA9IDA7CiAgZm9yICggOyBzY29yZXMgPiAwOyBzY29yZXMgLz0gMTApIHsKICAgIHN1bSArPSBzY29yZXMgJSAxMDsKICAgICsrbnNjb3JlczsKICB9CiAgcmV0dXJuIChkb3VibGUpc3VtIC8gbnNjb3JlczsgLypYWFggcmVtb3ZlIC9uc2NvcmUgdG8gZ2V0IG1lcmUgc3VtICovCn0KCmludCBtYWluKHZvaWQpIHsKICBjb25zdCBjaGFyKiBzdHVkZW50X2xpc3RbXSA9IHsKICAgIC8qINCz0YDRg9C/0L/QsCB8INGE0LjQviB8ICDQvtGG0LXQvdC60LggKi8KICAgICI0MjcyINCT0LDQu9C60LjQvSDQky4g0JAuIDU0NDUiLAogICAgIjQyNzMg0JrQvtC90YHRgtCw0L3RgtC40L3QvtC/0L7Qu9GM0YHQutC40Lkg0JAuINCQLiA0MzMzIiwKICAgICI0MjczINCa0YPRgNC+0YfQutC40L0g0JAuINCQLiAzNDMzIiwKICAgICI0MjcyINCa0L7Qt9C70L7QsiDQmC4g0JguIDQ0NDMiCiAgfTsKICBjb25zdCBzaXplX3QgbiA9IHNpemVvZihzdHVkZW50X2xpc3QpIC8gc2l6ZW9mKHN0dWRlbnRfbGlzdFswXSk7CiAgY29uc3QgY2hhciogKnBzdHVkZW50ID0gTlVMTDsKICBpbnQgbGFzdF9ncm91cCA9IC0xOwogIGRvdWJsZSBncm91cF9zY29yZSA9IDA7CiAgc2l6ZV90IGdyb3VwX2NvdW50ID0gMDsKCiAgcXNvcnQoc3R1ZGVudF9saXN0LCBuLCBzaXplb2Yoc3R1ZGVudF9saXN0WzBdKSwgY21wc3RyaW5ncCk7CgogIGZvciAocHN0dWRlbnQgPSBzdHVkZW50X2xpc3Q7IHBzdHVkZW50ICE9ICZzdHVkZW50X2xpc3Rbbl07ICsrcHN0dWRlbnQpIHsKICAgIGludCBncm91cCA9IC0xLCBzY29yZXMgPSAtMTsKICAgIGNoYXIgKm5hbWUgPSBOVUxMOwoKICAgIGVycm5vID0gMDsKICAgIGlmIChzc2NhbmYoKnBzdHVkZW50LCAiJWQgJW1bXjAtOV0gJWQiLCAmZ3JvdXAsICZuYW1lLCAmc2NvcmVzKSAhPSAzKSB7CiAgICAgIGlmIChlcnJubykgcGVycm9yKCJzc2NhbmYiKTsKICAgICAgZnByaW50ZihzdGRlcnIsICJlcnJvcjogY2FuJ3QgcGFyc2UgJyVzJ1xuIiwgKnBzdHVkZW50KTsKICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOwogICAgfQogICAgaWYgKGdyb3VwICE9IGxhc3RfZ3JvdXApIHsKICAgICAgaWYgKGdyb3VwX2NvdW50ID4gMCkgLyogcHJpbnQgdGhlIGxhc3QgZ3JvdXAgYXZlcmFnZSBzY29yZSAqLwogICAgICAgIHByaW50ZigiJWQgJWZcbiIsIGxhc3RfZ3JvdXAsIChkb3VibGUpZ3JvdXBfc2NvcmUvZ3JvdXBfY291bnQpOwoKICAgICAgZ3JvdXBfc2NvcmUgPSAwOyAvKiBzdGFydCBuZXcgZ3JvdXAgKi8KICAgICAgZ3JvdXBfY291bnQgPSAwOwogICAgICBsYXN0X2dyb3VwID0gZ3JvdXA7CiAgICB9CiAgICArK2dyb3VwX2NvdW50OwogICAgZ3JvdXBfc2NvcmUgKz0gZ2V0X3Njb3JlKHNjb3Jlcyk7CiAgICBmcmVlKG5hbWUpOwogIH0KICBpZiAoZ3JvdXBfY291bnQgPiAwKSAvKiBwcmludCB0aGUgbGFzdCBncm91cCBhdmVyYWdlIHNjb3JlICovCiAgICBwcmludGYoIiVkICVmXG4iLCBsYXN0X2dyb3VwLCAoZG91YmxlKWdyb3VwX3Njb3JlL2dyb3VwX2NvdW50KTsKICByZXR1cm4gMDsKfQo=