Advertisement
Guest User

Untitled

a guest
Apr 4th, 2020
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 41.71 KB | None | 0 0
  1. /* Programmatismos2
  2. ---project2.c    : mia pio polyploki basi dedomenwn me dynamiki desmeusi mnimis.
  3. ---Onomatepwnymo : Sarafoglou Dimitrios
  4. ---AEM           : 02993
  5. */
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11. #include <signal.h>
  12.  
  13. struct COURSE_CODE
  14. {
  15.     short unsigned int code;
  16.     struct COURSE_CODE *next;
  17. };
  18. typedef struct COURSE_CODE course_code;
  19.  
  20. struct ENTRY
  21. {
  22.     long unsigned int AEM;
  23.     short unsigned int courses;
  24.     char name[64];
  25.     struct ENTRY *next_student;
  26.     struct ENTRY *previous_student;
  27.     course_code *root;
  28. };
  29. typedef struct ENTRY entry;
  30.  
  31. typedef struct
  32. {
  33.     entry **entries;
  34.     entry **hash_table;
  35.     int size;
  36.     int hashTable_size;
  37.     int capacity;
  38.     int increaser;
  39.     int decreaser;
  40.     int isSorted;
  41. } entry_list;
  42.  
  43. /* Ylopoihsh synarthsewn. */
  44.  
  45. /* Initalization functions. */
  46. void init_entry_list(entry_list *el)
  47. {
  48.     el->entries = NULL;
  49.     el->capacity = 0;
  50.     el->size = 0;
  51.     el->increaser = 0;
  52.     el->decreaser = 0;
  53.     el->isSorted = 0;
  54. }
  55.  
  56. void init_course_list(entry_list *el)
  57. {
  58.     int i;
  59.     for (i=0; i<el->size; i++)
  60.         el->entries[i]->root = NULL;
  61. }
  62.  
  63.  
  64. void hash_table_init(entry_list *el)
  65. {
  66.     int i;
  67.     for (i=0; i<el->hashTable_size; i++)
  68.     {
  69.         el->hash_table[i] = (entry *) malloc(sizeof(entry));
  70.         if (el->hash_table[i] == NULL)
  71.             exit(0);   /* No memory for allocation. */
  72.  
  73.         el->hash_table[i]->previous_student = el->hash_table[i];
  74.         el->hash_table[i]->next_student = el->hash_table[i];
  75.     }
  76. }
  77.  
  78. void deleteHashTable(entry_list *el)
  79. {
  80.     int i;
  81.     for (i=0; i<el->hashTable_size; i++)
  82.         free(el->hash_table[i]);
  83.     free(el->hash_table);
  84. }
  85.  
  86. void clear_hash_table(entry_list *el)
  87. {
  88.     free(el->hash_table);
  89. }
  90.  
  91. long unsigned int hash(char *str)
  92. {
  93.     long unsigned int hash = 5381;
  94.     int c;
  95.  
  96.     while ((c = *str++))
  97.         hash = ((hash << 5) + hash) + c;
  98.  
  99.     return hash;
  100. }
  101.  
  102.  
  103. /* Binary search or linear search (in one). */
  104. int student_search(entry_list *el, long unsigned int AEM)
  105. {
  106.     int i, middle, from = 0, to = el->size-1;
  107.  
  108.     if (el->isSorted == 0)
  109.     {
  110.         /* Edw ta AEM den einai taksinomimena, ara efarmozoume linear search. */
  111.         for (i=0; i<el->size; i++)
  112.         {
  113.             if (AEM == el->entries[i]->AEM)
  114.             {
  115.                 return 1;
  116.             }
  117.         }
  118.         return 0;
  119.     }
  120.     else
  121.     {
  122.         /* Edw o pinakas me ta AEM einai taksinomimenos, opote efarmozoume binary search. */
  123.         while(from <= to)
  124.         {
  125.             middle = (to + from) / 2;
  126.             if (el->entries[middle]->AEM == AEM)
  127.             {
  128.                 return 1;
  129.             }
  130.             else if (el->entries[middle]->AEM > AEM)
  131.             {
  132.                 to = middle - 1;
  133.             }
  134.             else
  135.             {
  136.                 from = middle + 1;
  137.             }
  138.         }
  139.         return 0;
  140.     }
  141. }
  142.  
  143. int find_cmps(entry_list *el, long unsigned int AEM)
  144. {
  145.     int i, middle, from = 0, to = el->size-1, comparisons = 0;
  146.     if (el->isSorted == 0)
  147.     {
  148.         for (i=0; i<el->size; i++)
  149.         {
  150.             if (AEM == el->entries[i]->AEM)
  151.             {
  152.                 comparisons++;
  153.                 break;
  154.             }
  155.             else
  156.             {
  157.                 comparisons++;
  158.                 continue;
  159.             }
  160.         }
  161.         return comparisons;
  162.     }
  163.     else
  164.     {
  165.         while (from <= to)
  166.         {
  167.             middle = (to + from) / 2;
  168.             if (el->entries[middle]->AEM == AEM)
  169.             {
  170.                 comparisons++;
  171.                 return comparisons;
  172.             }
  173.             comparisons++;
  174.             if (el->entries[middle]->AEM > AEM)
  175.             {
  176.                 comparisons++;
  177.                 to = middle - 1;
  178.             }
  179.             else
  180.             {
  181.                 comparisons++;
  182.                 from = middle + 1;
  183.             }
  184.         }
  185.         return comparisons;
  186.     }
  187. }
  188.  
  189.  
  190. /* Find comparisons while sorting function.
  191. H synartisi epistrefei to plithos twn sygkrisewn. */
  192. int insertion_sort(entry_list *el, long unsigned int AEM)
  193. {
  194.     int i, step, key_aem, key_course, comparisons = 0;
  195.     char key_name[64] = {'\0'};
  196.     for (step = 1; step < el->size; step++)   /* step = 1: afinoume to prwto stoixeio, giati theoroume oti einai sorted. */
  197.     {
  198.         i = step - 1;
  199.         key_aem = el->entries[step]->AEM;
  200.         key_course = el->entries[step]->courses;
  201.         strcpy(key_name, el->entries[step]->name);
  202.  
  203.         comparisons++;
  204.  
  205.         while(i>=0 && key_aem < el->entries[i]->AEM)
  206.         {
  207.             if (i == 0)
  208.             {
  209.                 comparisons--;
  210.             }
  211.             comparisons++;
  212.             el->entries[i+1]->AEM = el->entries[i]->AEM;
  213.             el->entries[i+1]->courses = el->entries[i]->courses;
  214.             strcpy(el->entries[i+1]->name, el->entries[i]->name);
  215.             i--;
  216.  
  217.             if (i < 0)
  218.             {
  219.                 break;
  220.             }
  221.         }
  222.         el->entries[i+1]->AEM = key_aem;
  223.         el->entries[i+1]->courses = key_course;
  224.         strcpy(el->entries[i+1]->name, key_name);
  225.     }
  226.  
  227.     el->isSorted = 1;  /* Sorted. */
  228.  
  229.     return comparisons;
  230. }
  231.  
  232. /* Swap. */
  233. void swap(course_code *a, course_code *b)
  234. {
  235.     int temp;
  236.     temp = a->code;
  237.     a->code = b->code;
  238.     b->code = temp;
  239. }
  240.  
  241. /* Sorting of nodes(codes of courses). */
  242. void course_sorting(course_code *root)
  243. {
  244.     int cont;
  245.     course_code *ptr1, *ptr2 = NULL;
  246.  
  247.     /* Tsekaroume an i lista mas einai keni. */
  248.     if (root == NULL)
  249.         return;
  250.  
  251.     do
  252.     {
  253.         cont = 0;
  254.         ptr1 = root;
  255.  
  256.         while (ptr1->next != ptr2)
  257.         {
  258.             if (ptr1->code > ptr1->next->code)
  259.             {
  260.                 swap(ptr1,ptr1->next);
  261.                 cont = 1;
  262.             }
  263.             ptr1 = ptr1->next;
  264.         }
  265.         ptr2 = ptr1;
  266.     }  while(cont);
  267. }
  268.  
  269.  
  270.  
  271. /* Find position of student function
  272. H synartisi epistrefei tin thesi tou foititi mesa stin agenta.
  273. */
  274. int find_pos_of_student(entry_list *el, long unsigned int AEM)
  275. {
  276.     int position;
  277.     for (position = 0; (position < el->capacity) && (el->entries[position] != NULL); position++)
  278.     {
  279.         if (el->entries[position]->AEM == AEM)
  280.             break;
  281.     }
  282.     return position;
  283. }
  284.  
  285. /* Hash Table's content is printed. */
  286. void print_hash_table(entry_list *el)
  287. {
  288.     entry *current;
  289.     course_code *current_course;
  290.  
  291.     int i;
  292.     for (i=0; i<el->hashTable_size; i++)
  293.     {
  294.         if (el->hash_table[i]->next_student == el->hash_table[i])   /* Periptwsi opou exoume keno bucket. */
  295.             continue;
  296.         for (current=el->hash_table[i]->next_student; current!=el->hash_table[i]; current=current->next_student)
  297.         {
  298.             printf("----------------------------\n");
  299.             printf("[Position in the Hash Table]: %d\n", i);
  300.             printf("[Name]:                       %s\n", current->name);
  301.             printf("[AEM]:                        %lu\n", current->AEM);
  302.             printf("[Courses]:                    %hu\n", current->courses);
  303.             printf("%s is registered in these courses:\n", current->name);
  304.             for (current_course=current->root; current_course!=NULL; current_course=current_course->next)
  305.             {
  306.                 printf("%hu\n", current_course->code);
  307.             }
  308.         }
  309.     }
  310. }
  311.  
  312. /* Find student in a circular list function.
  313. 1: If YES
  314. 0: If NO
  315. */
  316. int student_search_circular_list(entry_list *el, long unsigned int AEM, char name[])
  317. {
  318.     entry *current;
  319.     int position_in_HT = hash(name) % (el->hashTable_size);
  320.  
  321.     el->hash_table[position_in_HT]->AEM = AEM;
  322.     for (current=el->hash_table[position_in_HT]->next_student; current!=el->hash_table[position_in_HT]; current=current->next_student)
  323.     {
  324.         if (current->AEM == AEM)
  325.             return 1; /* O foititis yparxei idi sto hash table. */
  326.     }
  327.     return 0;
  328. }
  329.  
  330. /* Rehashing functions. */
  331. void rehashing(entry_list *el)
  332. {
  333.     /* Diagrafoume to hash table. */
  334.     clear_hash_table(el);
  335.  
  336.     /* Desmeuoume ena neo me allagmeno megethos.
  337.     To megethos eksartatai apo to load factor opote den allazei edw. */
  338.     el->hash_table = (entry **) malloc(sizeof(entry *) * el->hashTable_size);
  339.     if (el->hash_table == NULL)
  340.         exit(0);  /* No memory for allocation. */
  341.  
  342.     /* Kanoume arxikopoiisi tou hash table.
  343.     Prepei na exoume kai ta sentinels. */
  344.     hash_table_init(el);
  345.  
  346.     /* Edw ginetai to rehashing. */
  347.     entry *current, *temp;
  348.     int i, position_in_HT;
  349.     for (i=0; i<el->size; i++)
  350.     {
  351.         /* Edw vriskoume ti nea thesi tou entry sto hash table. */
  352.         position_in_HT = hash(el->entries[i]->name) % el->hashTable_size;
  353.  
  354.         /* Case1: Periptwsi opou to bucket me to sentinel einai keno. */
  355.         if (el->hash_table[position_in_HT]->next_student == el->hash_table[position_in_HT])
  356.         {
  357.             /* Apla eisagoume to entry xwris kapoion periorismo. */
  358.             el->hash_table[position_in_HT]->next_student = el->entries[i];
  359.             el->entries[i]->previous_student = el->hash_table[position_in_HT];
  360.             el->entries[i]->next_student = el->hash_table[position_in_HT];
  361.         }
  362.         else
  363.         {
  364.             /* Case2: Periptwsi opou prepei o foititis na mpei sth swsth thesi (sortarismeni lista diladi). */
  365.             for (current=el->hash_table[position_in_HT]->next_student; current!=el->hash_table[position_in_HT]; current=current->next_student)
  366.             {
  367.                 if (strcmp(el->entries[i]->name, current->name) < 0)
  368.                     break;
  369.                 if (strcmp(el->entries[i]->name, current->name) == 0)
  370.                 {
  371.                     if (el->entries[i]->AEM < current->AEM)
  372.                         break;
  373.                     else
  374.                     {
  375.                         while(strcmp(el->entries[i]->name, current->name) == 0)
  376.                         {
  377.                             current = current->next_student;
  378.                             if (el->entries[i]->AEM < current->AEM)
  379.                                 break;
  380.                         }
  381.                         break;
  382.                     }
  383.                 }
  384.             }
  385.             /* Se auto to simeio ousiastika exoume enan deikti current pou deixnei se mia sygkekrimeni thesi sti dipli lista mas. */
  386.             /* Case1: Periptwsi opou den eftasa sto telos tis listas.
  387.             O foititis mpainei kapou endiamesa (H sthn arxh h sti mesi.) */
  388.             if (current != el->hash_table[position_in_HT])
  389.             {
  390.                 el->entries[i]->next_student = current;
  391.                 el->entries[i]->previous_student = current->previous_student;
  392.                 current->previous_student = el->entries[i];
  393.                 current->previous_student->previous_student->next_student = current->previous_student;
  394.             }
  395.             else
  396.             {
  397.                 /* Case2: Periptwsi opou h eggrafi mpainei sto telos tis diplis listas.
  398.                 Emeis xreiazomaste enan deikti sto teleutaio stoixeio tis listas. */
  399.                 for (temp=el->hash_table[position_in_HT]->next_student; temp->next_student!=el->hash_table[position_in_HT]; temp=temp->next_student);
  400.                 el->entries[i]->previous_student = temp;
  401.                 el->entries[i]->next_student = temp->next_student;
  402.                 temp->next_student = el->entries[i];
  403.             }
  404.         }
  405.     }
  406. }
  407.  
  408. void rehashing2(entry_list *el, long unsigned int AEM)
  409. {
  410.     /* Diagrafoume to hash table. */
  411.     clear_hash_table(el);
  412.  
  413.     /* Desmeuoume ena neo me allagmeno megethos.
  414.     To megethos eksartatai apo to load factor opote den allazei edw. */
  415.     el->hash_table = (entry **) malloc(sizeof(entry *) * el->hashTable_size);
  416.     if (el->hash_table == NULL)
  417.         exit(0);  /* No memory for allocation. */
  418.  
  419.     /* Kanoume arxikopoiisi tou hash table.
  420.     Prepei na exoume kai ta sentinels. */
  421.     hash_table_init(el);
  422.  
  423.     /* Edw ginetai to rehashing. */
  424.     entry *current, *temp;
  425.     int i, position_in_HT, position = find_pos_of_student(el, AEM);
  426.     for (i=0; i<el->size; i++)
  427.     {
  428.         if (i == position)
  429.             continue;   /* Auto pou svisame den theloume na to ksanavaloume. */
  430.         /* Edw vriskoume ti nea thesi tou entry sto hash table. */
  431.         position_in_HT = hash(el->entries[i]->name) % el->hashTable_size;
  432.  
  433.         /* Case1: Periptwsi opou to bucket me to sentinel einai keno. */
  434.         if (el->hash_table[position_in_HT]->next_student == el->hash_table[position_in_HT])
  435.         {
  436.             /* Apla eisagoume to entry xwris kapoion periorismo. */
  437.             el->hash_table[position_in_HT]->next_student = el->entries[i];
  438.             el->entries[i]->previous_student = el->hash_table[position_in_HT];
  439.             el->entries[i]->next_student = el->hash_table[position_in_HT];
  440.         }
  441.         else
  442.         {
  443.             /* Case2: Periptwsi opou prepei o foititis na mpei sth swsth thesi (sortarismeni lista diladi). */
  444.             for (current=el->hash_table[position_in_HT]->next_student; current!=el->hash_table[position_in_HT]; current=current->next_student)
  445.             {
  446.                 if (strcmp(el->entries[i]->name, current->name) < 0)
  447.                     break;
  448.                 if (strcmp(el->entries[i]->name, current->name) == 0)
  449.                 {
  450.                     if (el->entries[i]->AEM < current->AEM)
  451.                         break;
  452.                     else
  453.                     {
  454.                         while(strcmp(el->entries[i]->name, current->name) == 0)
  455.                         {
  456.                             current = current->next_student;
  457.                             if (el->entries[i]->AEM < current->AEM)
  458.                                 break;
  459.                         }
  460.                         break;
  461.                     }
  462.                 }
  463.             }
  464.             /* Se auto to simeio ousiastika exoume enan deikti current pou deixnei se mia sygkekrimeni thesi sti dipli lista mas. */
  465.             /* Case1: Periptwsi opou den eftasa sto telos tis listas.
  466.             O foititis mpainei kapou endiamesa (H sthn arxh h sti mesi.) */
  467.             if (current != el->hash_table[position_in_HT])
  468.             {
  469.                 el->entries[i]->next_student = current;
  470.                 el->entries[i]->previous_student = current->previous_student;
  471.                 current->previous_student = el->entries[i];
  472.                 current->previous_student->previous_student->next_student = current->previous_student;
  473.             }
  474.             else
  475.             {
  476.                 /* Case2: Periptwsi opou h eggrafi mpainei sto telos tis diplis listas.
  477.                 Emeis xreiazomaste enan deikti sto teleutaio stoixeio tis listas. */
  478.                 for (temp=el->hash_table[position_in_HT]->next_student; temp->next_student!=el->hash_table[position_in_HT]; temp=temp->next_student);
  479.                 el->entries[i]->previous_student = temp;
  480.                 el->entries[i]->next_student = temp->next_student;
  481.                 temp->next_student = el->entries[i];
  482.             }
  483.         }
  484.     }
  485. }
  486.  
  487.  
  488. /* Insert name to hash table function.
  489. Return  0: An o foititis iparxei idi sti lista.
  490. Return -1: An o foititis den yparxei sto database.
  491. Return  1: Success.
  492. */
  493. void entry_insert_to_HTable2(entry_list *el, long unsigned int AEM, char name[])
  494. {
  495.     entry *current;
  496.     float load_factor = el->size / el->hashTable_size;
  497.  
  498.     int position_in_HT = hash(name) % (el->hashTable_size); /* Thesi ston pinaka hash. */
  499.     int position = find_pos_of_student(el, AEM); /* Thesi ston pinaka twn entries. */
  500.  
  501.     /* Periptwsi opou i lista mas einai keni. */
  502.     if (el->hash_table[position_in_HT]->next_student == el->hash_table[position_in_HT])
  503.     {
  504.         el->hash_table[position_in_HT]->next_student = el->entries[position];
  505.         el->entries[position]->previous_student = el->hash_table[position_in_HT];
  506.         el->entries[position]->next_student = el->hash_table[position_in_HT];
  507.     }
  508.     else  /* Periptwsi opou i lista den einai keni. */
  509.     {
  510.         /* Mesa edw kanw to sorting.
  511.         Den pairnw periptwsi otan exw keni lista , giati den ginetai kapoiou eidous sortarisma. */
  512.         for (current=el->hash_table[position_in_HT]->next_student; current!=el->hash_table[position_in_HT]; current=current->next_student)
  513.         {
  514.             if (strcmp(name, current->name) < 0)
  515.                 break;
  516.             if (strcmp(name, current->name) == 0)
  517.             {
  518.                 if (AEM < current->AEM)
  519.                     break;
  520.                 else   /* Prepei na ginei enas elegxos gia to an meta exw entries me idia onomata. */
  521.                 {
  522.                     while(strcmp(name, current->name) == 0)
  523.                     {
  524.                         /* Ousiastika prepei na ftasw sto akrivws epomeno entry pou exei diaforetiko onoma. */
  525.                         current = current->next_student;
  526.                         if (AEM < current->AEM)
  527.                             break;
  528.                     }
  529.                     break;
  530.                 }
  531.             }
  532.         }
  533.         /* Periptwsi opou i eggrafi mpainei stin arxi h se endiameso simeio tis listas tou bucket se sygkekrimeni thesi tou hash table. */
  534.         if (current != el->hash_table[position_in_HT])
  535.         {
  536.             el->entries[position]->next_student = current;
  537.             el->entries[position]->previous_student = current->previous_student;
  538.             current->previous_student = el->entries[position];
  539.             el->entries[position]->previous_student->next_student = el->entries[position];
  540.         }
  541.         else
  542.         {
  543.             /* Periptwsi opou prepei i eggrafi na mpei sto telos tis listas. */
  544.             for (current=el->hash_table[position_in_HT]->next_student; current->next_student!=el->hash_table[position_in_HT]; current=current->next_student);
  545.  
  546.             el->entries[position]->previous_student = current;
  547.             el->entries[position]->next_student = current->next_student;
  548.             current->next_student = el->entries[position];
  549.         }
  550.     }
  551.  
  552.     if (load_factor >= 4)
  553.     {
  554.         el->hashTable_size = el->hashTable_size * 2;
  555.         rehashing(el);
  556.     }
  557. }
  558.  
  559. void entry_remove_from_HT2(entry_list *el, long unsigned int AEM, char name[], int StartingHT_size)
  560. {
  561.     float load_factor = el->size / el->hashTable_size;
  562.     entry *current;
  563.  
  564.     int position_in_HT = hash(name) % el->hashTable_size;
  565.     for (current=el->hash_table[position_in_HT]->next_student; current->AEM!=AEM; current=current->next_student);
  566.  
  567.     if (current != el->hash_table[position_in_HT])
  568.     {
  569.         /* Parakampsi komvou. */
  570.         /* Periptwsi opou eksetazoume an to stoixeio pou theloume na diagrapsoume einai sto telos tis listas. */
  571.         if (current->next_student == el->hash_table[position_in_HT])
  572.         {
  573.             current->previous_student->next_student = el->hash_table[position_in_HT];
  574.             current->next_student = NULL;
  575.             current->previous_student = NULL;
  576.         }
  577.         else
  578.         {
  579.             current->previous_student->next_student = current->next_student;
  580.             current->next_student->previous_student = current->previous_student;
  581.             current->previous_student = NULL;
  582.             current->next_student = NULL;
  583.         }
  584.     }
  585.  
  586.     if (load_factor == 1)
  587.     {
  588.         if (el->hashTable_size / 2 < StartingHT_size)
  589.             el->hashTable_size = StartingHT_size;   /* To megethos tou epanaferetai sto arxiko. */
  590.         else
  591.             el->hashTable_size = el->hashTable_size / 2;
  592.  
  593.         rehashing2(el, AEM);
  594.     }
  595. }
  596.  
  597.  
  598.  
  599. void sort_circ_list(entry_list *el, char name[])
  600. {
  601.     entry *current, *index;
  602.  
  603.     long unsigned int temp_AEM;
  604.     short unsigned int temp_courses;
  605.     char temp_name[64];
  606.     course_code *temp_root;
  607.  
  608.     /* Prepei na vroume ti thesi sto hash table tis listas tin opoia theloume na sortaroume. */
  609.     int position_in_HT = hash(name) % el->hashTable_size;
  610.  
  611.     current = el->hash_table[position_in_HT]->next_student;
  612.  
  613.     do {
  614.         index = current->next_student;
  615.         while(index != el->hash_table[position_in_HT]->next_student)
  616.         {
  617.             if (strcmp(current->name, index->name) > 0)
  618.             {
  619.                 /* Edw tha ginei to swapping metaksy twn entries. */
  620.                 temp_AEM = current->AEM;
  621.                 current->AEM = index->AEM;
  622.                 index->AEM = temp_AEM;
  623.  
  624.                 temp_courses = current->courses;
  625.                 current->courses = index->courses;
  626.                 index->courses = temp_courses;
  627.  
  628.                 strcpy(temp_name, current->name);
  629.                 strcpy(current->name, index->name);
  630.                 strcpy(index->name, temp_name);
  631.  
  632.                 temp_root = current->root;
  633.                 current->root = index->root;
  634.                 index->root = temp_root;
  635.             }
  636.             else if (strcmp(current->name, index->name) == 0)
  637.             {
  638.                 /* Edw sortaroume me basi to AEM. */
  639.                 if (current->AEM > index->AEM)
  640.                 {
  641.                     temp_AEM = current->AEM;
  642.                     current->AEM = index->AEM;
  643.                     index->AEM = temp_AEM;
  644.  
  645.                     temp_courses = current->courses;
  646.                     current->courses = index->courses;
  647.                     index->courses = temp_courses;
  648.  
  649.                     temp_root = current->root;
  650.                     current->root = index->root;
  651.                     index->root = temp_root;
  652.  
  653.                     /* Ta onomata den xreiazontai swapping, giati einia idia. */
  654.                 }
  655.             }
  656.             index = index->next_student;
  657.         }
  658.         current = current->next_student;
  659.  
  660.     } while(current->next_student != el->hash_table[position_in_HT]->next_student);
  661. }
  662.  
  663.  
  664. /* Add student function.
  665. H synartisi auti epistrefei 1: An o foititis prostethike epityxws.
  666. H synartisi auti epistrefei 0: An o foititis yparxei idi.
  667. */
  668. int add(entry_list *el, long unsigned int AEM, short unsigned int courses, char name[])
  669. {
  670.     entry **temp;
  671.     int i, length;
  672.     int finder;
  673.  
  674.     finder = student_search(el, AEM);
  675.     if (finder == 1)
  676.     {
  677.         /* Simainei oti o foititis yparxei idi. */
  678.         return 0;
  679.     }
  680.     else
  681.     {
  682.         /* Prwta eksetazoume tin periptwsi opou den yparxei xwros ston pinaka deiktwn. */
  683.         if (el->capacity == el->size)
  684.         {
  685.             temp = (entry **) realloc(el->entries, (el->capacity + el->increaser) * sizeof(entry *));
  686.             if (temp == NULL)
  687.             {
  688.                 /* No memory for allocation!\n */
  689.                 exit(0);
  690.             }
  691.  
  692.             /* Desmeuoume xwro gia tin yparksi neas eggrafis. */
  693.             entry *student;
  694.             student = (entry *) malloc(sizeof(entry));
  695.             if (student == NULL)
  696.             {
  697.                 /* No memory for allocation... */
  698.                 exit(0);
  699.             }
  700.  
  701.             el->entries = temp;
  702.             /* for (i=el->capacity; i<(el->capacity+el->increaser); i++)
  703.             {
  704.                 el->entries[i]->root = NULL;
  705.             }*/
  706.             el->capacity += el->increaser;
  707.             el->entries[el->size] = student;
  708.             el->entries[el->size]->AEM = AEM;
  709.             el->entries[el->size]->courses = courses;
  710.  
  711.             /* Metatropi tou onomatos se kefalaia. */
  712.             length = strlen(name);
  713.             for (i=0; i<length; i++)
  714.             {
  715.                 name[i] = toupper(name[i]);
  716.             }
  717.             strcpy(el->entries[el->size]->name, name);
  718.             el->entries[el->size]->root = NULL;
  719.             //el->entries[el->size]->next_student = NULL;
  720.  
  721.             el->size++;
  722.             el->isSorted = 0;
  723.  
  724.             entry_insert_to_HTable2(el, AEM, name);
  725.             //sort_circ_list(el, name);
  726.             return 1;
  727.         }
  728.         /* Twra eksetazoume tin periptwsi opou yparxei eleutheros xwros ston pinaka deiktwn. */
  729.  
  730.         /* Desmeuw xwro gia mia nea eggrafi. */
  731.         entry *student;
  732.         student = (entry *) malloc(sizeof(entry));
  733.         if (student == NULL)
  734.         {
  735.             /* No memory for allocation... */
  736.             exit(0);
  737.         }
  738.  
  739.         el->entries[el->size] = student;
  740.         el->entries[el->size]->AEM = AEM;
  741.         el->entries[el->size]->courses = courses;
  742.         el->entries[el->size]->root = NULL;
  743.         el->entries[el->size]->next_student = NULL;
  744.  
  745.         /* Metatropi tou onomatos se kefalaia. */
  746.         length = strlen(name);
  747.         for (i=0; i<length; i++)
  748.         {
  749.             name[i] = toupper(name[i]);
  750.         }
  751.         strcpy(el->entries[el->size]->name, name);
  752.  
  753.         el->size++;
  754.         el->isSorted = 0;
  755.  
  756.         entry_insert_to_HTable2(el, AEM, name);
  757.         //sort_circ_list(el, name);
  758.         return 1;
  759.     }
  760. }
  761.  
  762. /* Find course function.
  763. H synartisi epistrefei 1: an to mathima vrethike.
  764. H synartisi epistrefei 0: an to mathima den vrethike. */
  765. int find_course(entry_list *el, short unsigned int code, long unsigned int AEM)
  766. {
  767.       course_code *current;
  768.  
  769.       if (student_search(el, AEM) == 0) /* Pou Simainei oti o foititis den vrethike. */
  770.           return 0; /* Oute kai to mathima tha yparxei epomenws. */
  771.  
  772.       /* An o foititis yparxei, prepei na vroume ti thesi tou. */
  773.       int position = find_pos_of_student(el, AEM);
  774.       for (current=el->entries[position]->root; current!=NULL; current=current->next)
  775.       {
  776.           if (current->code == code)
  777.               return 1;
  778.       }
  779.       return 0;
  780. }
  781.  
  782.  
  783. /* isreg function.
  784. Epistrefetai: 1 an einai eggegrammenos.
  785.               0 an den yparxei sto database.
  786.              -1 an den einai eggegrammenos.*/
  787. int isRegistered(entry_list *el, short unsigned int code, long unsigned int AEM)
  788. {
  789.     int finder = student_search(el, AEM);
  790.     if (finder == 0)
  791.         return -1;
  792.  
  793.     int position = find_pos_of_student(el, AEM);
  794.  
  795.     course_code *current;
  796.     for (current=el->entries[position]->root; current!=NULL; current=current->next)
  797.     {
  798.         if (current->code == code)
  799.             return 1;
  800.     }
  801.     return 0;
  802. }
  803.  
  804.  
  805. /* Insert course node to the list function (Eggrafi foititi se mathima).
  806. H synartisi auti epistrefei 1 an i eisagwgi tou node stin lista egine me epityxia,
  807. alliws 0 se periptwsi pou o mathitis den vrisketai sto database kai -1 se periptwsi
  808. pou einai idi eggegrammenos. */
  809. int course_insert(entry_list *el, short unsigned int code, long unsigned int AEM)
  810. {
  811.     int finder = student_search(el, AEM);
  812.     if (finder == 0)  /* Den yparxei o mathitis. */
  813.         return 0;  /* Den mporw na prosthesw mathima. */
  814.  
  815.     int find_crs = find_course(el, code, AEM);
  816.     if (find_crs == 1) /* O mathitis einai eggegrammenos. */
  817.         return -1;
  818.  
  819.     int position = find_pos_of_student(el, AEM);
  820.  
  821.     course_code *current;
  822.     current = (course_code *) malloc(sizeof(course_code));
  823.     if (current == NULL)
  824.         exit(0);  /* No memory for allocation. */
  825.  
  826.     current->code = code;
  827.     current->next = el->entries[position]->root;
  828.     el->entries[position]->root = current;
  829.  
  830.     /* Twra sortaroume. */
  831.     course_sorting(el->entries[position]->root);
  832.  
  833.     return 1; /* inserted. */
  834.  
  835. }
  836.  
  837. /* Remove course function.
  838. H synartisi auti epistrefei 1: an petyxe h apomakrynsi komvou.
  839. H synartisi auti epistrefei 0: an o foititis den yparxe sto database.
  840. H synartisi auti epistrefei -1: an to mathima pou theloume na afairesoume den yparxei.*/
  841. int remove_course(entry_list *el, short unsigned int code, long unsigned int AEM)
  842. {
  843.     int finder = student_search(el, AEM);
  844.     if (finder == 0) /* O foititis den yparxei sto database. */
  845.         return 0;
  846.  
  847.     course_code *current, *previous;
  848.     int position = find_pos_of_student(el, AEM);
  849.     for (current=el->entries[position]->root; current!=NULL; previous=current,current=current->next)
  850.     {
  851.         if (current->code == code)
  852.             break;
  853.     }
  854.     if (current != NULL)
  855.     {
  856.         if (current == el->entries[position]->root)
  857.             el->entries[position]->root = current->next;
  858.         else
  859.             previous->next = current->next;
  860.     }
  861.     else
  862.     {
  863.         return -1;
  864.     }
  865.     free(current);
  866.     return 1;   /* removed. */
  867. }
  868.  
  869.  
  870.  
  871. /* Remove student function
  872. H synartisi auti epistrefei 1: an o foititis afairethike me epityxia.
  873. H synartisi auti epistrefei 0: an to AEM to foititi den yparxei sti lista h an exw kenh lista me entries h an h apodeseusi tou pinaka apetyxe.
  874. */
  875. int remove_student(entry_list *el, long unsigned int AEM, int StartingHT_size)
  876. {
  877.     int finder, position, i, empty_positions = 0;
  878.     entry **temp;
  879.  
  880.     if (el->size == 0)
  881.     {
  882.         /* Periptwsi opou den exw kanena entry, opote den mporw na afairesw tpt. */
  883.         return 0;
  884.     }
  885.  
  886.     /* Periptwsi opou den yparxei o mathitis, ara den mporw na ton afairesw. */
  887.     finder = student_search(el, AEM);
  888.     if (finder == 0)
  889.     {
  890.         return 0; /* O foititis den vrethike. */
  891.     }
  892.  
  893.     /* Periptwsi opou o mathitis yparxei, kai thelw na ton afairesw. */
  894.     position = find_pos_of_student(el, AEM);
  895.  
  896.     entry_remove_from_HT2(el, AEM, el->entries[position]->name, StartingHT_size);
  897.  
  898.     if (position == el->size-1)
  899.     {
  900.         /* Simainei oti h eggrafi vrisketai stin teleutaia thesi tis listas eggrafwn. */
  901.         /* Prwta prepei na kanoume apodesmeusi tous komvous. */
  902.         /* Kai meta apodesmeusi tou struct tou foititi. */
  903.         course_code *current;
  904.         while (el->entries[position]->root != NULL)
  905.         {
  906.             current = el->entries[position]->root;
  907.             el->entries[position]->root = el->entries[position]->root->next;
  908.             free(current);
  909.         }
  910.         // Me to pou vgw apo tin loopa: el->entries[position]->root = NULL.
  911.  
  912.         free(el->entries[position]);
  913.  
  914.         el->entries[position] = NULL;
  915.         el->size--;
  916.  
  917.         /* Vriskoume poses kenes (NULL) theseis exei o pinakas deiktwn. */
  918.         for (i=0; i<el->capacity; i++)
  919.         {
  920.             if (el->entries[i] != NULL)
  921.                 continue;
  922.  
  923.             else
  924.                 empty_positions++;
  925.         }
  926.  
  927.         if (empty_positions > el->decreaser)
  928.         {
  929.             temp = (entry **) realloc(el->entries, (el->capacity - el->decreaser) * sizeof(entry));
  930.             if (temp == NULL)
  931.             {
  932.                 /* realloc() failed... */
  933.                 exit(0);
  934.             }
  935.             el->entries = temp;
  936.             el->capacity -= el->decreaser;
  937.         }
  938.  
  939.         return 1; /* removed */
  940.     }
  941.     else
  942.     {
  943.         /* Periptwsi opou o foititis den vrisketai stin teleutaia thesi. */
  944.         /* Prepei na apodesmeusoume tous komvous gia ta mathimata. */
  945.         course_code *current;
  946.         while (el->entries[position]->root != NULL)
  947.         {
  948.             current = el->entries[position]->root;
  949.             el->entries[position]->root = el->entries[position]->root->next;
  950.             free(current);
  951.         }
  952.  
  953.         free(el->entries[position]);
  954.         el->entries[position] = el->entries[el->size-1];
  955.         el->entries[el->size-1] = NULL;
  956.         el->size--;
  957.  
  958.         /* Vriskoume poses kenes (NULL) theseis exei o pinakas deiktwn. */
  959.         for (i=0; i<el->capacity; i++)
  960.         {
  961.             if (el->entries[i] != NULL)
  962.                 continue;
  963.             else
  964.                 empty_positions++;
  965.         }
  966.  
  967.         if (empty_positions > el->decreaser)
  968.         {
  969.             temp = (entry **) realloc(el->entries, (el->capacity - el->decreaser) * sizeof(entry));
  970.             if (temp == NULL)
  971.             {
  972.                 /* realloc() failed... */
  973.                 exit(0);
  974.             }
  975.             el->entries = temp;
  976.             el->capacity -= el->decreaser;
  977.  
  978.         }
  979.         el->isSorted = 0;
  980.         return 1; /* removed */
  981.  
  982.     }
  983.  
  984. }
  985.  
  986. /* Find by name function. */
  987. int find_by_name(entry_list *el, char name[])
  988. {
  989.     entry *current;
  990.  
  991.     int i, found = 0;
  992.     int length = strlen(name);
  993.     for (i=0; i<length; i++)  /* Meatrepoume to onoma se kefalaia giati etsi tha to sinantisoume mesa sto hash table. */
  994.         name[i] = toupper(name[i]);
  995.  
  996.     for (i=0; i<el->hashTable_size; i++)
  997.     {
  998.         for (current=el->hash_table[i]->next_student; current!=el->hash_table[i]; current=current->next_student)
  999.         {
  1000.             if (strcmp(current->name, name) != 0)  /* To onoma pou sinantisame den einai auto pou psaxnoume. */
  1001.                 continue;
  1002.             else
  1003.             {
  1004.                 found++;
  1005.                 printf("\nN-OK %s\n", current->name);
  1006.                 printf("%lu %hu\n", current->AEM, current->courses);
  1007.  
  1008.                 while (strcmp(current->name, name) == 0)
  1009.                 {
  1010.                     current = current->next_student;
  1011.                     if (strcmp(current->name, name) == 0)
  1012.                     {
  1013.                         printf("%lu %hu\n", current->AEM, current->courses);
  1014.                     }
  1015.                 }
  1016.                 break;
  1017.             }
  1018.         }
  1019.     }
  1020.     if (found == 0)
  1021.         return 0;
  1022.     else
  1023.         return 1;
  1024.  
  1025. }
  1026.  
  1027.  
  1028. /* Modify courses based on AEM function.
  1029. H synartisi epistrefei 1: an epiteuxthei h tropopoiisi.
  1030. H synartisi epistrefei 0: an h tropoiisi den epiteuxthei h an o foititis gia ton opoio theloume na kanoume tis allages den yparxei sti lista mas. */
  1031. int course_modify(entry_list *el, const long unsigned int AEM, short unsigned int courses)
  1032. {
  1033.     int finder, position;
  1034.     finder = student_search(el, AEM);
  1035.  
  1036.     if (finder == 0)
  1037.     {
  1038.         /* Simainei oti o foititis den yparxei sti lista. */
  1039.         return 0;
  1040.     }
  1041.  
  1042.     /* O foititis yparxei sti lista. Prepei na vrethei i thesi tou. */
  1043.     position = find_pos_of_student(el, AEM);
  1044.     el->entries[position]->courses = courses;
  1045.  
  1046.     return 1; /* changed. */
  1047. }
  1048.  
  1049. /* List courses function. */
  1050. void list_courses(entry_list *el, short unsigned int code, long unsigned int AEM)
  1051. {
  1052.     int position = find_pos_of_student(el, AEM);
  1053.  
  1054.     course_code *current;
  1055.  
  1056.     printf("\nL-OK %s\n", el->entries[position]->name);
  1057.     for (current=el->entries[position]->root; current!=NULL; current=current->next)
  1058.         printf("%d\n", current->code);
  1059. }
  1060.  
  1061. /* Print entries function.
  1062. H synartisi epistrefei void. */
  1063. void print_entries(entry_list *el)
  1064. {
  1065.     int i;
  1066.  
  1067.     printf("\n#\n");
  1068.  
  1069.     for (i=0; i<el->size; i++)
  1070.         printf("%lu %s %hu\n", el->entries[i]->AEM, el->entries[i]->name, el->entries[i]->courses);
  1071. }
  1072.  
  1073. /* Clear function. */
  1074. void clear_entries(entry_list *el)
  1075. {
  1076.     int i;
  1077.     course_code *current;
  1078.  
  1079.     /* Arxika prepei na diagrapsoume oles tis eggrafes.
  1080.     Meta ton pinaka deiktwn. */
  1081.     for (i=0; i<el->capacity; i++)
  1082.     {
  1083.         if (el->entries[i] == NULL)
  1084.         {
  1085.             free(el->entries[i]);
  1086.             continue;
  1087.         }
  1088.  
  1089.         /* Arxika prepei na diagrapsoume ti lista tou kathe foititi. */
  1090.         while (el->entries[i]->root != NULL)
  1091.         {
  1092.             current = el->entries[i]->root;
  1093.             el->entries[i]->root = el->entries[i]->root->next;
  1094.             free(current);
  1095.         }
  1096.         free(el->entries[i]);
  1097.     }
  1098.     free(el->entries);
  1099.  
  1100.     el->size = 0;
  1101.     el->capacity = 0;
  1102.     el->entries = NULL;
  1103.     el->isSorted = 0;
  1104. }
  1105.  
  1106. /* Main. */
  1107. int main(int argc, char **argv)
  1108. {
  1109.     long unsigned int AEM = 0;
  1110.     short unsigned int courses = 0, code;
  1111.     char name[64] = {'\0'}, menu_choice;
  1112.     int add_tester, remove_tester, mod_tester, find_tester, position, comparisons = 0, sorting_comparisons = 0;
  1113.     int reg_tester, unreg_tester, isReg_tester;
  1114.  
  1115.     if (argc != 4)
  1116.     {
  1117.         printf("Invalid command-line arguments!\n");
  1118.         return 0;
  1119.     }
  1120.  
  1121.     entry_list el;
  1122.  
  1123.  
  1124.     el.capacity = atoi(argv[1]);
  1125.     el.entries = (entry **) malloc(sizeof(entry *) * el.capacity); /* Desmeusame xwro gia ton pinaka deiktwn dynamika. */
  1126.     if (el.entries == NULL)
  1127.         exit(0);  /* No memory for allocation. */
  1128.  
  1129.     init_entry_list(&el);
  1130.     init_course_list(&el);
  1131.  
  1132.     el.decreaser = atoi(argv[2]);
  1133.     el.increaser = atoi(argv[2]);
  1134.  
  1135.     el.hashTable_size = atoi(argv[3]);
  1136.     el.hash_table = (entry **) malloc(sizeof(entry *) * el.hashTable_size);  /* Desmeuoume xwro gia to hash table. */
  1137.     if (el.hash_table == NULL)
  1138.         exit(0); /* No memory for allocation. */
  1139.  
  1140.     hash_table_init(&el);
  1141.  
  1142.     while(1)
  1143.     {
  1144.         scanf(" %c", &menu_choice);
  1145.         switch(menu_choice)
  1146.         {
  1147.             case 'a':
  1148.             {
  1149.                 scanf("%lu %63s %hu", &AEM, name, &courses);
  1150.                 add_tester = add(&el, AEM, courses, name);
  1151.                 if (add_tester == 0)
  1152.                 {
  1153.                     /* Simainei oti den petyxe h eggrafi. */
  1154.                     printf("\nA-NOK %lu, %d %d\n", AEM, el.size, el.capacity);
  1155.                 }
  1156.                 else
  1157.                 {
  1158.                     printf("\nA-OK %lu, %d %d\n", AEM, el.size, el.capacity);
  1159.                 }
  1160.                 break;
  1161.             }
  1162.             case 'g':
  1163.             {
  1164.                 scanf("%lu %hu", &AEM, &code);
  1165.  
  1166.                 reg_tester = course_insert(&el, code, AEM);
  1167.                 if (reg_tester == 1)
  1168.                     printf("\nG-OK %lu %hu\n", AEM, code);
  1169.  
  1170.                 else if (reg_tester == 0)
  1171.                     printf("\nG-NOK %lu\n", AEM);
  1172.                 else
  1173.                     printf("\nG-NOK %hu\n", code);
  1174.  
  1175.                 break;
  1176.             }
  1177.             case 'r':
  1178.             {
  1179.                 scanf("%lu", &AEM);
  1180.                 remove_tester = remove_student(&el, AEM, el.hashTable_size);
  1181.                 if (remove_tester == 1)
  1182.                 {
  1183.                     printf("\nR-OK %lu, %d %d\n", AEM, el.size, el.capacity);
  1184.                 }
  1185.                 else
  1186.                 {
  1187.                     printf("\nR-NOK %lu, %d %d\n", AEM, el.size, el.capacity);
  1188.                 }
  1189.                 break;
  1190.             }
  1191.             case 'u':
  1192.             {
  1193.                 scanf("%lu %hu", &AEM, &code);
  1194.                 unreg_tester = remove_course(&el, code, AEM);
  1195.                 if (unreg_tester == 1)
  1196.                     printf("\nU-OK %lu %hu\n", AEM, code);
  1197.  
  1198.                 else if (unreg_tester == 0)
  1199.                     printf("\nU-NOK %lu\n", AEM);
  1200.                 else
  1201.                     printf("\nU-NOK %hu\n", code);
  1202.                 break;
  1203.             }
  1204.             case 's':
  1205.             {
  1206.  
  1207.                 sorting_comparisons = insertion_sort(&el, AEM);
  1208.                 printf("\nS-OK\n");
  1209.                 fprintf(stderr, "\n$%d\n", sorting_comparisons);
  1210.  
  1211.                 break;
  1212.             }
  1213.             case 'i':
  1214.             {
  1215.                 scanf("%lu %hu", &AEM, &code);
  1216.                 isReg_tester = isRegistered(&el, code, AEM);
  1217.                 if (isReg_tester == 1)
  1218.                 {
  1219.                     printf("\nYES\n");
  1220.                 }
  1221.                 else if (isReg_tester == 0)
  1222.                 {
  1223.                     printf("\nNO\n");
  1224.                 }
  1225.                 else
  1226.                 {
  1227.                     printf("\nI-NOK %lu\n", AEM);
  1228.                 }
  1229.                 break;
  1230.             }
  1231.             case 'f':
  1232.             {
  1233.                 scanf("%lu", &AEM);
  1234.                 find_tester = student_search(&el, AEM);
  1235.  
  1236.                 if (find_tester == 1)
  1237.                 {   position = find_pos_of_student(&el, AEM);
  1238.                     printf("\nF-OK %s %hu\n", el.entries[position]->name, el.entries[position]->courses);
  1239.  
  1240.                     comparisons = find_cmps(&el, AEM);
  1241.                     fprintf(stderr, "\n$%d\n", comparisons);
  1242.                 }
  1243.                 else
  1244.                 {
  1245.                     printf("\nF-NOK %lu\n", AEM);
  1246.  
  1247.                     comparisons = find_cmps(&el, AEM);
  1248.                     fprintf(stderr, "\n$%d\n", comparisons);
  1249.                 }
  1250.                 break;
  1251.             }
  1252.             case 'n':
  1253.             {
  1254.                 scanf("%63s", name);
  1255.                 int found = find_by_name(&el, name);
  1256.                 if (found == 1)
  1257.                     break;
  1258.                 else
  1259.                     printf("\nN-NOK %s\n", name);
  1260.                 break;
  1261.             }
  1262.             case 'm':
  1263.             {
  1264.                 scanf("%lu %hu", &AEM, &courses);
  1265.                 mod_tester = course_modify(&el, AEM, courses);
  1266.  
  1267.                 if (mod_tester == 1)
  1268.                 {
  1269.                     printf("\nM-OK %lu\n", AEM);
  1270.                 }
  1271.                 else
  1272.                 {
  1273.                     printf("\nM-NOK %lu\n", AEM);
  1274.                 }
  1275.                 break;
  1276.             }
  1277.             case 'p':
  1278.             {
  1279.                 print_entries(&el);
  1280.                 break;
  1281.             }
  1282.             case 'h':
  1283.             {
  1284.                 print_hash_table(&el);
  1285.                 break;
  1286.             }
  1287.             case 'l':
  1288.             {
  1289.                 scanf("%lu", &AEM);
  1290.  
  1291.                 find_tester = student_search(&el, AEM);
  1292.                 if (find_tester == 0)   /* O foititis den yparxei sto database. */
  1293.                     printf("\nL-NOK %lu\n", AEM);
  1294.                 else
  1295.                 {
  1296.                     list_courses(&el, code, AEM);
  1297.                 }
  1298.                 break;
  1299.             }
  1300.             case 'c':
  1301.             {
  1302.                 deleteHashTable(&el); /* Ousiastika edw digrafoume ton pinaka katakermatismou. */
  1303.  
  1304.                 el.hash_table = (entry **) malloc(sizeof(entry *) * atoi(argv[3]));
  1305.                 if (el.hash_table == NULL)
  1306.                     exit(0);
  1307.  
  1308.                 hash_table_init(&el);
  1309.  
  1310.                 clear_entries(&el);
  1311.                 printf("\nC-OK\n");
  1312.                 break;
  1313.             }
  1314.             case 'q':
  1315.             {
  1316.                 clear_entries(&el);
  1317.                 clear_hash_table(&el);
  1318.                 //deleteHashTable(&el);
  1319.                 return 0;
  1320.             }
  1321.         }
  1322.     }
  1323.  
  1324.     return 0;
  1325. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement