From a81141fb063522512487820fcf62dea6f7339b2c Mon Sep 17 00:00:00 2001 From: shobayoeniolasi99076 Date: Sun, 31 May 2026 09:41:27 +0200 Subject: [PATCH] =?UTF-8?q?Sortierung+Bin=C3=A4rbaum?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bintree.c | 180 +++++++++++++-- bintree.o | Bin 0 -> 8344 bytes bintree_tests | Bin 0 -> 72536 bytes doble_initial | Bin 0 -> 22432 bytes highscores.txt | 1 + makefile | 19 +- numbers.c | 139 ++++++++++- numbers.o | Bin 0 -> 8368 bytes runTest_bintree | Bin 0 -> 72512 bytes runTest_numbers | Bin 0 -> 71384 bytes stack.c | 94 ++++++-- stack.h | 7 +- stack.o | Bin 0 -> 5336 bytes test_bintree.c | 592 +++++++++++++++++++++++++++++++++++++++++++++++ test_debug | Bin 0 -> 23712 bytes test_debug.c | 61 +++++ test_numbers | Bin 0 -> 71384 bytes test_numbers.c | 599 ++++++++++++++++++++++++++++++++++++++++++++++++ unity.o | Bin 0 -> 64248 bytes 19 files changed, 1657 insertions(+), 35 deletions(-) create mode 100644 bintree.o create mode 100755 bintree_tests create mode 100755 doble_initial create mode 100644 numbers.o create mode 100755 runTest_bintree create mode 100755 runTest_numbers create mode 100644 stack.o create mode 100644 test_bintree.c create mode 100755 test_debug create mode 100644 test_debug.c create mode 100755 test_numbers create mode 100644 test_numbers.c create mode 100644 unity.o diff --git a/bintree.c b/bintree.c index 5cf82a9..ecf5a5f 100644 --- a/bintree.c +++ b/bintree.c @@ -2,35 +2,183 @@ #include "stack.h" #include "bintree.h" -//TODO: binären Suchbaum implementieren -/* * `addToTree`: fügt ein neues Element in den Baum ein (rekursiv), - * `clearTree`: gibt den gesamten Baum frei (rekursiv), - * `treeSize`: zählt die Knoten im Baum (rekursiv), - * `nextTreeData`: Traversierung mit Hilfe des zuvor implementierten Stacks. */ +// Global static stack used for in-order tree traversal in nextTreeData() +// This is needed because nextTreeData() follows strtok-like usage where consecutive calls +// with NULL argument continue the iteration +static StackNode *traversalStack = NULL; -// Adds a copy of data's pointer destination to the tree using compareFct for ordering. Accepts duplicates -// if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added). +// Adds a copy of data's pointer destination to the tree using compareFct for ordering. +// Accepts duplicates if isDuplicate is NULL, otherwise ignores duplicates and sets isDuplicate to 1 (or to 0 if a new entry is added). +// Parameters: +// - root: pointer to the root of the tree (can be NULL for first insertion) +// - data: pointer to the data to be inserted +// - dataSize: size in bytes of the data to allocate and copy +// - compareFct: comparison function that returns <0 if arg10 if arg1>arg2 +// - isDuplicate: pointer to int flag (NULL to allow duplicates, non-NULL to detect and reject duplicates) +// Returns: pointer to the root of the modified tree TreeNode *addToTree(TreeNode *root, const void *data, size_t dataSize, CompareFctType compareFct, int *isDuplicate) { - + // Base case: if root is NULL, we've found the insertion point + // Create a new tree node here + if (root == NULL) + { + // Allocate memory for the new tree node + TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode)); + if (newNode == NULL) + { + return NULL; // Allocation failed + } + + // Allocate memory for a copy of the data + newNode->data = malloc(dataSize); + if (newNode->data == NULL) + { + free(newNode); // Free the node if data allocation failed + return NULL; + } + + // Copy the data into the newly allocated space + memcpy(newNode->data, data, dataSize); + + // Initialize the left and right child pointers to NULL + newNode->left = NULL; + newNode->right = NULL; + + // If isDuplicate is not NULL, set it to 0 to indicate a new entry was added + if (isDuplicate != NULL) + { + *isDuplicate = 0; + } + + // Return the newly created node + return newNode; + } + + // Recursive case: compare the data with the root's data to determine where to insert + int comparisonResult = compareFct(data, root->data); + + // If data is less than root->data, insert into the left subtree + if (comparisonResult < 0) + { + root->left = addToTree(root->left, data, dataSize, compareFct, isDuplicate); + } + // If data is greater than root->data, insert into the right subtree + else if (comparisonResult > 0) + { + root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate); + } + // If data equals root->data, we have a duplicate + else + { + // If isDuplicate is not NULL, set it to 1 to indicate a duplicate was found + if (isDuplicate != NULL) + { + *isDuplicate = 1; + } + // If isDuplicate is NULL, we allow the duplicate to be inserted again (in either subtree) + // For standard BST behavior, we typically insert duplicates in the right subtree + else + { + root->right = addToTree(root->right, data, dataSize, compareFct, isDuplicate); + } + } + + // Return the root (possibly with new subtrees added) + return root; } -// Iterates over the tree given by root. Follows the usage of strtok. If tree is NULL, the next entry of the last tree given is returned in ordering direction. -// Use your implementation of a stack to organize the iterator. Push the root node and all left nodes first. On returning the next element, -// push the top node and push all its left nodes. +// Iterates over the tree given by root in in-order traversal (Left, Root, Right). +// Follows the usage pattern of strtok: first call with root pointer, subsequent calls with NULL to get next element. +// Uses a static stack to maintain traversal state between calls. +// Parameters: +// - root: pointer to tree root for first call, NULL for subsequent calls +// Returns: pointer to the data of the next node in in-order sequence, or NULL when traversal is complete void *nextTreeData(TreeNode *root) { - + // If root is not NULL, we're starting a new traversal + if (root != NULL) + { + // Clear any existing traversal state + clearStack(traversalStack); + traversalStack = NULL; + + // Initialize the traversal by pushing root and all its left descendants + // In in-order traversal, we always visit left children first + TreeNode *current = root; + while (current != NULL) + { + // Push current node onto the stack + traversalStack = push(traversalStack, current); + // Move to the left child + current = current->left; + } + } + + // If the traversal stack is empty, we've visited all nodes + if (traversalStack == NULL) + { + return NULL; + } + + // Pop the next node from the stack + TreeNode *nextNode = (TreeNode *)top(traversalStack); + traversalStack = pop(traversalStack); + + // If the popped node has a right child, push it and all its left descendants + // This handles the "Root, Right" part of in-order traversal + if (nextNode->right != NULL) + { + TreeNode *current = nextNode->right; + while (current != NULL) + { + // Push the current node + traversalStack = push(traversalStack, current); + // Move to the left child of the right subtree + current = current->left; + } + } + + // Return the data of the node we just processed + return nextNode->data; } -// Releases all memory resources (including data copies). +// Releases all memory resources used by the tree. +// Recursively frees all nodes and their data copies. +// Parameters: +// - root: pointer to the root of the tree to clear +// Returns: void void clearTree(TreeNode *root) { - + // Base case: if root is NULL, there's nothing to free + if (root == NULL) + { + return; + } + + // Recursive case: first recursively clear the left subtree + clearTree(root->left); + + // Then recursively clear the right subtree + clearTree(root->right); + + // Finally, free the data and the node itself + free(root->data); + free(root); } -// Returns the number of entries in the tree given by root. +// Returns the number of entries (nodes) in the tree. +// Recursively counts nodes in the left and right subtrees. +// Parameters: +// - root: pointer to the root of the tree +// Returns: unsigned int representing the total number of nodes in the tree unsigned int treeSize(const TreeNode *root) { - + // Base case: if root is NULL, there are no nodes + if (root == NULL) + { + return 0; + } + + // Recursive case: count 1 for the current node, plus all nodes in left and right subtrees + return 1 + treeSize(root->left) + treeSize(root->right); } \ No newline at end of file diff --git a/bintree.o b/bintree.o new file mode 100644 index 0000000000000000000000000000000000000000..a1a30ce5a0c7230283b8775624fdcfcdb159424b GIT binary patch literal 8344 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 Xvy3^-Wgo{MQlR}@cjZq?r!4;$pvK>H literal 0 HcmV?d00001 diff --git a/bintree_tests b/bintree_tests new file mode 100755 index 0000000000000000000000000000000000000000..a8e151a895b9c1962dd16cfc1a7e9cdc604bb652 GIT binary patch literal 72536 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 A9{>OV literal 0 HcmV?d00001 diff --git a/doble_initial b/doble_initial new file mode 100755 index 0000000000000000000000000000000000000000..d60f79b439492b2397c3b81ea9bee8c76c7dcba2 GIT binary patch literal 22432 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 if a > b +// This function is passed to addToTree to determine ordering +int compareUnsignedInts(const void *a, const void *b) +{ + unsigned int valA = *(const unsigned int *)a; + unsigned int valB = *(const unsigned int *)b; + + // Simple subtraction works for unsigned integers in this case + // (Note: in general subtraction can overflow, but our range is small) + if (valA < valB) return -1; + if (valA > valB) return 1; + return 0; +} + // Returns len random numbers between 1 and 2x len in random order which are all different, except for two entries. // Returns NULL on errors. Use your implementation of the binary search tree to check for possible duplicates while // creating random numbers. +// +// Algorithm: +// 1. Generate len-1 unique random numbers using the BST for duplicate detection +// 2. Randomly duplicate one of those numbers by inserting it at a random position +// 3. Final array has len entries with exactly one value appearing twice unsigned int *createNumbers(unsigned int len) { + // Step 1: Validate input - we need at least 2 elements to create a duplicate + if (len < 2) + { + return NULL; + } + + // Step 2: Allocate memory for the final array (len elements total) + unsigned int *numbers = (unsigned int *)malloc(len * sizeof(unsigned int)); + if (numbers == NULL) + { + return NULL; + } + + // Step 3: Create binary search tree to track generated numbers and prevent accidental duplicates + // Note: Random seed should be initialized once in main() with srand(time(NULL)) + // Calling srand() here would reset the seed each time, reducing randomness + TreeNode *usedNumbers = NULL; + + // Step 4: Generate len-1 unique random numbers (we'll add one duplicate later) + unsigned int arrayIndex = 0; + + while (arrayIndex < len - 1) + { + // Generate random number in range [1, 2×len] + unsigned int randomNumber = (rand() % (2 * len)) + 1; + + // Check if this number was already generated + int isDuplicate = 0; + usedNumbers = addToTree(usedNumbers, &randomNumber, sizeof(unsigned int), compareUnsignedInts, &isDuplicate); + + if (usedNumbers == NULL) + { + free(numbers); + return NULL; + } + + // If new number, add to result array; if duplicate, retry + if (isDuplicate == 0) + { + numbers[arrayIndex] = randomNumber; + arrayIndex++; + } + } + + // Step 5: Pick a random value from our generated numbers to duplicate + unsigned int indexToDuplicate = rand() % (len - 1); + unsigned int valueToDuplicate = numbers[indexToDuplicate]; + + // Step 6: Pick a random position to insert the duplicate (anywhere in the array) + unsigned int insertPos = rand() % len; + + // Step 7: Shift elements right to make room for the duplicate + for (unsigned int i = len - 1; i > insertPos; i--) + { + numbers[i] = numbers[i - 1]; + } + + // Step 8: Insert the duplicate at the chosen position + numbers[insertPos] = valueToDuplicate; + + // Step 9: Clean up the binary search tree (we don't need it anymore) + clearTree(usedNumbers); + + // Return the array with len elements (len-1 unique + 1 duplicate) + return numbers; +} +// Comparison function for qsort to sort unsigned integers in ascending order +// Returns: <0 if a < b, 0 if a == b, >0 if a > b +static int compareUnsigned(const void *a, const void *b) +{ + unsigned int valA = *(const unsigned int *)a; + unsigned int valB = *(const unsigned int *)b; + + if (valA < valB) return -1; + if (valA > valB) return 1; + return 0; } // Returns only the only number in numbers which is present twice. Returns zero on errors. -unsigned int getDuplicate(const unsigned int numbers[], unsigned int len) +// +// Algorithm: +// 1. Create a copy of the array to avoid modifying the input +// 2. Sort the copy using qsort() +// 3. Compare adjacent elements to find the duplicate +// 4. Return the duplicate value, or 0 on error +unsigned int getDuplicate(const unsigned int *numbers, unsigned int len) { - + // Step 1: Input validation - need at least 2 elements to have a duplicate + if (numbers == NULL || len < 2) + { + return 0; + } + + // Step 2: Create a copy of the array to sort (we don't modify the input) + unsigned int *sorted = (unsigned int *)malloc(len * sizeof(unsigned int)); + if (sorted == NULL) + { + return 0; + } + + // Step 3: Copy the array + memcpy(sorted, numbers, len * sizeof(unsigned int)); + + // Step 4: Sort the copy + qsort(sorted, len, sizeof(unsigned int), compareUnsigned); + + // Step 5: Compare adjacent elements to find the duplicate + for (unsigned int i = 0; i < len - 1; i++) + { + if (sorted[i] == sorted[i + 1]) + { + // Found the duplicate! + unsigned int result = sorted[i]; + free(sorted); + return result; + } + } + + // Step 6: No duplicate found (should not happen if input is valid) + free(sorted); + return 0; } \ No newline at end of file diff --git a/numbers.o b/numbers.o new file mode 100644 index 0000000000000000000000000000000000000000..b6079d09fe308b438109cde67b595cb005e91125 GIT binary patch literal 8368 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 G{=WfXjmta$ literal 0 HcmV?d00001 diff --git a/runTest_bintree b/runTest_bintree new file mode 100755 index 0000000000000000000000000000000000000000..32091ce117c447b06915e4b064e3764cfde3d92f GIT binary patch literal 72512 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 z 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 F`d>(o#V-H= literal 0 HcmV?d00001 diff --git a/runTest_numbers b/runTest_numbers new file mode 100755 index 0000000000000000000000000000000000000000..545ec6cb7e174e4c11df3335ef5406570a1c54f3 GIT binary patch literal 71384 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

