/* License: AGPLv3 or later. https://www.gnu.org/licenses/licenses.html
 * 
 * Exercise 5 - Hash Map (Week 6)
 * Name: Manish
 * Student Login: *****
 * 
 * Compile as:
 * $ gcc -std=c11 -Wall -o ex5 ex5.c
 */ 

#include <stdio.h>
#include <stdlib.h>

typedef struct entry
{
    int data;
    struct entry * next;
} entry;

/* This method of array initialization is GNU C extension and
 * may not work with other compilers. Not even g++
 */
entry hashmap[100] = {[0 ... 99] = (entry){.data = -1, .next = NULL}};
int size = 0;

int abs(int i);

int main(void)
{    
    printf("Enter file name: ");
    char filename[257];
    // Assuming filename/file path won't be longer than 256 characters
    scanf("%256s", filename);

    FILE* file = fopen(filename, "r");
    if (!file)
    {
        perror(filename);
        exit(EXIT_FAILURE);
    }
    
    int num;
    int key;
    entry * node;
    while (fscanf(file, "%d", &num) != EOF)
    {
        key = abs(num%100);
        if (hashmap[key].data == -1) // empty
            hashmap[key].data = num;
        else // chaining
        {
            node = &hashmap[key];
            while (node->next != NULL)
            {
                node = node->next;
            }
            entry * new_entry = malloc(sizeof(entry));
            new_entry->data = num;
            new_entry->next = NULL;
            node->next = new_entry;
        }
    }

    int empty = 0;
    for (int i=0; i < 100; i++)
    {
        if (hashmap[i].data == -1)
            empty++;
    }

    int max_chain = 0;
    int current_chain = 0;
    for (int i=0; i < 100; i++)
    {
        if (hashmap[i].data == -1) // if empty, chain is 0
            continue;
        current_chain = 1; // if not empty, chain is at least 1 long
        node = hashmap[i].next;
        while (node != NULL)
        {
            current_chain++;
            node = node->next;
        }
        if (current_chain > max_chain)
            max_chain = current_chain;
    }
    
    printf("Empty Entries: %d\nLongest Chain: %d\n", empty, max_chain);
    
    fclose(file);

    return 0;
}

int abs(int i)
{
    if (i < 0)
        return -i;
    return i;
}
