add sorter with respecting testcase collections
This commit is contained in:
parent
e80aa55375
commit
ec5f4f6543
7
Makefile
7
Makefile
|
@ -4,12 +4,15 @@ build: main
|
|||
|
||||
test: tester
|
||||
|
||||
tester: out/tester.o out/swapper.o
|
||||
gcc $(CFLAGS) out/tester.o out/swapper.o -o tester
|
||||
tester: out/tester.o out/sorter.o
|
||||
gcc $(CFLAGS) out/tester.o out/sorter.o -o tester
|
||||
|
||||
out/tester.o: out/ src/tester.c
|
||||
gcc $(CFLAGS) -c src/tester.c -o out/tester.o
|
||||
|
||||
out/sorter.o: out/ src/sorter.c
|
||||
gcc $(CFLAGS) -c src/sorter.c -o out/sorter.o
|
||||
|
||||
out/:
|
||||
mkdir out/
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
void sorter_insertion_sort(char **arr, int size);
|
|
@ -0,0 +1,44 @@
|
|||
#include <string.h>
|
||||
#include "sorter.h"
|
||||
|
||||
#define MIN(a, b) ( ((a) < (b)) ? (a) : (b) )
|
||||
|
||||
static int lt(char *a, char *b)
|
||||
{
|
||||
int len_a = strlen(a);
|
||||
int len_b = strlen(b);
|
||||
|
||||
for (int i = 0; i < MIN(len_a, len_b); i++) {
|
||||
if (a[i] < b[i])
|
||||
return 1;
|
||||
else if (a[i] > b[i])
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (len_a > len_b);
|
||||
}
|
||||
|
||||
static void swap(char **arr, int x, int y)
|
||||
{
|
||||
char *tmp = arr[x];
|
||||
arr[x] = arr[y];
|
||||
arr[y] = tmp;
|
||||
}
|
||||
|
||||
void sorter_insertion_sort(char **arr, int len)
|
||||
{
|
||||
for (int i = 0; i < len-1; i++) {
|
||||
char *min = arr[i];
|
||||
int min_index = i;
|
||||
|
||||
for (int j = i+1; j < len; j++) {
|
||||
if (lt(arr[j], min) == 1) {
|
||||
min_index = j;
|
||||
min = arr[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (min_index != i)
|
||||
swap(arr, i, min_index);
|
||||
}
|
||||
}
|
141
src/tester.c
141
src/tester.c
|
@ -1,12 +1,14 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "swapper.h"
|
||||
#include "sorter.h"
|
||||
|
||||
enum read_state {
|
||||
LEN = 0,
|
||||
STR1 = 1,
|
||||
STR2 = 2,
|
||||
ARR1 = 1,
|
||||
ARR2 = 2,
|
||||
FINISH = 3,
|
||||
IMPOSSIBLE_STATE = 4
|
||||
};
|
||||
|
@ -44,30 +46,55 @@ static int read_more(int f, char *buf, int bytes_read)
|
|||
return 1024 - bytes_read + new_bytes;
|
||||
}
|
||||
|
||||
static int parse_case(char *cmd, int *target_length_diff, char *str_a, char *str_b)
|
||||
static int parse_case(char *cmd, int *array_size, char ***a, char ***b)
|
||||
{
|
||||
int bytes_read;
|
||||
int write_offset = 0;
|
||||
int array_offset = 0;
|
||||
char len_buffer[4] = {0};
|
||||
enum read_state rs = LEN;
|
||||
|
||||
for (bytes_read = 0; bytes_read < 1024; bytes_read++) {
|
||||
switch (cmd[bytes_read]) {
|
||||
case ',':
|
||||
switch (rs) {
|
||||
case ARR1:
|
||||
(*a)[array_offset][write_offset] = '\0';
|
||||
break;
|
||||
case ARR2:
|
||||
(*b)[array_offset][write_offset] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
write_offset = 0;
|
||||
array_offset++;
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
switch (rs) {
|
||||
case LEN:
|
||||
*target_length_diff = to_int(len_buffer);
|
||||
*array_size = to_int(len_buffer);
|
||||
|
||||
*a = (char **) malloc(sizeof(char *) * (*array_size));
|
||||
*b = (char **) malloc(sizeof(char *) * (*array_size));
|
||||
|
||||
for (int i = 0; i < *array_size; i++) {
|
||||
(*a)[i] = malloc(sizeof(char) * 128);
|
||||
(*b)[i] = malloc(sizeof(char) * 128);
|
||||
}
|
||||
|
||||
break;
|
||||
case STR1:
|
||||
str_a[write_offset] = '\0';
|
||||
case ARR1:
|
||||
(*a)[array_offset][write_offset] = '\0';
|
||||
break;
|
||||
}
|
||||
rs++;
|
||||
write_offset = 0;
|
||||
array_offset = 0;
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
str_b[write_offset] = '\0';
|
||||
(*b)[array_offset][write_offset] = '\0';
|
||||
bytes_read++;
|
||||
goto finish;
|
||||
break;
|
||||
|
@ -77,11 +104,11 @@ static int parse_case(char *cmd, int *target_length_diff, char *str_a, char *str
|
|||
case LEN:
|
||||
len_buffer[write_offset] = cmd[bytes_read];
|
||||
break;
|
||||
case STR1:
|
||||
str_a[write_offset] = cmd[bytes_read];
|
||||
case ARR1:
|
||||
(*a)[array_offset][write_offset] = cmd[bytes_read];
|
||||
break;
|
||||
case STR2:
|
||||
str_b[write_offset] = cmd[bytes_read];
|
||||
case ARR2:
|
||||
(*b)[array_offset][write_offset] = cmd[bytes_read];
|
||||
break;
|
||||
}
|
||||
write_offset++;
|
||||
|
@ -93,30 +120,90 @@ static int parse_case(char *cmd, int *target_length_diff, char *str_a, char *str
|
|||
return bytes_read;
|
||||
}
|
||||
|
||||
static int assert_length(int test_id, int target_length_diff, char *a, char *b)
|
||||
static void destroy_array(char **a, int array_size)
|
||||
{
|
||||
int len_diff = swapper_length_difference(a, b);
|
||||
for (int i = 0; i < array_size; i++)
|
||||
free(a[i]);
|
||||
|
||||
if (len_diff == target_length_diff) {
|
||||
free(a);
|
||||
}
|
||||
|
||||
static int cmp_arrays(int array_size, char **a, char **b)
|
||||
{
|
||||
int mismatch_byte = 0;
|
||||
|
||||
for (int i = 0; i < array_size; i++, mismatch_byte++) {
|
||||
int la = strlen(a[i]);
|
||||
int lb = strlen(b[i]);
|
||||
|
||||
if (la != lb)
|
||||
return mismatch_byte;
|
||||
|
||||
for (int j = 0; j < la; j++, mismatch_byte++) {
|
||||
if (a[i][j] != b[i][j])
|
||||
return mismatch_byte;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void print_array(int array_size, char **arr)
|
||||
{
|
||||
for (int i = 0; i < array_size; i++)
|
||||
printf("%s ", arr[i]);
|
||||
|
||||
puts("");
|
||||
}
|
||||
|
||||
static void print_mismatch(int position)
|
||||
{
|
||||
for (int i = 0; i < position; i++)
|
||||
fputs(" ", stdout);
|
||||
|
||||
puts("^");
|
||||
|
||||
for (int i = 0; i < position; i++)
|
||||
fputs(" ", stdout);
|
||||
|
||||
puts("sort mismatch");
|
||||
}
|
||||
|
||||
static int assert_sort(int test_id, int array_size, char **a, char **b)
|
||||
{
|
||||
sorter_insertion_sort(a, array_size);
|
||||
|
||||
int result = cmp_arrays(array_size, a, b);
|
||||
|
||||
if (result == -1) {
|
||||
printf("[TEST#%02d] OK\r", test_id);
|
||||
return 0;
|
||||
} else {
|
||||
printf("\n[TEST#%02d] FAILED!\n", test_id);
|
||||
printf("Case details:\n");
|
||||
printf("Str1: %s\n", a);
|
||||
printf("Str2: %s\n", b);
|
||||
printf("Mismatch: %d expected, %d retrieved\n", target_length_diff, len_diff);
|
||||
printf("Retrieved array: ");
|
||||
print_array(array_size, a);
|
||||
|
||||
printf("Expected array: ");
|
||||
print_array(array_size, b);
|
||||
|
||||
print_mismatch(result + 17);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int success_tests_counter = 0;
|
||||
int failed_tests_counter = 0;
|
||||
|
||||
int f = open("test/testcases_len", O_RDONLY);
|
||||
int f;
|
||||
|
||||
if (argc == 2)
|
||||
f = open(argv[1], O_RDONLY);
|
||||
else
|
||||
f = open("test/testcases_sort_official", O_RDONLY);
|
||||
|
||||
if (f < 0)
|
||||
return 1;
|
||||
|
@ -126,16 +213,20 @@ int main(void)
|
|||
remaining_buffer_length = read(f, cmd, 1024);
|
||||
|
||||
while (remaining_buffer_length) {
|
||||
char str_a[1024], str_b[1024];
|
||||
int target_length_diff;
|
||||
char **a, **b;
|
||||
int array_size;
|
||||
|
||||
int bytes_read = parse_case(cmd, &target_length_diff, str_a, str_b);
|
||||
int bytes_read = parse_case(cmd, &array_size, &a, &b);
|
||||
|
||||
if (assert_length(success_tests_counter + failed_tests_counter + 1, target_length_diff, str_a, str_b))
|
||||
if (assert_sort(success_tests_counter + failed_tests_counter + 1, array_size, a, b))
|
||||
failed_tests_counter++;
|
||||
else
|
||||
success_tests_counter++;
|
||||
|
||||
// clean up before next iteration
|
||||
destroy_array(a, array_size);
|
||||
destroy_array(b, array_size);
|
||||
|
||||
if (remaining_buffer_length == 1024)
|
||||
remaining_buffer_length = read_more(f, cmd, bytes_read);
|
||||
else
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
3 banana,apple,egg apple,banana,egg
|
||||
4 banana,test,apple,egg apple,banana,egg,test
|
|
@ -0,0 +1,5 @@
|
|||
5 banana,apple,cherry,date,elderberry apple,banana,cherry,date,elderberry
|
||||
1 hello hello
|
||||
3 alpha,beta,gamma alpha,beta,gamma
|
||||
3 gamma,beta,alpha alpha,beta,gamma
|
||||
8 hello,world,foo,bar,baz,qux,quux,corge bar,baz,corge,foo,hello,quux,qux,world
|
|
@ -0,0 +1 @@
|
|||
3 1,2,3 2,1,3
|
Loading…
Reference in New Issue