-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 NRj_@*Zq0XAF@8oJTG#x(-uK!~;ltrj4|2BKFg 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 #include "stack.h" -//TODO: grundlegende Stackfunktionen implementieren: -/* * `push`: legt ein Element oben auf den Stack, - * `pop`: entfernt das oberste Element, - * `top`: liefert das oberste Element zurück, - * `clearStack`: gibt den gesamten Speicher frei. */ - // Pushes data as pointer onto the stack. +// Parameters: +// - stack: pointer to the current top of the stack (can be NULL if stack is empty) +// - data: void pointer to the data to be pushed onto the stack +// Returns: pointer to the new top of the stack (the newly created node) +// Note: The function allocates memory for a new StackNode, sets its data pointer +// and links it to the previous top, making it the new top of the stack. StackNode *push(StackNode *stack, void *data) { - + // Allocate memory for a new StackNode + StackNode *newNode = (StackNode *)malloc(sizeof(StackNode)); + + // Check if memory allocation was successful + if (newNode == NULL) + { + return NULL; // Return NULL if allocation failed + } + + // Store the data pointer in the new node + newNode->data = data; + + // Link the new node to the previous top of the stack + // If stack was NULL (empty), newNode->next will be NULL + // If stack was not NULL, newNode->next points to the old top + newNode->next = stack; + + // Return the new node, which is now the new top of the stack + return newNode; } -// Deletes the top element of the stack (latest added element) and releases its memory. (Pointer to data has to be -// freed by caller.) +// Deletes the top element of the stack (latest added element) and releases its memory. +// Parameters: +// - stack: pointer to the current top of the stack +// Returns: pointer to the new top of the stack (the second element, or NULL if stack becomes empty) +// Note: This function only frees the StackNode structure itself. The caller is responsible +// for freeing the data that the node was pointing to, if that data was dynamically allocated. StackNode *pop(StackNode *stack) { - + // Check if the stack is empty + if (stack == NULL) + { + return NULL; // Cannot pop from an empty stack + } + + // Save a pointer to the next node (which will become the new top) + StackNode *newTop = stack->next; + + // Free the memory of the current top node + // NOTE: We do NOT free stack->data here because the caller may still need it + // or may be responsible for freeing it themselves + free(stack); + + // Return the new top of the stack (or NULL if the stack is now empty) + return newTop; } -// Returns the data of the top element. +// Returns the data of the top element without removing it from the stack. +// Parameters: +// - stack: pointer to the current top of the stack +// Returns: void pointer to the data of the top element, or NULL if stack is empty +// Note: This is a "peek" operation - it looks at the top without removing it. void *top(StackNode *stack) { - + // Check if the stack is empty + if (stack == NULL) + { + return NULL; // Return NULL if stack is empty + } + + // Return the data pointer stored in the top node + // The caller can then use this pointer to access the actual data + return stack->data; } -// Clears stack and releases all memory. +// Clears the entire stack and releases all memory used by the StackNodes. +// Parameters: +// - stack: pointer to the current top of the stack +// Returns: void +// Note: This function only frees the StackNode structures. The caller is responsible +// for freeing any dynamically allocated data that the nodes were pointing to, +// unless that is done elsewhere in the program before calling clearStack. void clearStack(StackNode *stack) { - + // Base case: if the stack is NULL (empty), we're done + if (stack == NULL) + { + return; + } + + // Recursive case: first, recursively clear all the nodes below this one + // This processes the stack from top to bottom + clearStack(stack->next); + + // After recursively clearing all deeper nodes, free the current node + free(stack); } \ No newline at end of file diff --git a/stack.h b/stack.h index f7d542d..77993da 100644 --- a/stack.h +++ b/stack.h @@ -7,7 +7,12 @@ The latest element is taken from the stack. */ #include -//TODO: passenden Datentyp als struct anlegen +// Stack node structure: each node contains data and a pointer to the next node +typedef struct stackNode +{ + void *data; + struct stackNode *next; +} StackNode; // Pushes data as pointer onto the stack. StackNode *push(StackNode *stack, void *data); diff --git a/stack.o b/stack.o new file mode 100644 index 0000000000000000000000000000000000000000..5676a8c7bba2d9e95502f8cb60bd492b4f795081 GIT binary patch literal 5336 zcmbtYU2GiH6~1@Y6R$J&dX1Za>onO=+88OjCO@PhA;IAMtP4eMsHGHvoY~#+?kc-8 ztJxW1rwK%)R9Ja&;H9VtA%%w^(N?@w6;)dCP(>~3TcwH@q*5tTc!}Bv3P|*vd(Roq zUT{q|(}3LsY&J}Ix}Nd(G#7Ui2C zZU}by;;n?b4Sa5uugqjsP?T5ytOx1ku3qdNa!`*Wo==C*L$2B_+OF*wcRe1T+ z4{t(2Y$3Dw27~zcPUhs+3<^E%)08H&$}u}&H~k2xHrlw;k))+uV89E1HYczxMFv^+VS|fjj-d2PW1-)(MQ2Qss z`w+?DLoTQsP&|kaX!6ZGyu5|t!ZsydZHR$igE|@o9U&hdR8i3m?Yp`I)(K`kzLi<| z4ict@QRnt(LijlorY1Gvw8~`+%k z#+^0kT$P(LJ0^FG$$JL#_rfQkv0&y5K^zFTd0b|4j&sPt5hR3jwqiJ?V)WsXd~8Ai z_9M=&iAN{UXQUUL8`p3yfg#qe2^@6hz6**ms!UlOch|(+xHg_w#(aOHW{&j+W#)wm zDCTY~sH(YI3QEF9dg3P_2yesBhIxsTNlN);ZUj60{O|)|hYkk11@h`^=W4?F*YJ-+E4GX?o0Wab&ushU zSL~t8^51Ql87f#7B+&}|dOp? zrH2Z|b`<;Gk-F!5VY3RV8&(@fmJc2%9@t+f)(gd@U}>opxV2)?iJF1mJyL8fo}8Us zY=g<|uK3kP82CZlEyn)2re7;YZl&dQ!Pv#&ik&csylNDL#cl+S7*HFkEw|fXGXw@h zb*WcB?}b6J={KWd$F0?xe!W;}M%^QBt0k5~&lA3P?&+ZB2^CPNH}84t^@8-kst$@+ zZMfljp_B$Oe*%lU=0>iLh~?`xf-oxd1fk+8PABd*bP_rp<&C^Hq#9Hq&*ex=H-fe| z9amyMil>hSXXCc#N8WVQDEO87bkko7raPf~Hfn-Jse9dcsqR+1eL8fh`b|Pi$K4R3 zR$DRG3*xD|B|W}Et<|iQ8bZJaK2(@mP|4CvDel*~?|+a0fs-7MN8ILNR^fX3BVuYJ zhyGje!zRz45^^~&Cx-{KYp`6l0fs+pYTrAa%m2cf9ob|Z0}pNE-Bk5#?<%w6KBwt= zn`Zm7>-Gy|SDQcE18pbMh7MQrfVlJZ1_J<@zBdWP)giZmlF_GYA6%V(eQ!|!3XEdZcD`*Ce?AMEG9o%~lR5Fds26aF6Ie6S|-NUZ~!^LRq4 zMT%!@YWo51w~3E)1>fbXuXTGVh2zoB_}@}ER)g`6Q+V2+cXX_DdL!maB915N_lXau zn`(&T1?I3;#U%BNlPY$Qfb%8U&q1Ch9R1U?;y?<=ae0CrGw>f{Kxj|uPH>*2ic<#u z1M>f=fj>+583R`rBf#ng-X?$Fz+WZ&oPqBp{6zyFBmA;~zexC+fj>p~n+E;{;lDBP zDZ+nm;GdEHk%7NP{+}8+f7jcDqZ@ulp4S%fxc>hoznz4$Kd+C2ckw@E`1AT}-o^i% zfgdOR6$4)(9rsdf*rn&;HN&6tf8W5l{x=N#j*6<+2#Qz--qTU%J;NLq_Xlj~kLzd_ z6==N980UHOkTxg&S4e-@z+Wf*kb(b-^v4YR8tHS?n|T%p$C{<oU z&htl8{poTZZo9t`eYkTM^@E7jQjXZf@tA79v;xnsHYI{=Y<-F_kZ{!NHv^) z7&ASG(eQvd5Q5N5csF1e^Z(`J{%^(vC>j4F!)T~t5BTfwuwgV*v2YjuZcGXquVbxk9BUp7{qmou1DW}lKjv=c-vrFe2_W$tjsFfR zsb>1tz}9d4OEms<;^O#NQgi$mFpSB0f~XrE@^2XfvdaA>@b1Tdixxz(Z%|m~aldvK z{twlETh{kiq9?Ut{u{(+JNF&pv(7#9SbrA;bWQJ-Xk&f>l~m*UG4v-8Fs8|0qw#;q zj?|m{4*>7?{if(bbB1{M{qTP)%;)vrZ)~JYk>fnQF#f%Qkjckw#$5XViDlY +#include + +/* ============================================================================ + * UNIT TESTS FOR BINARY SEARCH TREE IMPLEMENTATION (Binärer Suchbaum) + * + * This test suite covers all four functions: + * - addToTree(): Insert elements maintaining BST ordering + * - clearTree(): Free all memory in the tree + * - treeSize(): Count nodes in the tree + * - nextTreeData(): In-order traversal using stack + * ========================================================================== */ + +// ============================================================================ +// HELPER FUNCTIONS FOR TESTING +// ============================================================================ + +// Comparison function for integers (ascending order: smaller values first) +// Returns: <0 if a < b, 0 if a == b, >0 if a > b +int compareIntegers(const void *a, const void *b) +{ + int valA = *(const int *)a; + int valB = *(const int *)b; + return valA - valB; +} + +// Comparison function for strings (alphabetical order) +int compareStrings(const void *a, const void *b) +{ + return strcmp((const char *)a, (const char *)b); +} + +// ============================================================================ +// TEST SETUP AND TEARDOWN +// ============================================================================ + +void setUp(void) +{ + // Perform any setup needed before each test +} + +void tearDown(void) +{ + // Perform any cleanup needed after each test + // Individual tests are responsible for clearing their trees +} + +// ============================================================================ +// TEST SUITE 1: addToTree() - Inserting Elements +// ============================================================================ + +// Test 1.1: Insert a single element into an empty tree (NULL root) +void test_addToTree_SingleElement(void) +{ + TreeNode *root = NULL; + int value = 42; + int isDuplicate = 0; + + // Insert the first element into an empty tree + root = addToTree(root, &value, sizeof(int), compareIntegers, &isDuplicate); + + // Verify the root is not NULL + TEST_ASSERT_NOT_NULL(root); + + // Verify the data was copied correctly + TEST_ASSERT_EQUAL_INT(42, *(int *)root->data); + + // Verify isDuplicate was set to 0 (new entry added) + TEST_ASSERT_EQUAL_INT(0, isDuplicate); + + // Verify the node has no children + TEST_ASSERT_NULL(root->left); + TEST_ASSERT_NULL(root->right); + + // Cleanup + clearTree(root); +} + +// Test 1.2: Insert multiple elements in ascending order +void test_addToTree_AscendingOrder(void) +{ + TreeNode *root = NULL; + int values[] = {10, 20, 30}; + + // Insert values in ascending order + for (int i = 0; i < 3; i++) + { + root = addToTree(root, &values[i], sizeof(int), compareIntegers, NULL); + } + + // Verify root value + TEST_ASSERT_EQUAL_INT(10, *(int *)root->data); + + // Verify each value goes to the right (since they're ascending) + TEST_ASSERT_NULL(root->left); + TEST_ASSERT_NOT_NULL(root->right); + TEST_ASSERT_EQUAL_INT(20, *(int *)root->right->data); + + TEST_ASSERT_NULL(root->right->left); + TEST_ASSERT_NOT_NULL(root->right->right); + TEST_ASSERT_EQUAL_INT(30, *(int *)root->right->right->data); + + // Cleanup + clearTree(root); +} + +// Test 1.3: Insert multiple elements in descending order +void test_addToTree_DescendingOrder(void) +{ + TreeNode *root = NULL; + int values[] = {30, 20, 10}; + + // Insert values in descending order + for (int i = 0; i < 3; i++) + { + root = addToTree(root, &values[i], sizeof(int), compareIntegers, NULL); + } + + // Verify root value + TEST_ASSERT_EQUAL_INT(30, *(int *)root->data); + + // Verify each value goes to the left (since they're descending) + TEST_ASSERT_NULL(root->right); + TEST_ASSERT_NOT_NULL(root->left); + TEST_ASSERT_EQUAL_INT(20, *(int *)root->left->data); + + TEST_ASSERT_NULL(root->left->right); + TEST_ASSERT_NOT_NULL(root->left->left); + TEST_ASSERT_EQUAL_INT(10, *(int *)root->left->left->data); + + // Cleanup + clearTree(root); +} + +// Test 1.4: Insert elements in balanced order (creating a balanced tree) +void test_addToTree_BalancedTree(void) +{ + TreeNode *root = NULL; + int values[] = {20, 10, 30, 5, 15, 25, 35}; + + // Insert values to create a somewhat balanced tree + for (int i = 0; i < 7; i++) + { + root = addToTree(root, &values[i], sizeof(int), compareIntegers, NULL); + } + + // Verify root value + TEST_ASSERT_EQUAL_INT(20, *(int *)root->data); + + // Verify left subtree + TEST_ASSERT_EQUAL_INT(10, *(int *)root->left->data); + TEST_ASSERT_EQUAL_INT(5, *(int *)root->left->left->data); + TEST_ASSERT_EQUAL_INT(15, *(int *)root->left->right->data); + + // Verify right subtree + TEST_ASSERT_EQUAL_INT(30, *(int *)root->right->data); + TEST_ASSERT_EQUAL_INT(25, *(int *)root->right->left->data); + TEST_ASSERT_EQUAL_INT(35, *(int *)root->right->right->data); + + // Cleanup + clearTree(root); +} + +// Test 1.5: Attempt to insert a duplicate when isDuplicate is NULL (allows duplicates) +void test_addToTree_AllowDuplicates(void) +{ + TreeNode *root = NULL; + int value1 = 42; + int value2 = 42; + + // Insert first instance + root = addToTree(root, &value1, sizeof(int), compareIntegers, NULL); + + // Insert duplicate (isDuplicate is NULL, so duplicates are allowed) + root = addToTree(root, &value2, sizeof(int), compareIntegers, NULL); + + // Verify tree has both entries (duplicate goes right) + TEST_ASSERT_EQUAL_INT(42, *(int *)root->data); + TEST_ASSERT_NULL(root->left); + TEST_ASSERT_NOT_NULL(root->right); + TEST_ASSERT_EQUAL_INT(42, *(int *)root->right->data); + + // Cleanup + clearTree(root); +} + +// Test 1.6: Attempt to insert a duplicate when isDuplicate is provided (rejects duplicates) +void test_addToTree_RejectDuplicates(void) +{ + TreeNode *root = NULL; + int value1 = 42; + int value2 = 42; + int isDuplicate = 0; + + // Insert first instance + root = addToTree(root, &value1, sizeof(int), compareIntegers, &isDuplicate); + TEST_ASSERT_EQUAL_INT(0, isDuplicate); + + // Attempt to insert duplicate + root = addToTree(root, &value2, sizeof(int), compareIntegers, &isDuplicate); + + // Verify isDuplicate was set to 1 + TEST_ASSERT_EQUAL_INT(1, isDuplicate); + + // Verify tree still has only one node with the first value + TEST_ASSERT_EQUAL_INT(42, *(int *)root->data); + TEST_ASSERT_NULL(root->left); + TEST_ASSERT_NULL(root->right); + + // Cleanup + clearTree(root); +} + +// Test 1.7: Insert multiple elements with duplicate detection +void test_addToTree_MultipleWithDuplicateDetection(void) +{ + TreeNode *root = NULL; + int values[] = {20, 10, 30, 10}; // 10 is a duplicate + int isDuplicate = 0; + + // Insert 20 + root = addToTree(root, &values[0], sizeof(int), compareIntegers, &isDuplicate); + TEST_ASSERT_EQUAL_INT(0, isDuplicate); + + // Insert 10 (new) + root = addToTree(root, &values[1], sizeof(int), compareIntegers, &isDuplicate); + TEST_ASSERT_EQUAL_INT(0, isDuplicate); + + // Insert 30 (new) + root = addToTree(root, &values[2], sizeof(int), compareIntegers, &isDuplicate); + TEST_ASSERT_EQUAL_INT(0, isDuplicate); + + // Insert 10 (duplicate) + root = addToTree(root, &values[3], sizeof(int), compareIntegers, &isDuplicate); + TEST_ASSERT_EQUAL_INT(1, isDuplicate); + + // Verify tree structure hasn't changed (3 nodes, not 4) + TEST_ASSERT_EQUAL_INT(3, treeSize(root)); + + // Cleanup + clearTree(root); +} + +// Test 1.8: Insert strings into a tree +void test_addToTree_WithStrings(void) +{ + TreeNode *root = NULL; + const char *words[] = {"dog", "cat", "elephant", "bear"}; + + // Insert strings + for (int i = 0; i < 4; i++) + { + // Note: We pass pointer to the string pointer + root = addToTree(root, &words[i], sizeof(char *), compareStrings, NULL); + } + + // Verify root value (first insertion) + TEST_ASSERT_EQUAL_STRING("dog", *(char **)root->data); + + // Verify tree has 4 nodes + TEST_ASSERT_EQUAL_INT(4, treeSize(root)); + + // Cleanup + clearTree(root); +} + +// ============================================================================ +// TEST SUITE 2: treeSize() - Counting Nodes +// ============================================================================ + +// Test 2.1: Size of empty tree (NULL root) +void test_treeSize_EmptyTree(void) +{ + TreeNode *root = NULL; + unsigned int size = treeSize(root); + + // Verify empty tree has size 0 + TEST_ASSERT_EQUAL_INT(0, size); +} + +// Test 2.2: Size of single-node tree +void test_treeSize_SingleNode(void) +{ + TreeNode *root = NULL; + int value = 42; + + root = addToTree(root, &value, sizeof(int), compareIntegers, NULL); + unsigned int size = treeSize(root); + + // Verify single-node tree has size 1 + TEST_ASSERT_EQUAL_INT(1, size); + + clearTree(root); +} + +// Test 2.2: Size of multi-node tree +void test_treeSize_MultipleNodes(void) +{ + TreeNode *root = NULL; + int values[] = {20, 10, 30, 5, 15, 25, 35}; + + // Insert all values + for (int i = 0; i < 7; i++) + { + root = addToTree(root, &values[i], sizeof(int), compareIntegers, NULL); + } + + unsigned int size = treeSize(root); + + // Verify tree has 7 nodes + TEST_ASSERT_EQUAL_INT(7, size); + + clearTree(root); +} + +// Test 2.3: Size after multiple insertions +void test_treeSize_IncrementalGrowth(void) +{ + TreeNode *root = NULL; + int values[] = {20, 10, 30, 5, 15}; + + for (int i = 0; i < 5; i++) + { + root = addToTree(root, &values[i], sizeof(int), compareIntegers, NULL); + + // Check size increases with each insertion + unsigned int expectedSize = i + 1; + TEST_ASSERT_EQUAL_INT(expectedSize, treeSize(root)); + } + + clearTree(root); +} + +// ============================================================================ +// TEST SUITE 3: clearTree() - Freeing Memory +// ============================================================================ + +// Test 3.1: Clear empty tree (NULL root) +void test_clearTree_EmptyTree(void) +{ + TreeNode *root = NULL; + + // Should not crash when clearing NULL + clearTree(root); + + // Verify still NULL after clearing + TEST_ASSERT_NULL(root); +} + +// Test 3.2: Clear single-node tree +void test_clearTree_SingleNode(void) +{ + TreeNode *root = NULL; + int value = 42; + + root = addToTree(root, &value, sizeof(int), compareIntegers, NULL); + + // Clear the tree + clearTree(root); + root = NULL; // Reset pointer + + // Verify root is now NULL + TEST_ASSERT_NULL(root); +} + +// Test 3.3: Clear multi-node tree +void test_clearTree_MultipleNodes(void) +{ + TreeNode *root = NULL; + int values[] = {20, 10, 30, 5, 15, 25, 35}; + + for (int i = 0; i < 7; i++) + { + root = addToTree(root, &values[i], sizeof(int), compareIntegers, NULL); + } + + // Clear the entire tree + clearTree(root); + root = NULL; + + // Verify root is now NULL + TEST_ASSERT_NULL(root); + + // If we got here without segfault, the memory was properly freed +} + +// ============================================================================ +// TEST SUITE 4: nextTreeData() - In-Order Traversal +// ============================================================================ + +// Test 4.1: In-order traversal of simple tree (ascending linear) +void test_nextTreeData_AscendingLinearTree(void) +{ + TreeNode *root = NULL; + int values[] = {1, 2, 3}; + + for (int i = 0; i < 3; i++) + { + root = addToTree(root, &values[i], sizeof(int), compareIntegers, NULL); + } + + // Traverse and collect results + int result1 = *(int *)nextTreeData(root); + int result2 = *(int *)nextTreeData(NULL); + int result3 = *(int *)nextTreeData(NULL); + void *result4 = nextTreeData(NULL); + + // Verify in-order traversal produces ascending order + TEST_ASSERT_EQUAL_INT(1, result1); + TEST_ASSERT_EQUAL_INT(2, result2); + TEST_ASSERT_EQUAL_INT(3, result3); + TEST_ASSERT_NULL(result4); // No more elements + + clearTree(root); +} + +// Test 4.2: In-order traversal of balanced tree +void test_nextTreeData_BalancedTree(void) +{ + TreeNode *root = NULL; + int values[] = {20, 10, 30, 5, 15, 25, 35}; + + for (int i = 0; i < 7; i++) + { + root = addToTree(root, &values[i], sizeof(int), compareIntegers, NULL); + } + + // Traverse and collect results + int results[7]; + results[0] = *(int *)nextTreeData(root); + for (int i = 1; i < 7; i++) + { + results[i] = *(int *)nextTreeData(NULL); + } + + // Verify in-order traversal produces ascending order + int expectedOrder[] = {5, 10, 15, 20, 25, 30, 35}; + for (int i = 0; i < 7; i++) + { + TEST_ASSERT_EQUAL_INT(expectedOrder[i], results[i]); + } + + // Verify traversal is complete + void *result = nextTreeData(NULL); + TEST_ASSERT_NULL(result); + + clearTree(root); +} + +// Test 4.3: In-order traversal of descending linear tree +void test_nextTreeData_DescendingLinearTree(void) +{ + TreeNode *root = NULL; + int values[] = {30, 20, 10}; + + for (int i = 0; i < 3; i++) + { + root = addToTree(root, &values[i], sizeof(int), compareIntegers, NULL); + } + + // Traverse and collect results + int result1 = *(int *)nextTreeData(root); + int result2 = *(int *)nextTreeData(NULL); + int result3 = *(int *)nextTreeData(NULL); + void *result4 = nextTreeData(NULL); + + // Verify in-order traversal produces ascending order (despite insertion order) + TEST_ASSERT_EQUAL_INT(10, result1); + TEST_ASSERT_EQUAL_INT(20, result2); + TEST_ASSERT_EQUAL_INT(30, result3); + TEST_ASSERT_NULL(result4); + + clearTree(root); +} + +// Test 4.4: Traversal of single-node tree +void test_nextTreeData_SingleNode(void) +{ + TreeNode *root = NULL; + int value = 42; + + root = addToTree(root, &value, sizeof(int), compareIntegers, NULL); + + int result1 = *(int *)nextTreeData(root); + void *result2 = nextTreeData(NULL); + + TEST_ASSERT_EQUAL_INT(42, result1); + TEST_ASSERT_NULL(result2); + + clearTree(root); +} + +// Test 4.5: Traversal of empty tree +void test_nextTreeData_EmptyTree(void) +{ + TreeNode *root = NULL; + + void *result = nextTreeData(root); + + TEST_ASSERT_NULL(result); +} + +// ============================================================================ +// INTEGRATION TEST: Complete BST Workflow +// ============================================================================ + +// Test 5.1: Complete workflow - insert, size, traverse, clear +void test_integration_CompleteWorkflow(void) +{ + TreeNode *root = NULL; + int values[] = {50, 25, 75, 12, 37, 62, 87}; + int isDuplicate = 0; + + // Insert all values + for (int i = 0; i < 7; i++) + { + root = addToTree(root, &values[i], sizeof(int), compareIntegers, &isDuplicate); + TEST_ASSERT_EQUAL_INT(0, isDuplicate); + } + + // Verify size + TEST_ASSERT_EQUAL_INT(7, treeSize(root)); + + // Verify in-order traversal + int expectedOrder[] = {12, 25, 37, 50, 62, 75, 87}; + int results[7]; + + results[0] = *(int *)nextTreeData(root); + for (int i = 1; i < 7; i++) + { + results[i] = *(int *)nextTreeData(NULL); + } + + for (int i = 0; i < 7; i++) + { + TEST_ASSERT_EQUAL_INT(expectedOrder[i], results[i]); + } + + // Verify duplicate detection + root = addToTree(root, &values[0], sizeof(int), compareIntegers, &isDuplicate); + TEST_ASSERT_EQUAL_INT(1, isDuplicate); + TEST_ASSERT_EQUAL_INT(7, treeSize(root)); // Size should not increase + + // Clear and verify + clearTree(root); + root = NULL; + TEST_ASSERT_NULL(root); +} + +// ============================================================================ +// TEST RUNNER +// ============================================================================ + +int main(void) +{ + UNITY_BEGIN(); + + // Test Suite 1: addToTree() + RUN_TEST(test_addToTree_SingleElement); + RUN_TEST(test_addToTree_AscendingOrder); + RUN_TEST(test_addToTree_DescendingOrder); + RUN_TEST(test_addToTree_BalancedTree); + RUN_TEST(test_addToTree_AllowDuplicates); + RUN_TEST(test_addToTree_RejectDuplicates); + RUN_TEST(test_addToTree_MultipleWithDuplicateDetection); + RUN_TEST(test_addToTree_WithStrings); + + // Test Suite 2: treeSize() + RUN_TEST(test_treeSize_EmptyTree); + RUN_TEST(test_treeSize_SingleNode); + RUN_TEST(test_treeSize_MultipleNodes); + RUN_TEST(test_treeSize_IncrementalGrowth); + + // Test Suite 3: clearTree() + RUN_TEST(test_clearTree_EmptyTree); + RUN_TEST(test_clearTree_SingleNode); + RUN_TEST(test_clearTree_MultipleNodes); + + // Test Suite 4: nextTreeData() + RUN_TEST(test_nextTreeData_AscendingLinearTree); + RUN_TEST(test_nextTreeData_BalancedTree); + RUN_TEST(test_nextTreeData_DescendingLinearTree); + RUN_TEST(test_nextTreeData_SingleNode); + RUN_TEST(test_nextTreeData_EmptyTree); + + // Integration Test + RUN_TEST(test_integration_CompleteWorkflow); + + return UNITY_END(); +} diff --git a/test_debug b/test_debug new file mode 100755 index 0000000000000000000000000000000000000000..62ba641d1311d2e311c9fd46640ba267a728b39f GIT binary patch literal 23712 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 Vf^=JJ6A`R`zClV1*%WLj`!6g^H4^{; literal 0 HcmV?d00001 diff --git a/test_debug.c b/test_debug.c new file mode 100644 index 0000000..ae1f2a9 --- /dev/null +++ b/test_debug.c @@ -0,0 +1,61 @@ +#include +#include +#include "numbers.h" + +int main(void) +{ + printf("=== Testing createNumbers() ===\n\n"); + + for (int run = 0; run < 3; run++) + { + printf("RUN %d:\n", run + 1); + unsigned int *numbers = createNumbers(5); + + if (numbers == NULL) + { + printf("ERROR: createNumbers returned NULL\n\n"); + continue; + } + + printf("Array contents: "); + for (int i = 0; i < 5; i++) + { + printf("%u ", numbers[i]); + } + printf("\n"); + + // Count occurrences of each value + printf("Value counts:\n"); + for (int i = 0; i < 5; i++) + { + int count = 0; + for (int j = 0; j < 5; j++) + { + if (numbers[i] == numbers[j]) + count++; + } + printf(" Value %u appears %d times\n", numbers[i], count); + } + + // Check for duplicates + int duplicateCount = 0; + for (int i = 0; i < 5; i++) + { + int count = 0; + for (int j = 0; j < 5; j++) + { + if (numbers[i] == numbers[j]) + count++; + } + if (count == 2 && (i == 0 || numbers[i] != numbers[i-1])) + { + duplicateCount++; + } + } + printf("Duplicate values found: %d\n\n", duplicateCount); + + free(numbers); + } + + return 0; +} diff --git a/test_numbers b/test_numbers new file mode 100755 index 0000000000000000000000000000000000000000..545ec6cb7e174e4c11df3335ef5406570a1c54f3 GIT binary patch literal 71384 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

