Advertisement
gur111

Mtm Spring 2020 Ex1 Dry Pt1 Tester

Apr 9th, 2020
777
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.87 KB | None | 0 0
  1. #include <assert.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <time.h>
  5.  
  6. #include "q1.h"
  7.  
  8. #define LIST_AS_STR_MAX_SIZE 3000
  9. #define NODE_AS_STR_MAX_SIZE 50
  10.  
  11. Node copyNode(Node n) {
  12.     Node newNode = malloc(sizeof(*n));
  13.     newNode->x = n->x;
  14.     return newNode;
  15. }
  16.  
  17. void freeListSol(Node list) {
  18.     if (list == NULL) {
  19.         return;
  20.     }
  21.     Node prev;
  22.     while (list) {
  23.         prev = list;
  24.         list = list->next;
  25.         free(prev);
  26.     }
  27. }
  28.  
  29. int getListLength(Node list) {
  30.     int count = 0;
  31.  
  32.     while (list) {
  33.         count++;
  34.         list = list->next;
  35.     }
  36.     return count;
  37. }
  38.  
  39. bool isListSorted(Node list) {
  40.     if (list == NULL) {
  41.         return true;
  42.     }
  43.  
  44.     int prev = list->x;
  45.     list = list->next;
  46.  
  47.     while (list != NULL) {
  48.         if (prev > list->x) {
  49.             return false;
  50.         }
  51.         prev = list->x;
  52.         list = list->next;
  53.     }
  54.  
  55.     return true;
  56. }
  57.  
  58. Node copyList(Node list) {
  59.     Node head = malloc(sizeof(*head)), curr = head;
  60.     head->next = NULL;
  61.  
  62.     while (list) {
  63.         curr->next = malloc(sizeof(*curr));
  64.         curr = curr->next;
  65.         curr->next = NULL;
  66.         curr->x = list->x;
  67.         list = list->next;
  68.     }
  69.  
  70.     if (curr == head) {
  71.         free(head);
  72.         return NULL;
  73.     }
  74.     curr = head->next;
  75.     free(head);
  76.  
  77.     return curr;
  78. }
  79.  
  80. Node sortedMergeSol(Node a, Node b) {
  81.     Node result = NULL; /* Base cases */
  82.     if (a == NULL)
  83.         return copyList(b);
  84.     else if (b == NULL)
  85.         return copyList(a); /* Pick either a or b, and recur */
  86.     if (a->x <= b->x) {
  87.         result = copyNode(a);
  88.         result->next = sortedMergeSol(a->next, b);
  89.     } else {
  90.         result = copyNode(b);
  91.         result->next = sortedMergeSol(a, b->next);
  92.     }
  93.     return (result);
  94. }
  95.  
  96. char *listToString(Node list) {
  97.     char *str = malloc(sizeof(char) * LIST_AS_STR_MAX_SIZE);
  98.     assert(str != NULL);
  99.     str[0] = '\0';
  100.     char buff[NODE_AS_STR_MAX_SIZE];
  101.  
  102.     while (list != NULL) {
  103.         sprintf(buff, "%d->", list->x);
  104.         strncat(str, buff, NODE_AS_STR_MAX_SIZE);
  105.         list = list->next;
  106.     }
  107.     strcat(str, "NULL");
  108.     return str;
  109. }
  110.  
  111. bool areListsEqual(Node list1, Node list2) {
  112.     while (list1 != NULL || list2 != NULL) {
  113.         if (list1 == NULL || list2 == NULL || list1->x != list2->x) {
  114.             return false;
  115.         }
  116.         list1 = list1->next;
  117.         list2 = list2->next;
  118.     }
  119.     return true;
  120. }
  121.  
  122. bool testOnce(int test_num) {
  123.     Node lists[] = {malloc(sizeof(*lists[0])), malloc(sizeof(*lists[1]))};
  124.     for (int i = 0; i < 2; i++) {
  125.         Node curr = lists[i];
  126.         curr->x = rand() % 100 - 40;
  127.         int count = rand() % 20;  // Random length for the list
  128.         int tmp_value;
  129.         while (count > 0) {
  130.             curr->next = malloc(sizeof(*lists[i]));
  131.             // tmp_value = rand() % 1;
  132.             tmp_value = rand() % 400;
  133.             tmp_value = tmp_value ? (rand() % 5) : (-1);
  134.             curr->next->x =
  135.                 curr->x +
  136.                 tmp_value;  // Generate a series which is likely rising
  137.             curr = curr->next;
  138.             count--;
  139.         }
  140.         curr->next = NULL;
  141.         curr = lists[i];
  142.         lists[i] = lists[i]->next;
  143.         free(curr);
  144.     }
  145.  
  146.     char *list1_before = listToString(lists[0]);
  147.     char *list2_before = listToString(lists[1]);
  148.     // printf("List1 before:\n\t%s\n", list1_before);
  149.  
  150.     Node merged_actual = NULL, merged_expected = NULL;
  151.     Node *merge_actual_address = (rand() % 10) ? &merged_actual : NULL;
  152.     ErrorCode merge_status =
  153.         mergeSortedLists(lists[0], lists[1], merge_actual_address);
  154.     char *list1_after = listToString(lists[0]);
  155.     char *list2_after = listToString(lists[1]);
  156.     if (merge_actual_address && lists[0] && lists[1] &&
  157.         isListSorted(lists[0]) && isListSorted(lists[1])) {
  158.         merged_expected = sortedMergeSol(lists[0], lists[1]);
  159.     }
  160.  
  161.     bool status = true;
  162.     if (lists[0] == NULL || lists[1] == NULL) {
  163.         if (merge_status != EMPTY_LIST) {
  164.             printf("Extecped status EMPTY_LIST (%d) but got %d\n", EMPTY_LIST,
  165.                    merge_status);
  166.             status = false;
  167.         }
  168.     } else if (!isListSorted(lists[0]) || !isListSorted(lists[1])) {
  169.         if (merge_status != UNSORTED_LIST) {
  170.             printf("Extecped status UNSORTED_LIST (%d) but got %d\n",
  171.                    UNSORTED_LIST, merge_status);
  172.             status = false;
  173.         }
  174.     } else if (merge_actual_address == NULL) {
  175.         if (merge_status != NULL_ARGUMENT) {
  176.             printf("Extecped status NULL_ARGUMENT (%d) but got %d\n",
  177.                    NULL_ARGUMENT, merge_status);
  178.             status = false;
  179.         }
  180.     } else if (merge_status == MEMORY_ERROR) {
  181.         if (merged_actual != NULL) {
  182.             printf(
  183.                 "Extecped merged_actual (MEMORY_ERROR) to be NULL but got %p\n",
  184.                 (void *)merged_actual);
  185.             status = false;
  186.         }
  187.     } else {
  188.         status = status && areListsEqual(merged_actual, merged_expected);
  189.     }
  190.     char *merged_expected_str = NULL, *merged_actual_str = NULL;
  191.  
  192.     if (strcmp(list1_before, list1_after) ||
  193.         strcmp(list2_before, list2_after) || !status) {
  194.         fprintf(stderr, "\n\n======= Test #%d Failed ========\n", test_num);
  195.  
  196.         fprintf(stderr, "List1 before:\n");
  197.         fprintf(stderr, "\t%s\n", list1_before);
  198.         fprintf(stderr, "List2 before:\n");
  199.         fprintf(stderr, "\t%s\n", list2_before);
  200.  
  201.         fprintf(stderr, "List1 after:\n");
  202.         fprintf(stderr, "\t%s\n", list1_after);
  203.         fprintf(stderr, "List2 after:\n");
  204.         fprintf(stderr, "\t%s\n", list2_after);
  205.  
  206.         fprintf(stderr, "Merged expected:\n");
  207.         merged_expected_str = listToString(merged_expected);
  208.         fprintf(stderr, "\t%s\n", merged_expected_str);
  209.         fprintf(stderr, "Merged actual:\n");
  210.         merged_actual_str = listToString(merged_actual);
  211.         fprintf(stderr, "\t%s\n", merged_actual_str);
  212.         status = false;
  213.     }
  214.     free(list1_before);
  215.     free(list1_after);
  216.     free(list2_before);
  217.     free(list2_after);
  218.     free(merged_expected_str);
  219.     free(merged_actual_str);
  220.  
  221.     freeListSol(merged_actual);
  222.     freeListSol(merged_expected);
  223.     freeListSol(lists[0]);
  224.     freeListSol(lists[1]);
  225.     return status;
  226. }
  227.  
  228. void printUsage(char *name) { printf("Usage:\n%s [NUM_OF_TESTS]\n", name); }
  229.  
  230. int main(int argc, char **argv) {
  231.     int count = 0, failures = 0;
  232.  
  233.     if (argc == 2 && sscanf(argv[1], "%d", &count) == 1) {
  234.         printf("Running %d random tests...\n", count);
  235.     } else {
  236.         printUsage(argv[0]);
  237.         return 1;
  238.     }
  239.     srand(time(0));
  240.  
  241.     for (int i = 0; i < count; i++) {
  242.         if (!testOnce(i)) {
  243.             failures++;
  244.         }
  245.     }
  246.  
  247.     printf("%d failures out of %d tests\n", failures, count);
  248. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement