Added exercise 26 (sort cars)
This commit is contained in:
parent
834f854fd9
commit
e098bc87ac
2 changed files with 218 additions and 0 deletions
92
cars/sort_cars.c
Normal file
92
cars/sort_cars.c
Normal 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
126
cars/test_sort_cars.sh
Executable 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
|
Reference in a new issue