Comments (5)
The problem is that add_student()
calls qsort()
twice, But qsort()
does not necessarily (or usually) use a stable sorting algorithm.
After the first call to qsort()
the students are sorted by their names.
After the second call to qsort()
the students are sorted by their rank ... but within the same rank they are no longer necessarily sorted by their names.
The standard does not specify the implementation of qsort()
, so the implementations vary. That's why you get different results on different platforms, they rely on an implementation detail.
The simplest fix is to merge the two comparison functions into one.
from c.
Advice applied : tests passe online ;-)
Thanks !
from c.
Can you show your solution and the error you got from Exercism's test runner?
from c.
Test 14 (test_students_are_sorted_by_grades_and_then_by_names_in_roster)
- Expected 'Anna' Was 'Barb'
Test 20 (test_students_are_sorted_by_name_in_grade)
- Expected 'Bradley' Was 'Franklin'
For example, test 14 expects
roster_t expected = {7,
{(student_t){1, "Anna"},
(student_t){1, "Barb"},
(student_t){1, "Charlie"},
(student_t){2, "Alex"},
(student_t){2, "Peter"},
(student_t){2, "Zoe"},
(student_t){3, "Jim"}}};
And when I print the roster's state during test 14 I get
[Anna ] 1
[Barb ] 1
[Charlie ] 1
[Alex ] 2
[Peter ] 2
[Zoe ] 2
[Jim ] 3
My solution
grade_school.h
#ifndef GRADE_SCHOOL_H
#define GRADE_SCHOOL_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#define MAX_NAME_LENGTH 20
#define MAX_STUDENTS 20
typedef struct {
uint8_t grade;
char name[MAX_NAME_LENGTH];
} student_t;
typedef struct {
size_t count;
student_t students[MAX_STUDENTS];
} roster_t;
int name_comparator(const void* first, const void* second);
int grade_comparator(const void* first, const void* second);
void init_roster(roster_t* roster);
bool add_student(roster_t* roster, char* name, int grade);
roster_t get_grade(roster_t* roster, uint8_t desired_grade);
#endif
grade_school.c
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "grade_school.h"
roster_t result;
void print_roster(roster_t* roster);
void print_roster(roster_t* roster) {
size_t i = 0;
for (i = 0; i < roster->count; i++) {
printf("[%-20s] %2d\n", roster->students[i].name, roster->students[i].grade);
}
printf("-------------\n");
}
int name_comparator(const void* first, const void* second) {
student_t* s1 = (student_t*)first;
student_t* s2 = (student_t*)second;
return strncmp(s1->name, s2->name, MAX_NAME_LENGTH);
}
int grade_comparator(const void* first, const void* second) {
student_t* s1 = (student_t*)first;
student_t* s2 = (student_t*)second;
return s1->grade - s2->grade;
}
void init_roster(roster_t* roster) {
memset((void*)roster, 0, sizeof(roster_t));
}
bool add_student(roster_t* roster, char* name, int grade) {
size_t i = 0;
for (i = 0; i < roster->count; i++) {
if (strncmp(roster->students[i].name, name, MAX_NAME_LENGTH) == 0)
return false; // forbid adding student twice
}
i = 0;
while (roster->students[i].grade != 0) {
i++;
if (i == MAX_STUDENTS)
return false;
}
roster->students[i].grade = grade;
strncpy(roster->students[i].name, name, MAX_NAME_LENGTH);
roster->count++;
qsort((void*)roster->students, roster->count, sizeof(student_t), name_comparator);
qsort((void*)roster->students, roster->count, sizeof(student_t), grade_comparator);
print_roster(roster);
return true;
}
roster_t get_grade(roster_t* roster, uint8_t desired_grade) {
result.count = 0;
for (size_t i = 0; i < roster->count; i++) {
if (roster->students[i].grade == desired_grade) {
memcpy((void*)&result.students[result.count], (void*)&roster->students[i], sizeof(student_t));
result.count++;
}
}
return result;
}
from c.
Djizz I wasn't aware of this subtle detail about qsort (and didn't see anything related in the online docs or ref, or maybe I missed it)
from c.
Related Issues (20)
- Add learn track for C HOT 5
- Implement the exercise "high-scores" HOT 9
- Change to "community-contributions-accepted" HOT 2
- Expected and actual assertion arguments reversed in some tests HOT 2
- Docs: test framework overview links to empty article HOT 1
- More documentation to `Grade School` HOT 1
- Add `make memcheck` tip for the HELP.md file. HOT 1
- Building a training set of tags for c HOT 23
- Rework the gigasecond exercise? HOT 3
- Problems in pascals-triangle test HOT 12
- The order of the results actually matters for the Word Count exercise HOT 4
- Pascal's Triangle has a bad Test Case defining Zero Rows. HOT 2
- Exercises for #48in24 HOT 17
- pig latin in C track HOT 2
- The square root problem needs to be improved HOT 4
- Return type for `convert(char result[], int drops)` in "Raindrop" should be of type `void` HOT 2
- Approach is missing in "Hamming" HOT 5
- Jumped right from Hello World to Armstrong Numbers? HOT 5
- Use of macros in "Series" isn't clear, consideration for removal? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from c.