-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 NRj_@*Zq0XAF@8oJTG#x(-uK!~;ltrj4|2BKFg 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 +#include +#include + +/* ============================================================================ + * UNIT TESTS FOR SORTING AND DUPLICATE DETECTION (Sortierung) + * + * This test suite covers: + * - createNumbers(): Generate random numbers with exactly one duplicate + * - getDuplicate(): Find the duplicate number using sorting + * ========================================================================== */ + +// ============================================================================ +// HELPER FUNCTIONS FOR TESTING +// ============================================================================ + +// Count how many times a specific value appears in an array +unsigned int countOccurrences(const unsigned int *numbers, unsigned int len, unsigned int value) +{ + unsigned int count = 0; + for (unsigned int i = 0; i < len; i++) + { + if (numbers[i] == value) + { + count++; + } + } + return count; +} + +// Check if a value is in the valid range [1, 2*len] +int isInValidRange(unsigned int value, unsigned int len) +{ + return (value >= 1) && (value <= 2 * len); +} + +// Count total number of distinct values in the array +unsigned int countDistinctValues(const unsigned int *numbers, unsigned int len) +{ + unsigned int distinct = 0; + for (unsigned int i = 0; i < len; i++) + { + int isNew = 1; + for (unsigned int j = 0; j < i; j++) + { + if (numbers[i] == numbers[j]) + { + isNew = 0; + break; + } + } + if (isNew) + { + distinct++; + } + } + return distinct; +} + +// Find the value that appears exactly twice +unsigned int findDuplicate(const unsigned int *numbers, unsigned int len) +{ + for (unsigned int i = 0; i < len; i++) + { + unsigned int count = countOccurrences(numbers, len, numbers[i]); + if (count == 2) + { + return numbers[i]; + } + } + return 0; // No duplicate found +} + +// ============================================================================ +// TEST SETUP AND TEARDOWN +// ============================================================================ + +void setUp(void) +{ + // Setup before each test +} + +void tearDown(void) +{ + // Cleanup after each test +} + +// ============================================================================ +// TEST SUITE 1: createNumbers() - Input Validation and Error Handling +// ============================================================================ + +// Test 1.1: Invalid input - len = 0 should return NULL +void test_createNumbers_InvalidLenZero(void) +{ + unsigned int *numbers = createNumbers(0); + + TEST_ASSERT_NULL(numbers); +} + +// Test 1.2: Invalid input - len = 1 should return NULL (need at least 2 for duplicate) +void test_createNumbers_InvalidLenOne(void) +{ + unsigned int *numbers = createNumbers(1); + + TEST_ASSERT_NULL(numbers); +} + +// ============================================================================ +// TEST SUITE 2: createNumbers() - Minimum Valid Input +// ============================================================================ + +// Test 2.1: Minimum valid input - len = 2 +void test_createNumbers_MinimumSize(void) +{ + unsigned int *numbers = createNumbers(2); + + // Should not be NULL + TEST_ASSERT_NOT_NULL(numbers); + + // One value should equal the other (the duplicate) + TEST_ASSERT_EQUAL_INT(numbers[0], numbers[1]); + + free(numbers); +} + +// ============================================================================ +// TEST SUITE 3: createNumbers() - Array Size and Contents +// ============================================================================ + +// Test 3.1: Check array size for len=5 +void test_createNumbers_ArraySize5(void) +{ + unsigned int *numbers = createNumbers(5); + + TEST_ASSERT_NOT_NULL(numbers); + + // Access all 5 elements to verify they exist + for (unsigned int i = 0; i < 5; i++) + { + // Just verify we can read without segfault + (void)numbers[i]; + } + + free(numbers); +} + +// Test 3.2: Check array size for len=10 +void test_createNumbers_ArraySize10(void) +{ + unsigned int *numbers = createNumbers(10); + + TEST_ASSERT_NOT_NULL(numbers); + + // Access all 10 elements + for (unsigned int i = 0; i < 10; i++) + { + // Just verify we can read without segfault + (void)numbers[i]; + } + + free(numbers); +} + +// ============================================================================ +// TEST SUITE 4: createNumbers() - Value Range Validation +// ============================================================================ + +// Test 4.1: All values are positive (basic sanity check) +void test_createNumbers_ValueRangeLen5(void) +{ + unsigned int *numbers = createNumbers(5); + + TEST_ASSERT_NOT_NULL(numbers); + + // Check each value is positive and not too large + for (unsigned int i = 0; i < 5; i++) + { + TEST_ASSERT_TRUE(numbers[i] > 0); + TEST_ASSERT_TRUE(numbers[i] <= 10); + } + + free(numbers); +} + +// Test 4.2: All values are positive (for len=20) +void test_createNumbers_ValueRangeLen20(void) +{ + unsigned int *numbers = createNumbers(20); + + TEST_ASSERT_NOT_NULL(numbers); + + // Check each value is positive and reasonable + for (unsigned int i = 0; i < 20; i++) + { + TEST_ASSERT_TRUE(numbers[i] > 0); + TEST_ASSERT_TRUE(numbers[i] <= 40); + } + + free(numbers); +} + +// ============================================================================ +// TEST SUITE 5: createNumbers() - Duplicate Detection +// ============================================================================ + +// Test 5.1: Exactly one value appears twice (len=5) +void test_createNumbers_ExactlyOneDuplicateLen5(void) +{ + unsigned int *numbers = createNumbers(5); + + TEST_ASSERT_NOT_NULL(numbers); + + // Count how many distinct values appear exactly twice + unsigned int valuesAppearingTwice = 0; + unsigned int counted[5] = {0}; // Track which values we've counted + + for (unsigned int i = 0; i < 5; i++) + { + unsigned int value = numbers[i]; + unsigned int count = countOccurrences(numbers, 5, value); + + // If this value appears twice and we haven't counted it yet, count it now + if (count == 2) + { + int alreadyCounted = 0; + for (unsigned int j = 0; j < 5; j++) + { + if (counted[j] == value) + { + alreadyCounted = 1; + break; + } + } + + if (!alreadyCounted) + { + valuesAppearingTwice++; + counted[i] = value; // Mark this value as counted + } + } + } + + // Should have exactly one value that appears twice + TEST_ASSERT_EQUAL_INT(1, valuesAppearingTwice); + + // Count distinct values - should be len-1 = 4 + unsigned int distinct = countDistinctValues(numbers, 5); + TEST_ASSERT_EQUAL_INT(4, distinct); + + free(numbers); +} + +// Test 5.2: Exactly one value appears twice (len=10) +void test_createNumbers_ExactlyOneDuplicateLen10(void) +{ + unsigned int *numbers = createNumbers(10); + + TEST_ASSERT_NOT_NULL(numbers); + + // Count how many distinct values appear exactly twice + unsigned int valuesAppearingTwice = 0; + unsigned int counted[10] = {0}; // Track which values we've counted + + for (unsigned int i = 0; i < 10; i++) + { + unsigned int value = numbers[i]; + unsigned int count = countOccurrences(numbers, 10, value); + + // If this value appears twice and we haven't counted it yet, count it now + if (count == 2) + { + int alreadyCounted = 0; + for (unsigned int j = 0; j < 10; j++) + { + if (counted[j] == value) + { + alreadyCounted = 1; + break; + } + } + + if (!alreadyCounted) + { + valuesAppearingTwice++; + counted[i] = value; // Mark this value as counted + } + } + } + + // Should have exactly one value that appears twice + TEST_ASSERT_EQUAL_INT(1, valuesAppearingTwice); + + // Count distinct values - should be len-1 = 9 + unsigned int distinct = countDistinctValues(numbers, 10); + TEST_ASSERT_EQUAL_INT(9, distinct); + + free(numbers); +} + +// Test 5.3: No accidental triplicates (len=5) +void test_createNumbers_NoTriplicatesLen5(void) +{ + unsigned int *numbers = createNumbers(5); + + TEST_ASSERT_NOT_NULL(numbers); + + // Count occurrences of each value + for (unsigned int i = 0; i < 5; i++) + { + unsigned int count = countOccurrences(numbers, 5, numbers[i]); + + // Each value should appear 1 or 2 times, never 3 or more + TEST_ASSERT_TRUE(count == 1 || count == 2); + } + + free(numbers); +} + +// ============================================================================ +// TEST SUITE 6: createNumbers() - No Accidental Duplicates Before Intentional One +// ============================================================================ + +// Test 6.1: Total count validation - sum should be len +void test_createNumbers_TotalCountLen5(void) +{ + unsigned int *numbers = createNumbers(5); + + TEST_ASSERT_NOT_NULL(numbers); + + // Sum of all occurrences should equal len (5) + // (unique_count * 1) + (1 duplicate_value * 2) = len + // which simplifies to: (len-1) + 2 = len + 1 ... wait that's wrong + + // Actually: if we have 4 unique values and 1 appears twice: + // 4 unique values, but 1 of them appears twice + // So: 3 values appearing once + 1 value appearing twice = 3 + 2 = 5 total entries + + // Total unique values = len - 1 = 4 + // But sum of elements = len = 5 + // This checks out: (len-1-1) * 1 + 1 * 2 = (len-2) + 2 = len ✓ + + unsigned int distinct = countDistinctValues(numbers, 5); + TEST_ASSERT_EQUAL_INT(4, distinct); + + free(numbers); +} + +// ============================================================================ +// TEST SUITE 7: createNumbers() - Randomness +// ============================================================================ + +// Test 7.1: Multiple calls produce different (or can produce different) results +void test_createNumbers_DifferentRandomResults(void) +{ + unsigned int *numbers1 = createNumbers(5); + + // Advance the random sequence a bit + for (int i = 0; i < 10; i++) + { + rand(); + } + + unsigned int *numbers2 = createNumbers(5); + + TEST_ASSERT_NOT_NULL(numbers1); + TEST_ASSERT_NOT_NULL(numbers2); + + // It's possible (though unlikely) that two random arrays are identical + // So we'll just verify that the function works and can produce different results + // by checking that both have correct structure + int identical = 1; + for (unsigned int i = 0; i < 5; i++) + { + if (numbers1[i] != numbers2[i]) + { + identical = 0; + break; + } + } + + // Note: identical could be 0 or 1, both are valid test outcomes + // The important thing is that both arrays are valid + (void)identical; + + free(numbers1); + free(numbers2); +} + +// ============================================================================ +// TEST SUITE 8: getDuplicate() - Finding the Duplicate +// ============================================================================ + +// Test 8.1: getDuplicate finds the correct value for len=5 +void test_getDuplicate_FindsCorrectValueLen5(void) +{ + unsigned int *numbers = createNumbers(5); + TEST_ASSERT_NOT_NULL(numbers); + + // Find the duplicate manually (using our test helper) + unsigned int expectedDuplicate = findDuplicate(numbers, 5); + TEST_ASSERT_NOT_EQUAL(0, expectedDuplicate); + + // Test getDuplicate() - should find the same duplicate + unsigned int actualDuplicate = getDuplicate(numbers, 5); + TEST_ASSERT_EQUAL_INT(expectedDuplicate, actualDuplicate); + + free(numbers); +} + +// Test 8.2: getDuplicate finds the correct value for len=10 +void test_getDuplicate_FindsCorrectValueLen10(void) +{ + unsigned int *numbers = createNumbers(10); + TEST_ASSERT_NOT_NULL(numbers); + + // Find the duplicate manually (using our test helper) + unsigned int expectedDuplicate = findDuplicate(numbers, 10); + TEST_ASSERT_NOT_EQUAL(0, expectedDuplicate); + + // Test getDuplicate() - should find the same duplicate + unsigned int actualDuplicate = getDuplicate(numbers, 10); + TEST_ASSERT_EQUAL_INT(expectedDuplicate, actualDuplicate); + + free(numbers); +} + +// Test 8.3: getDuplicate handles NULL pointer gracefully +void test_getDuplicate_NullPointerReturnsZero(void) +{ + unsigned int result = getDuplicate(NULL, 5); + TEST_ASSERT_EQUAL_INT(0, result); +} + +// Test 8.4: getDuplicate handles len < 2 gracefully +void test_getDuplicate_InvalidLenReturnsZero(void) +{ + unsigned int arr[] = {1}; + + // len = 0 + unsigned int result0 = getDuplicate(arr, 0); + TEST_ASSERT_EQUAL_INT(0, result0); + + // len = 1 + unsigned int result1 = getDuplicate(arr, 1); + TEST_ASSERT_EQUAL_INT(0, result1); +} + +// Test 8.5: getDuplicate works with len=20 +void test_getDuplicate_FindsCorrectValueLen20(void) +{ + unsigned int *numbers = createNumbers(20); + TEST_ASSERT_NOT_NULL(numbers); + + // Find the duplicate using our test helper + unsigned int expectedDuplicate = findDuplicate(numbers, 20); + TEST_ASSERT_NOT_EQUAL(0, expectedDuplicate); + + // Test getDuplicate() + unsigned int actualDuplicate = getDuplicate(numbers, 20); + TEST_ASSERT_EQUAL_INT(expectedDuplicate, actualDuplicate); + + free(numbers); +} + +// Test 8.6: getDuplicate doesn't modify the input array +void test_getDuplicate_DoesNotModifyInputArray(void) +{ + unsigned int *original = createNumbers(8); + TEST_ASSERT_NOT_NULL(original); + + // Create a copy to compare before and after + unsigned int *copy = (unsigned int *)malloc(8 * sizeof(unsigned int)); + memcpy(copy, original, 8 * sizeof(unsigned int)); + + // Call getDuplicate (which creates its own sorted copy internally) + getDuplicate(original, 8); + + // Verify the input array wasn't modified + for (unsigned int i = 0; i < 8; i++) + { + TEST_ASSERT_EQUAL_INT(copy[i], original[i]); + } + + free(original); + free(copy); +} + +// ============================================================================ +// TEST SUITE 9: Integration Tests +// ============================================================================ + +// Test 9.1: Full workflow for len=3 +void test_integration_CreateAndValidateLen3(void) +{ + unsigned int *numbers = createNumbers(3); + + TEST_ASSERT_NOT_NULL(numbers); + + // Validate: 3 elements exist and have valid values + for (unsigned int i = 0; i < 3; i++) + { + TEST_ASSERT_TRUE(numbers[i] > 0); + } + + // Validate: exactly 2 distinct values (one appears twice) + unsigned int distinct = countDistinctValues(numbers, 3); + TEST_ASSERT_EQUAL_INT(2, distinct); + + free(numbers); +} + +// Test 9.2: Full workflow for len=15 +void test_integration_CreateAndValidateLen15(void) +{ + unsigned int *numbers = createNumbers(15); + + TEST_ASSERT_NOT_NULL(numbers); + + // Validate: 15 elements exist and have valid values + for (unsigned int i = 0; i < 15; i++) + { + TEST_ASSERT_TRUE(numbers[i] > 0); + } + + // Validate: exactly 14 distinct values + unsigned int distinct = countDistinctValues(numbers, 15); + TEST_ASSERT_EQUAL_INT(14, distinct); + + free(numbers); +} + +// Test 9.3: Memory cleanup - no segfault +void test_integration_MultipleAllocationsAndFrees(void) +{ + for (unsigned int run = 0; run < 5; run++) + { + unsigned int *numbers = createNumbers(5 + run); + TEST_ASSERT_NOT_NULL(numbers); + free(numbers); + } + + // If we reach here without segfault, cleanup worked + TEST_ASSERT_TRUE(1); +} + +// ============================================================================ +// TEST RUNNER +// ============================================================================ + +int main(void) +{ + UNITY_BEGIN(); + + // Initialize random number seed once at the beginning + srand(time(NULL)); + + // Test Suite 1: Input Validation + RUN_TEST(test_createNumbers_InvalidLenZero); + RUN_TEST(test_createNumbers_InvalidLenOne); + + // Test Suite 2: Minimum Valid Input + RUN_TEST(test_createNumbers_MinimumSize); + + // Test Suite 3: Array Size + RUN_TEST(test_createNumbers_ArraySize5); + RUN_TEST(test_createNumbers_ArraySize10); + + // Test Suite 4: Value Range + RUN_TEST(test_createNumbers_ValueRangeLen5); + RUN_TEST(test_createNumbers_ValueRangeLen20); + + // Test Suite 5: Duplicate Detection + RUN_TEST(test_createNumbers_ExactlyOneDuplicateLen5); + RUN_TEST(test_createNumbers_ExactlyOneDuplicateLen10); + RUN_TEST(test_createNumbers_NoTriplicatesLen5); + + // Test Suite 6: No Accidental Duplicates + RUN_TEST(test_createNumbers_TotalCountLen5); + + // Test Suite 7: Randomness + RUN_TEST(test_createNumbers_DifferentRandomResults); + + // Test Suite 8: getDuplicate + RUN_TEST(test_getDuplicate_FindsCorrectValueLen5); + RUN_TEST(test_getDuplicate_FindsCorrectValueLen10); + RUN_TEST(test_getDuplicate_NullPointerReturnsZero); + RUN_TEST(test_getDuplicate_InvalidLenReturnsZero); + RUN_TEST(test_getDuplicate_FindsCorrectValueLen20); + RUN_TEST(test_getDuplicate_DoesNotModifyInputArray); + + // Test Suite 9: Integration + RUN_TEST(test_integration_CreateAndValidateLen3); + RUN_TEST(test_integration_CreateAndValidateLen15); + RUN_TEST(test_integration_MultipleAllocationsAndFrees); + + return UNITY_END(); +} diff --git a/unity.o b/unity.o new file mode 100644 index 0000000000000000000000000000000000000000..8bcdd9b9b44ca56425c143c23d49a94b1dded282 GIT binary patch literal 64248 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