Added exercise 26 (sort cars)

This commit is contained in:
Claudio Maggioni 2019-11-05 15:03:46 +01:00
parent 834f854fd9
commit e098bc87ac
2 changed files with 218 additions and 0 deletions

92
cars/sort_cars.c Normal file
View file

@ -0,0 +1,92 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct car {
char maker[21];
char model[21];
unsigned int power;
unsigned int price;
};
enum sort {
MODEL,
MAKER,
PRICE,
POWER
};
enum sort sorting = MAKER;
int asc = 0;
int asc_desc(int o) {
if (asc) {
return o;
} else {
return o * -1;
}
}
int compare_cars(const void* car1, const void* car2) {
const struct car* c1 = car1;
const struct car* c2 = car2;
// printf("%s %s %u %u\n", c1->maker, c1->model, c1->power, c1->price);
// printf("%s %s %u %u\n", c2->maker, c2->model, c2->power, c2->price);
switch (sorting) {
case MODEL:
return asc_desc(strcmp(c1->model, c2->model));
case MAKER:
return asc_desc(strcmp(c1->maker, c2->maker));
case PRICE:
return asc_desc(c1->price - c2->price);
case POWER:
return asc_desc(c1->power - c2->power);
}
}
int main(int argc, const char** argv) {
if (argc == 2) {
if (!strcmp(argv[1], "+model")) { sorting = MODEL; asc = 1; }
else if (!strcmp(argv[1], "-model")) { sorting = MODEL; asc = 0; }
else if (!strcmp(argv[1], "+maker")) { sorting = MAKER; asc = 1; }
else if (!strcmp(argv[1], "-maker")) { sorting = MAKER; asc = 0; }
else if (!strcmp(argv[1], "+price")) { sorting = PRICE; asc = 1; }
else if (!strcmp(argv[1], "-price")) { sorting = PRICE; asc = 0; }
else if (!strcmp(argv[1], "+power")) { sorting = POWER; asc = 1; }
else if (!strcmp(argv[1], "-power")) { sorting = POWER; asc = 0; }
else { fprintf(stderr, "wrong argument\n"); return 3; }
} else if (argc > 2) {
fprintf(stderr, "wrong arguments\n");
return 3;
}
size_t length = 1024, i = 0;
struct car* A = malloc(sizeof(struct car) * length);
if (!A) {
perror("Cannot allocate cars");
return 1;
}
while(!feof(stdin)) {
scanf("%s %s %u %u\n", A[i].maker, A[i].model, &A[i].power, &A[i].price);
i++;
if (i == length) {
length *= 2;
struct car* B = realloc(A, sizeof(struct car) * length);
if (!B) {
perror("Cannot expand cars");
free(A);
return 2;
}
A = B;
}
}
qsort(A, i, sizeof(struct car), compare_cars);
for (size_t j = 0; j < i; j++) {
printf("%s %s %u %u\n", A[j].maker, A[j].model, A[j].power, A[j].price);
}
free(A);
}

126
cars/test_sort_cars.sh Executable file
View file

@ -0,0 +1,126 @@
#!/bin/sh
#
# test 1
#
cat > test1.in <<EOF
fiat bravo 105 30000
bmw 305i 120 50000
bmw 305 100 45000
fiat 500 80 25000
EOF
./sort_cars < test1.in > test1.out
cat > test1.expected <<EOF
fiat bravo 105 30000
fiat 500 80 25000
bmw 305i 120 50000
bmw 305 100 45000
EOF
if diff -q test1.out test1.expected; then
rm -f test1.out test1.expected
else
echo "Test 1 FAILED"
diff test1.out test1.expected
exit 1
fi
#
# test 2
#
./sort_cars +model < test1.in > test1.out
cat > test1.expected <<EOF
bmw 305 100 45000
bmw 305i 120 50000
fiat 500 80 25000
fiat bravo 105 30000
EOF
if diff -q test1.out test1.expected; then
rm -f test1.out test1.expected
else
echo "Test 2 FAILED"
diff test1.out test1.expected
exit 1
fi
#
# test 3
#
./sort_cars -power < test1.in > test1.out
cat > test1.expected <<EOF
bmw 305i 120 50000
fiat bravo 105 30000
bmw 305 100 45000
fiat 500 80 25000
EOF
if diff -q test1.out test1.expected; then
rm -f test1.out test1.expected
else
echo "Test 3 FAILED"
diff test1.out test1.expected
exit 1
fi
#
# test 4
#
./sort_cars +power < test1.in > test1.out
cat > test1.expected <<EOF
fiat 500 80 25000
bmw 305 100 45000
fiat bravo 105 30000
bmw 305i 120 50000
EOF
if diff -q test1.out test1.expected; then
rm -f test1.out test1.expected
else
echo "Test 4 FAILED"
diff test1.out test1.expected
exit 1
fi
#
# test 5
#
./sort_cars +price < test1.in > test1.out
cat > test1.expected <<EOF
fiat 500 80 25000
fiat bravo 105 30000
bmw 305 100 45000
bmw 305i 120 50000
EOF
if diff -q test1.out test1.expected; then
rm -f test1.out test1.expected
else
echo "Test 5 FAILED"
diff test1.out test1.expected
exit 1
fi
#
# test 6
#
./sort_cars -price < test1.in > test1.out
cat > test1.expected <<EOF
bmw 305i 120 50000
bmw 305 100 45000
fiat bravo 105 30000
fiat 500 80 25000
EOF
if diff -q test1.out test1.expected; then
rm -f test1.out test1.expected
else
echo "Test 6 FAILED"
diff test1.out test1.expected
exit 1
fi
rm -f test1.in
#
# test 7
#
(for x in `seq 1 200`; do for y in `seq 100 300`; do echo "maker$x model$y 1$x ${x}9$y"; done; done ) > test1.in
./sort_cars +price < test1.in > test1.out
sort -n -k 4 < test1.in > test1.expected
if diff -q test1.out test1.expected; then
rm -f test1.out test1.expected
else
echo "Test 7 FAILED"
diff test1.out test1.expected
exit 1
fi
rm -f test1.in
echo PASSED