#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct cell
{
struct cell *next;
void *info;
} TCell, *TList;
typedef void (*TFPrintElem)(void*);
typedef void (*TFreeInfo)(void*);
int list_insert(TList *list, void *info, size_t infoSize);
void list_remove(TList *elem, TFreeInfo freeInfo);
void list_destroy(TList *list, TFreeInfo freeInfo);
size_t list_length(TList *list);
void list_print(TList *list, TFPrintElem print_elem);
typedef struct
{
int *key;
void *value;
} TPair;
typedef struct
{
int N;
TList* v;
} THashTable;
int __hashTable_hash(int *key, int N);
int __hashTable_keyCompare(void *keyA, void *keyB);
THashTable* hashTable_new(int N);
void hashTable_destroy(THashTable **ht, TFreeInfo freePair);
int hashTable_insert(THashTable *ht, int *key, void *value, size_t valueSize);
int hashTable_remove(THashTable *ht, int *key, TFreeInfo freePair);
void* hashTable_value(THashTable *ht, int *key);
int hashTable_hasKey(THashTable *ht, int *key);
void hashTable_print(THashTable *ht, TFPrintElem print_elem);
void hashTable_printBucket(THashTable *ht, int bucket, TFPrintElem print_elem);
void free_pair(void *p)
{
TPair *pair = p;
free(pair->key);
free(pair->value);
free(pair);
}
void print_pair(void *p)
{
TPair *pair = p;
printf("(%d %d) ", *pair->key, *(int*)pair->value);
}
int main(void)
{
int command, key, P, N, i;
P = 666013;
freopen("hashuri.in", "r", stdin);
freopen("hashuri.out", "w", stdout);
THashTable *ht = hashTable_new(P);
for (fscanf(stdin, "%d", &N); N; N--)
{
fscanf(stdin, "%d %d", &command, &key);
if (command == 1)
{
int value = 1;
hashTable_insert(ht, &key, &value, sizeof(int));
}
else if (command == 2)
{
hashTable_remove(ht, &key, free_pair);
}
else if (command == 3)
{
printf("%d\n", hashTable_hasKey(ht, &key));
}
}
//hashTable_print(ht, print_pair);
hashTable_destroy(&ht, free_pair);
return 0;
}
int list_insert(TList *list, void *info, size_t infoSize)
{
TList aux = calloc(1, sizeof(TCell));
if (!aux)
{
return 0;
}
aux->info = calloc(1, infoSize);
if (!aux->info)
{
free(aux);
return 0;
}
memcpy(aux->info, info, infoSize);
aux->next = *list;
*list = aux;
return 1;
}
void list_remove(TList *elem, TFreeInfo freeInfo)
{
TList aux = *elem;
if (!aux)
{
return;
}
freeInfo(aux->info);
*elem = aux->next;
free(aux);
}
void list_destroy(TList *list, TFreeInfo freeInfo)
{
while (*list != NULL)
{
list_remove(list, freeInfo);
}
}
size_t list_length(TList *list)
{
size_t lg = 0;
TList p = *list;
for ( ; p != NULL; p = p->next)
{
lg++;
}
return lg;
}
void list_print(TList *list, TFPrintElem print_elem)
{
if (!*list)
{
printf("VIDA\n");
return;
}
for ( ; *list != NULL; list = &(*list)->next)
{
print_elem((*list)->info);
}
printf("\n");
}
int __hashTable_hash(int *key, int N)
{
return *key % N;
}
int __hashTable_keyCompare(void *keyA, void *keyB)
{
return *(int*)keyA - *(int*)keyB;
}
THashTable* hashTable_new(int N)
{
THashTable *ht = calloc(1, sizeof(THashTable));
if (!ht)
{
return NULL;
}
ht->N = N;
ht->v = calloc(N, sizeof(TList));
if (!ht->v)
{
free(ht);
return NULL;
}
return ht;
}
void hashTable_destroy(THashTable **ht, TFreeInfo freePair)
{
int i;
TList l;
for (i = 0; i < (*ht)->N; i++)
{
l = (*ht)->v[i];
list_destroy(&l, freePair);
}
free((*ht)->v);
free(*ht);
*ht = NULL;
}
int hashTable_insert(THashTable *ht, int *key, void *value, size_t valueSize)
{
int p = __hashTable_hash(key, ht->N);
TList *l = &ht->v[p];
int ok = -1;
while (*l != NULL && (ok = __hashTable_keyCompare(((TPair*)(*l)->info)->key, key)) < 0)
{
l = &(*l)->next;
}
if (ok == 0)
{
return 0;
}
TPair *pair = calloc(1, sizeof(TPair));
if (!pair)
{
return -1;
}
pair->key = calloc(1, sizeof(int));
if (!pair->key)
{
free(pair);
return -1;
}
pair->value = calloc(1, valueSize);
if (!pair->value)
{
free(pair->key);
free(pair);
return -1;
}
memcpy(pair->key, key, sizeof(int));
memcpy(pair->value, value, valueSize);
TList aux = calloc(1, sizeof(TCell));
aux->next = *l;
aux->info = pair;
*l = aux;
return 1;
}
int hashTable_remove(THashTable *ht, int *key, TFreeInfo freePair)
{
int p = __hashTable_hash(key, ht->N);
TList *l = &ht->v[p];
int ok = -1;
while (*l != NULL && (ok = __hashTable_keyCompare(((TPair*)(*l)->info)->key, key)) < 0)
{
l = &(*l)->next;
}
if (ok == 0)
{
list_remove(l, freePair);
return 1;
}
return 0;
}
void* hashTable_value(THashTable *ht, int *key)
{
int p = __hashTable_hash(key, ht->N);
TList *l = &ht->v[p];
int ok = -1;
while (*l != NULL && (ok = __hashTable_keyCompare(((TPair*)(*l)->info)->key, key)) < 0)
{
l = &(*l)->next;
}
if (ok == 0)
{
return ((TPair*)(*l)->info)->value;
}
return NULL;
}
int hashTable_hasKey(THashTable *ht, int *key)
{
int p = __hashTable_hash(key, ht->N);
TList *l = &ht->v[p];
int ok = -1;
while (*l != NULL && (ok = __hashTable_keyCompare(((TPair*)(*l)->info)->key, key)) < 0)
{
l = &(*l)->next;
}
return (ok == 0);
}
void hashTable_print(THashTable *ht, TFPrintElem print_elem)
{
int i;
TList l;
for (i = 0; i < ht->N; i++)
{
l = ht->v[i];
if (!l)
{
continue;
}
printf("%d: ", i);
list_print(&l, print_elem);
}
}
void hashTable_printBucket(THashTable *ht, int bucket, TFPrintElem print_elem)
{
if (bucket >= ht->N)
{
return;
}
TList *l = &ht->v[bucket];
list_print(l, print_elem);
}