Uploaded most of my stuff

This commit is contained in:
Win 2025-05-03 23:22:40 +07:00
parent ff7991c82b
commit 0641107f4b
10 changed files with 1429 additions and 0 deletions

BIN
spring-2025/sen-107/00020/a.out Executable file

Binary file not shown.

View File

@ -0,0 +1,243 @@
/* matrilineal
*
* Build a simple, non-sorted tree of mother-daughter relationships
*
* Created by Nunthatinn Veerapaiboon, 30 Jan 2025
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Adds person with a given name at the root.
*/
#define MAX_CHILDREN 10
#define MAX_NAME_LENGTH 25
typedef struct NODE_T
{
char name[MAX_NAME_LENGTH];
int numChildren;
struct NODE_T * parent;
struct NODE_T *children[MAX_CHILDREN];
} NODE_T;
NODE_T* root = NULL;
NODE_T* createNode(char* name) {
NODE_T* newNode = (NODE_T*)malloc(sizeof(NODE_T));
if (newNode == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
strncpy(newNode->name, name, MAX_NAME_LENGTH - 1);
newNode->name[MAX_NAME_LENGTH - 1] = '\0';
newNode->numChildren = 0;
newNode->parent = NULL;
for (int i = 0; i < MAX_CHILDREN; i++) {
newNode->children[i] = NULL;
}
printf("Added\n");
return newNode;
}
// create Root
NODE_T* addRoot(char* name)
{
if (root != NULL)
{
printf("Root already exists.\n");
return root;
}
root = createNode(name);
return root;
}
// Helper function to find a node by name (DFS)
NODE_T* findNode(NODE_T* currentNode, char* name)
{
if (currentNode == NULL)
{
return NULL;
}
// Found at current node
if (strcmp(currentNode->name, name) == 0)
{
return currentNode;
}
for (int i = 0; i < currentNode->numChildren; i++)
{
// recursively find in Children node
NODE_T* found = findNode(currentNode->children[i], name);
// Return node if it was found
if (found != NULL)
{
return found;
}
}
return NULL;
}
/* Adds person with a given name and mother's name to the tree.
*/
NODE_T* addNonRoot(char* name, char* motherName)
{
if (root == NULL)
{
printf("Error: Root does not exist. Please add a root first.\n");
return NULL;
}
// Find mother node
NODE_T* motherNode = findNode(root, motherName);
if (motherNode == NULL)
{
printf("Not Found\n");
return NULL;
}
if (motherNode->numChildren == MAX_CHILDREN)
{
printf("Unsuccessful\n");
return NULL;
}
// Create new node
NODE_T* newNode = createNode(name);
newNode->parent = motherNode;
motherNode->children[motherNode->numChildren] = newNode;
motherNode->numChildren++;
return newNode;
}
/* Prints the person's mother.
*/
void queryMother(char* name)
{
if (root == NULL)
{
printf("The tree is empty.\n");
return;
}
NODE_T* node = findNode(root, name);
if (node == NULL)
{
printf("Not Found\n");
}
else if (node->parent == NULL)
{
printf("Not Found\n");
}
else
{
printf("%s", node->parent->name);
}
}
/* Prints the person's daughters.
*/
void queryDaughters(char* name)
{
if (root == NULL)
{
printf("The tree is empty.\n");
return;
}
NODE_T* node = findNode(root, name);
if (node == NULL)
{
printf("Not Found\n");
}
else if (node->numChildren == 0)
{
printf("Not Found\n");
}
else
{
for (int i = 0; i < node->numChildren; i++)
{
printf("%s ", node->children[i]->name);
}
printf("\n");
}
}
/* Prints the person's sisters.
*/
void querySisters(char* name)
{
if (root == NULL)
{
printf("The tree is empty.\n");
return;
}
NODE_T* node = findNode(root, name);
if (node == NULL)
{
printf("Not Found\n");
}
else if (node->parent == NULL)
{
printf("Not Found\n");
}
else
{
NODE_T* motherNode = node->parent;
if (motherNode->numChildren <= 1)
{
printf("Not Found\n");
}
else
{
for (int i = 0; i < motherNode->numChildren; i++)
{
// Don't print self name
if (strcmp(motherNode->children[i]->name, name) != 0)
{
printf("%s ", motherNode->children[i]->name);
}
printf("\n");
}
}
}
}
int main()
{
char input[64]; // Input operation name
char name[MAX_NAME_LENGTH]; // The name of the woman
char motherName[MAX_NAME_LENGTH]; // The number of woman's mother
int numOperations; // The number of operations.
scanf("%d", &numOperations);
scanf("\n%s", name);
NODE_T* root = addRoot(name);
for (int i = 1 ; i < numOperations ; i ++)
{
scanf("\n%s ", input);
if (strcmp(input, "Add") == 0)
{
scanf("%s %s", name, motherName);
addNonRoot(name, motherName);
}
else if (strcmp(input, "Mother") == 0)
{
scanf("%s", name);
queryMother(name);
}
else if (strcmp(input, "Daughters") == 0)
{
scanf("%s", name);
queryDaughters(name);
}
else
{
scanf("%s", name);
querySisters(name);
}
}
}

View File

@ -0,0 +1,226 @@
/* matrilineal.c
*
* A non-sorted tree of mother-daughter relationships
*
* Created by Pasin Manurangsi, 2025-01-08
* Modified by Thanawin Pattanaphol, 2025-05-02
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Adds person with a given name at the root
*/
#define MAX_CHILDREN 10
#define MAX_NAME_LENGTH 25
#define MAX_PATH_LENGTH 100
typedef struct NODE_T
{
char name[MAX_NAME_LENGTH];
int numChildren;
struct NODE_T* parent;
struct NODE_T* children[MAX_CHILDREN];
} NODE_T;
NODE_T* root = NULL;
NODE_T* createNode(char* name)
{
NODE_T* newNode = (NODE_T*)malloc(sizeof(NODE_T));
if (newNode == NULL)
{
printf("Memory allocation failed.\n");
exit(1);
}
strncpy(newNode->name, name, MAX_NAME_LENGTH - 1);
newNode->name[MAX_NAME_LENGTH - 1] = '\0';
newNode->numChildren = 0;
newNode->parent = NULL;
for (int i = 0; i < MAX_CHILDREN; i++)
{
newNode->children[i] = NULL;
}
printf("Added\n");
return newNode;
}
// Create the root
NODE_T* addRoot(char* name)
{
if (root != NULL)
{
printf("Root already exists.\n");
return root;
}
root = createNode(name);
return root;
}
// Function that helps finding a node by name
NODE_T* findNode(NODE_T* currentNode, char* name)
{
if (currentNode == NULL) return NULL;
if (strcmp(currentNode->name, name) == 0) return currentNode;
for (int i = 0; i < currentNode->numChildren; i++)
{
NODE_T* found = findNode(currentNode->children[i], name);
if (found != NULL) return found;
}
return NULL;
}
/* Adds person with a given name and mother's name to the tree.
*/
NODE_T* addNonRoot(char* name, char* motherName)
{
if (root == NULL)
{
printf("Error: Root does not exist. Please add a root first.\n");
return NULL;
}
NODE_T* motherNode = findNode(root, motherName);
if (motherNode == NULL)
{
printf("Unsuccessful\n");
return NULL;
}
if (motherNode->numChildren == MAX_CHILDREN)
{
printf("Unsuccessful\n");
return NULL;
}
NODE_T* newNode = createNode(name);
newNode->parent = motherNode;
motherNode->children[motherNode->numChildren++] = newNode;
return newNode;
}
/* DFS function
*/
void dfsPrintDescendants(NODE_T* node)
{
for (int i = 0; i < node->numChildren; i++)
{
printf("%s ", node->children[i]->name);
dfsPrintDescendants(node->children[i]);
}
}
/* Prints the descendants of a given node.
*/
void printDescendants(char* name)
{
NODE_T* node = findNode(root, name);
if (node == NULL || node->numChildren == 0)
{
printf("Not Found\n");
return;
}
dfsPrintDescendants(node);
printf("\n");
}
/* DFS function to find the maximum chain
*/
void dfsFindMaxChain(
NODE_T* node,
NODE_T* path[],
int depth,
NODE_T* maxPath[],
int* maxDepth
)
{
path[depth] = node;
if (node->numChildren == 0)
{
if (depth + 1 > *maxDepth)
{
*maxDepth = depth + 1;
for (int i = 0; i <= depth; i++)
{
maxPath[i] = path[i];
}
}
}
else
{
for (int i = 0; i < node->numChildren; i++)
{
dfsFindMaxChain(
node->children[i],
path,
depth + 1,
maxPath,
maxDepth
);
}
}
}
// Function to print the longest chain
void printLongestChain()
{
if (root == NULL)
{
printf("Tree is empty\n");
return;
}
NODE_T* path[MAX_PATH_LENGTH];
NODE_T* maxPath[MAX_PATH_LENGTH];
int maxDepth = 0;
dfsFindMaxChain(root, path, 0, maxPath, &maxDepth);
for (int i = 0; i < maxDepth; i++)
{
printf("%s ", maxPath[i]->name);
}
printf("\n");
}
int main()
{
char input[64];
char name[MAX_NAME_LENGTH];
char motherName[MAX_NAME_LENGTH];
int numOperations;
scanf("%d", &numOperations);
scanf("%s", name);
addRoot(name);
for (int i = 1; i < numOperations; i++)
{
scanf("%s", input);
if (strcmp(input, "Add") == 0)
{
scanf("%s %s", name, motherName);
addNonRoot(name, motherName);
}
else if (strcmp(input, "Descendant") == 0)
{
scanf("%s", name);
printDescendants(name);
}
else if (strcmp(input, "Max") == 0)
{
printLongestChain();
}
}
return 0;
}

BIN
spring-2025/sen-107/00030/a.out Executable file

Binary file not shown.

View File

@ -0,0 +1,177 @@
/* AICE Tree
*
* Build a sorted binary tree for competency information
*
* Template for Fundamental Data Structures Lab 3
* Created by Nunthatinn Veerapaiboon, 2025-02-15
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_COMPETENCY_CODE 8
#define MAX_COMPETENCY_TITLE 64
// Define the structs here
// Node Binary tree structure
typedef struct NODE_BT {
char competency_code[8];
char competency_title[64];
int credit;
int year;
int semester;
struct NODE_BT *leftChildren;
struct NODE_BT *rightChildren;
} NODE_BT;
// Declare a global variable for the root of the binary tree
NODE_BT* root = NULL;
/* Creates the node containing compentency's information
**** You may change the type of the function to make it matches the function
output ****
*/
NODE_BT * create_node(char competency_code[MAX_COMPETENCY_CODE], char competency_title[MAX_COMPETENCY_TITLE], int credit, int year, int semester)
{
NODE_BT* newNode = (NODE_BT*)malloc(sizeof(NODE_BT));
if (newNode == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
strncpy(newNode->competency_code, competency_code, MAX_COMPETENCY_CODE - 1);
newNode->competency_code[MAX_COMPETENCY_CODE - 1] = '\0';
strncpy(newNode->competency_title, competency_title, MAX_COMPETENCY_TITLE - 1);
newNode->competency_title[MAX_COMPETENCY_TITLE - 1] = '\0';
newNode->credit = credit;
newNode->year = year;
newNode->semester = semester;
newNode->leftChildren = NULL;
newNode->rightChildren = NULL;
return newNode;
}
/* Inserts the node into the sorted binary tree
**** You may add the function's parameter ****
*/
void insert(NODE_BT* newNode, NODE_BT* currentNode)
{
if (root == NULL) {
root = newNode;
return;
}
// compare year
if (currentNode->year < newNode->year) {
if (currentNode->rightChildren == NULL)
currentNode->rightChildren = newNode;
else
insert(newNode, currentNode->rightChildren);
return;
}
if (currentNode->year > newNode->year) {
if (currentNode->leftChildren == NULL)
currentNode->leftChildren = newNode;
else
insert(newNode, currentNode->leftChildren);
return;
}
// If years are equal, compare semester
if (currentNode->semester < newNode->semester) {
if (currentNode->rightChildren == NULL)
currentNode->rightChildren = newNode;
else
insert(newNode, currentNode->rightChildren);
return;
}
if (currentNode->semester > newNode->semester) {
if (currentNode->leftChildren == NULL)
currentNode->leftChildren = newNode;
else
insert(newNode, currentNode->leftChildren);
return;
}
// If both year and semester are equal, compare competency codes
for (int i = 0; i < MAX_COMPETENCY_CODE; i++) {
if (currentNode->competency_code[i] < newNode->competency_code[i]) {
if (currentNode->rightChildren == NULL)
currentNode->rightChildren = newNode;
else
insert(newNode, currentNode->rightChildren);
return;
}
if (currentNode->competency_code[i] > newNode->competency_code[i]) {
if (currentNode->leftChildren == NULL)
currentNode->leftChildren = newNode;
else
insert(newNode, currentNode->leftChildren);
return;
}
}
}
/* Prints competencies in-order
*/
void print_subtree(NODE_BT* currentNode)
{
if(currentNode->leftChildren != NULL)
{
print_subtree(currentNode->leftChildren);
}
printf("%d %d %s %s\n", currentNode->year, currentNode->semester, currentNode->competency_code, currentNode->competency_title);
if(currentNode->rightChildren != NULL)
{
print_subtree(currentNode->rightChildren);
}
}
void print_competencies()
{
print_subtree(root);
}
/* Free the contents
*/
void freeBT(NODE_BT* node) {
if (node == NULL) return; // Base case: empty node
freeBT(node->leftChildren); // Free left subtree
freeBT(node->rightChildren); // Free right subtree
free(node); // Free the current node
}
// Wrapper function to free the entire tree
void free_all() {
freeBT(root); // Free all nodes starting from the root
root = NULL; // Set root to NULL to prevent dangling reference
}
int main()
{
char competency_code[8];
char competency_title[64];
int credit;
int year;
int semester; // Spring = 0, Fall = 1
int num_operations; // The number of operations.
scanf("%d", &num_operations);
for (int i = 0; i < num_operations; i++)
{
scanf("%7s %63s %d %d %d", competency_code, competency_title, &credit,
&year, &semester);
NODE_BT * new_node = create_node(competency_code, competency_title, credit, year, semester); // You may change the datatype
insert(new_node, root); // You may add the function's argument
}
print_competencies();
free_all();
}

View File

@ -0,0 +1,337 @@
/* orgChart
*
* Build a corporate hierarchy structure and sorted binary tree
*
* Created by Chavakorn Arunkunarax and Phasit Thanitkul, 2025-01-12
* Modified by Thanawin Pattanaphol, 2025-05-02
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
// Structure for an employee in the organization chart (general tree node)
typedef struct EmployeeNode
{
char name[32];
char employeeId[8];
char jobTitle[32];
struct EmployeeNode *supervisor;
struct EmployeeNode *firstChild;
struct EmployeeNode *nextSibling;
} EmployeeNode;
// Structure for a node in the sorted binary tree (index)
typedef struct IndexNode
{
char key[40]; // Concatenation of Name and EmployeeId
EmployeeNode *employeePtr;
struct IndexNode *left;
struct IndexNode *right;
} IndexNode;
EmployeeNode *root = NULL; // Root of the organization chart
IndexNode *indexRoot = NULL; // Root of the sorted binary tree
// Function to create a new employee node
EmployeeNode *createEmployeeNode(char *name, char *employeeId, char *jobTitle)
{
EmployeeNode *newNode = (EmployeeNode *)malloc(sizeof(EmployeeNode));
if (newNode == NULL)
{
perror("Failed to allocate memory for employee node");
exit(EXIT_FAILURE);
}
strcpy(newNode->name, name);
strcpy(newNode->employeeId, employeeId);
strcpy(newNode->jobTitle, jobTitle);
newNode->supervisor = NULL;
newNode->firstChild = NULL;
newNode->nextSibling = NULL;
return newNode;
}
// Function to create a new index node
IndexNode *createIndexNode(char *key, EmployeeNode *employeePtr)
{
IndexNode *newNode = (IndexNode *)malloc(sizeof(IndexNode));
if (newNode == NULL)
{
perror("Failed to allocate memory for index node");
exit(EXIT_FAILURE);
}
strcpy(newNode->key, key);
newNode->employeePtr = employeePtr;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// Function to insert into the sorted binary tree
IndexNode *insertIndexNode(IndexNode *root, char *key, EmployeeNode *employeePtr)
{
if (root == NULL)
{
return createIndexNode(key, employeePtr);
}
int cmp = strcmp(key, root->key);
if (cmp < 0)
{
root->left = insertIndexNode(root->left, key, employeePtr);
}
else if (cmp > 0)
{
root->right = insertIndexNode(root->right, key, employeePtr);
}
return root;
}
/* Adds employee to the corporate hierarchy structure and sorted binary tree
*/
void addEmployee(char *name, char *employeeId, char *jobTitle, char *supervisorName, char *supervisorId)
{
EmployeeNode *newEmployee = createEmployeeNode(name, employeeId, jobTitle);
char indexKey[40];
sprintf(indexKey, "%s%s", name, employeeId);
indexRoot = insertIndexNode(indexRoot, indexKey, newEmployee);
if (strcmp(supervisorName, "--") == 0)
{
if (root == NULL)
{
root = newEmployee;
}
else
{
fprintf(stderr, "Error: Multiple root employees found.\n");
// Handle this error as needed, maybe free the newEmployee
}
return;
}
EmployeeNode *supervisorNode = NULL;
// Search for the supervisor in the existing organization chart
// A simple linear search here. For larger organizations, a hash map would be more efficient.
// However, for this exercise, we'll keep it straightforward.
EmployeeNode *queue[100]; // Assuming a reasonable maximum number of employees for the queue
int head = 0, tail = 0;
if (root != NULL)
{
queue[tail++] = root;
}
while (head < tail)
{
EmployeeNode *current = queue[head++];
if (strcmp(current->name, supervisorName) == 0 && strcmp(current->employeeId, supervisorId) == 0)
{
supervisorNode = current;
break;
}
EmployeeNode *child = current->firstChild;
while (child != NULL)
{
queue[tail++] = child;
child = child->nextSibling;
}
}
if (supervisorNode != NULL)
{
newEmployee->supervisor = supervisorNode;
if (supervisorNode->firstChild == NULL)
{
supervisorNode->firstChild = newEmployee;
}
else
{
EmployeeNode *sibling = supervisorNode->firstChild;
while (sibling->nextSibling != NULL)
{
sibling = sibling->nextSibling;
}
sibling->nextSibling = newEmployee;
}
}
else
{
fprintf(stderr, "cannot_add %s %s\n", name, employeeId);
// Free the allocated memory for the employee node since it couldn't be added
free(newEmployee);
}
}
/* Prints the corporate hierarchy structure, pre-order
*/
void printCorporateHierarchyHelper(EmployeeNode *node, int level)
{
if (node == NULL)
{
return;
}
for (int i = 0; i < level; i++)
{
printf("...");
}
printf("%s %s %s\n", node->name, node->employeeId, node->jobTitle);
EmployeeNode *child = node->firstChild;
while (child != NULL)
{
printCorporateHierarchyHelper(child, level + 1);
child = child->nextSibling;
}
}
void printCorporateHierarchy()
{
printCorporateHierarchyHelper(root, 0);
}
// Helper function for in-order traversal of the index tree to print sorted list
void printSortedListHelper(IndexNode *root)
{
if (root == NULL)
{
return;
}
printSortedListHelper(root->left);
printf("%s %s %s\n", root->employeePtr->name, root->employeePtr->employeeId, root->employeePtr->jobTitle);
printSortedListHelper(root->right);
}
/* Prints the sorted list of employees
*/
void printSortedList()
{
printSortedListHelper(indexRoot);
}
/* Searches for an employee in the corporate hierarchy structure using the index tree
*/
void searchEmployee(char *name, char *employeeId)
{
char searchKey[40];
sprintf(searchKey, "%s%s", name, employeeId);
IndexNode *current = indexRoot;
while (current != NULL)
{
int cmp = strcmp(searchKey, current->key);
if (cmp < 0)
{
current = current->left;
}
else if (cmp > 0)
{
current = current->right;
}
else
{
EmployeeNode *employee = current->employeePtr;
printf("%s %s %s\n", employee->jobTitle, employee->supervisor ? employee->supervisor->name : "Top", employee->employeeId);
return;
}
}
printf("not_found\n");
}
// Helper function to free the organization chart tree
void freeOrganizationChart(EmployeeNode *node)
{
if (node == NULL)
{
return;
}
EmployeeNode *child = node->firstChild;
while (child != NULL)
{
EmployeeNode *next = child->nextSibling;
freeOrganizationChart(child);
child = next;
}
free(node);
}
// Helper function to free the index tree
void freeIndexTree(IndexNode *node)
{
if (node == NULL)
{
return;
}
freeIndexTree(node->left);
freeIndexTree(node->right);
free(node);
}
/* Free the contents of the datastructures used */
void freeAll()
{
freeOrganizationChart(root);
freeIndexTree(indexRoot);
root = NULL;
indexRoot = NULL;
}
int main()
{
char input[128];
char name[32];
char employeeId[8];
char jobTitle[32];
char supervisorName[32];
char supervisorId[8];
int numEmployees;
int numQuestions;
if (scanf("%d", &numEmployees) != 1)
{
fprintf(stderr, "Error reading number of employees.\n");
return 1;
}
if (scanf("%d", &numQuestions) != 1)
{
fprintf(stderr, "Error reading number of queries.\n");
return 1;
}
for (int i = 0; i < numEmployees; i++) {
if (scanf("%s %s %s %s %s", name, employeeId, jobTitle, supervisorName, supervisorId) != 5)
{
fprintf(stderr, "Error reading employee data.\n");
return 1;
}
addEmployee(name, employeeId, jobTitle, supervisorName, supervisorId);
}
printCorporateHierarchy();
for (int i = 0; i < numQuestions; i++)
{
if (scanf("%s %s", name, employeeId) != 2)
{
fprintf(stderr, "Error reading query.\n");
return 1;
}
searchEmployee(name, employeeId);
}
printSortedList();
freeAll();
return 0;
}

BIN
spring-2025/sen-107/00050/a.out Executable file

Binary file not shown.

View File

@ -0,0 +1,446 @@
/* cmkl_book
*
* Build a social network with basic functionalities
*
* Template for Fundamental Data Structures Lab 2
* Modified by Thanawin Pattanaphol, 2025-05-02
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_ACCOUNTS 1000 // Arbitrary limit for simplicity
#define MAX_FRIENDS 100 // Arbitrary limit for simplicity
// Structure for an account
typedef struct Account
{
char emailAddress[55];
char firstName[25];
char lastName[25];
bool isActive;
int numFriends;
struct Account *friends[MAX_FRIENDS];
} Account;
// Hash table structure
#define HASH_TABLE_SIZE 101 // A prime number for better distribution
typedef struct HashNode
{
char emailAddress[55];
Account *account;
struct HashNode *next;
} HashNode;
HashNode *accountHashTable[HASH_TABLE_SIZE];
int numAccounts = 0;
Account accounts[MAX_ACCOUNTS];
// Hash function
unsigned long hash(const char *str)
{
unsigned long hash = 5381;
int c;
while ((c = *str++))
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
return hash % HASH_TABLE_SIZE;
}
// Find an account by email in the hash table
Account *findAccount(const char *emailAddress)
{
unsigned long index = hash(emailAddress);
HashNode *current = accountHashTable[index];
while (current != NULL)
{
if (strcmp(current->emailAddress, emailAddress) == 0 && current->account->isActive)
{
return current->account;
}
current = current->next;
}
return NULL;
}
// Insert an account into the hash table
void insertAccount(Account *account)
{
unsigned long index = hash(account->emailAddress);
HashNode *newNode = (HashNode *)malloc(sizeof(HashNode));
if (newNode == NULL)
{
perror("Failed to allocate memory for hash node");
exit(EXIT_FAILURE);
}
strcpy(newNode->emailAddress, account->emailAddress);
newNode->account = account;
newNode->next = accountHashTable[index];
accountHashTable[index] = newNode;
}
// Delete an account from the hash table (mark as inactive)
Account *deleteAccountFromTable(const char *emailAddress)
{
unsigned long index = hash(emailAddress);
HashNode *current = accountHashTable[index];
HashNode *prev = NULL;
while (current != NULL)
{
if (strcmp(current->emailAddress, emailAddress) == 0 && current->account->isActive)
{
current->account->isActive = false;
return current->account;
}
prev = current;
current = current->next;
}
return NULL;
}
// Add a new account
void newAccount(char *emailAddress, char *firstName, char *lastName)
{
if (numAccounts >= MAX_ACCOUNTS)
{
fprintf(stderr, "Error: Maximum number of accounts reached.\n");
return;
}
if (findAccount(emailAddress) != NULL) {
printf("Error: Duplicate\n");
return;
}
Account *newAccountPtr = &accounts[numAccounts++];
strcpy(newAccountPtr->emailAddress, emailAddress);
strcpy(newAccountPtr->firstName, firstName);
strcpy(newAccountPtr->lastName, lastName);
newAccountPtr->isActive = true;
newAccountPtr->numFriends = 0;
insertAccount(newAccountPtr);
printf("Success\n");
}
// Delete an account
void deleteAccount(char *emailAddress)
{
Account *accountToDelete = deleteAccountFromTable(emailAddress);
if (accountToDelete == NULL)
{
printf("Error: Not Found\n");
return;
}
// Remove this account from the friend lists of others
for (int i = 0; i < numAccounts; i++)
{
if (accounts[i].isActive)
{
Account *friendAccount = &accounts[i];
for (int j = 0; j < friendAccount->numFriends; j++)
{
if (friendAccount->friends[j] == accountToDelete)
{
// Shift remaining friends to the left
for (int k = j; k < friendAccount->numFriends - 1; k++)
{
friendAccount->friends[k] = friendAccount->friends[k + 1];
}
friendAccount->numFriends--;
break; // Only one instance of the deleted friend
}
}
}
}
printf("Success %s %s\n", accountToDelete->firstName, accountToDelete->lastName);
}
// Make two accounts friends
void addFriend(char *firstEmailAddress, char *secondEmailAddress)
{
Account *account1 = findAccount(firstEmailAddress);
Account *account2 = findAccount(secondEmailAddress);
if (account1 == NULL || account2 == NULL)
{
printf("Error: Account Not Found\n");
return;
}
if (strcmp(firstEmailAddress, secondEmailAddress) == 0)
{
printf("Error: Cant add friend to self\n");
return;
}
bool areFriends = false;
for (int i = 0; i < account1->numFriends; i++)
{
if (account1->friends[i] == account2)
{
areFriends = true;
break;
}
}
if (areFriends)
{
printf("Error: Accounts are already friends\n");
return;
}
if (account1->numFriends < MAX_FRIENDS && account2->numFriends < MAX_FRIENDS)
{
account1->friends[account1->numFriends++] = account2;
account2->friends[account2->numFriends++] = account1;
printf("Success\n");
}
else
{
fprintf(stderr, "Error: Maximum number of friends reached for one of the accounts.\n");
}
}
// Unfriend two accounts
void unfriend(char *firstEmailAddress, char *secondEmailAddress)
{
Account *account1 = findAccount(firstEmailAddress);
Account *account2 = findAccount(secondEmailAddress);
if (account1 == NULL || account2 == NULL)
{
printf("Error: Account Not Found\n");
return;
}
if (strcmp(firstEmailAddress, secondEmailAddress) == 0)
{
printf("Error: Cant unfriend self\n");
return;
}
int index1 = -1, index2 = -1;
for (int i = 0; i < account1->numFriends; i++)
{
if (account1->friends[i] == account2)
{
index1 = i;
break;
}
}
for (int i = 0; i < account2->numFriends; i++)
{
if (account2->friends[i] == account1)
{
index2 = i;
break;
}
}
if (index1 == -1 || index2 == -1)
{
printf("Error: Cant unfriend accounts that are not friends\n");
return;
}
// Remove from account1's friend list
for (int i = index1; i < account1->numFriends - 1; i++)
{
account1->friends[i] = account1->friends[i + 1];
}
account1->numFriends--;
// Remove from account2's friend list
for (int i = index2; i < account2->numFriends - 1; i++)
{
account2->friends[i] = account2->friends[i + 1];
}
account2->numFriends--;
printf("Success\n");
}
// List all friends of an account
void listFriends(char *emailAddress)
{
Account *account = findAccount(emailAddress);
if (account == NULL)
{
printf("Error: Account Not Found\n");
return;
}
if (account->numFriends == 0)
{
printf("No Friend\n");
return;
}
for (int i = 0; i < account->numFriends; i++)
{
printf("%s %s", account->friends[i]->firstName, account->friends[i]->lastName);
if (i < account->numFriends - 1)
{
printf(", ");
}
}
printf("\n");
}
// List friend suggestions for an account
void listSuggestions(char *emailAddress)
{
Account *account = findAccount(emailAddress);
if (account == NULL)
{
printf("Error: Account Not Found\n");
return;
}
if (account->numFriends == 0)
{
printf("No Friend Suggestion\n");
return;
}
Account *suggestions[MAX_ACCOUNTS];
int numSuggestions = 0;
bool isSuggested;
for (int i = 0; i < account->numFriends; i++)
{
Account *friend = account->friends[i];
for (int j = 0; j < friend->numFriends; j++)
{
Account *potentialFriend = friend->friends[j];
// Don't suggest self or existing friends
if (potentialFriend == account) continue;
bool isAlreadyFriend = false;
for (int k = 0; k < account->numFriends; k++)
{
if (account->friends[k] == potentialFriend)
{
isAlreadyFriend = true;
break;
}
}
if (isAlreadyFriend) continue;
// Check if already suggested
isSuggested = false;
for (int k = 0; k < numSuggestions; k++)
{
if (suggestions[k] == potentialFriend)
{
isSuggested = true;
break;
}
}
if (!isSuggested && potentialFriend->isActive)
{
suggestions[numSuggestions++] = potentialFriend;
}
}
}
if (numSuggestions == 0)
{
printf("No Friend Suggestion\n");
return;
}
for (int i = 0; i < numSuggestions; i++)
{
printf("%s %s", suggestions[i]->firstName, suggestions[i]->lastName);
if (i < numSuggestions - 1)
{
printf(", ");
}
}
printf("\n");
}
// Free the contents of the datastructures used
void freeAll()
{
// Accounts array is statically allocated, no need to free individually
// Free hash table nodes
for (int i = 0; i < HASH_TABLE_SIZE; i++)
{
HashNode *current = accountHashTable[i];
while (current != NULL)
{
HashNode *temp = current;
current = current->next;
free(temp);
}
accountHashTable[i] = NULL;
}
numAccounts = 0;
}
int main() {
char input[64]; // Input operation name
char emailAddress[55]; // Email address of a person
char secondEmailAddress[55]; // Email address of another person
char firstName[25]; // First name of the person
char lastName[25]; // First name of the person
int numOperations; // The number of operations.
// Initialize hash table
for (int i = 0; i < HASH_TABLE_SIZE; i++)
{
accountHashTable[i] = NULL;
}
scanf("%d", &numOperations);
for (int i = 0; i < numOperations; i++)
{
scanf("\n%s", input);
if (strcmp(input, "New") == 0)
{
scanf(" %s %s %s", emailAddress, firstName, lastName);
newAccount(emailAddress, firstName, lastName);
}
else if (strcmp(input, "Delete") == 0)
{
scanf(" %s", emailAddress);
deleteAccount(emailAddress);
}
else if (strcmp(input, "Add") == 0)
{
scanf(" %s %s", emailAddress, secondEmailAddress);
addFriend(emailAddress, secondEmailAddress);
}
else if (strcmp(input, "Unfriend") == 0)
{
scanf(" %s %s", emailAddress, secondEmailAddress);
unfriend(emailAddress, secondEmailAddress);
}
else if (strcmp(input, "Friend") == 0)
{
scanf(" %s", emailAddress);
listFriends(emailAddress);
}
else if (strcmp(input, "Suggestion") == 0)
{
scanf(" %s", emailAddress);
listSuggestions(emailAddress);
}
}
freeAll();
return 0;
}