├── 0 ├── count_of_2.c ├── equation.c ├── is_anagram.c ├── find_pivot.c └── print_doublon.c ├── 1 ├── count_alpha.c ├── height_tree.c ├── stack.c └── queue.c ├── 2 ├── reverse_tree.c ├── is_looping.c ├── longest_sequence.c ├── str_maxlenoc.c └── ord_alphlong.c ├── 3 ├── convert_bst.c ├── gold_gain.c ├── can_split.c ├── width_tree.c └── perimeter.c ├── 4 ├── intersection.c ├── longest_subarray.c ├── volume_histogram.c ├── range_comb.c └── clone_list.c ├── 5 ├── infin_mult.c ├── g_diam.c ├── infin_add.c └── count_island.c └── README.md /README.md: -------------------------------------------------------------------------------- 1 | # My solutions for 42's intermediate-level C exams 2 | Solutions aren't necessarily the most efficient. Written primarily for easy programming. 3 | 4 | Don't forget to watch, star, and fork :^) 5 | -------------------------------------------------------------------------------- /0/count_of_2.c: -------------------------------------------------------------------------------- 1 | int count_of_2(int n) { 2 | 3 | int count = 0; 4 | for (int i = 2; i <= n; i++) { 5 | int x = i; 6 | while (x > 0) { 7 | if (x % 10 == 2) 8 | count++; 9 | x /= 10; 10 | } 11 | } 12 | return count; 13 | } 14 | 15 | /************ 16 | Test Main 17 | ************/ 18 | 19 | #include 20 | #include 21 | int main(int ac, char* av[]) { 22 | if (ac == 2) 23 | printf("%d\n", count_of_2(atoi(av[1]))); 24 | return 0; 25 | } 26 | 27 | /* 28 | COUNT_OF_2 29 | Assignment name : count_of_2 30 | Expected files : count_of_2.c 31 | Allowed functions: None 32 | -------------------------------------------------------------------------------- 33 | Implement a function which counts, for a given integer n, the number of 2s 34 | that appear in all the numbers between 0 and n (inclusive). 35 | Your function must be declared as follows: 36 | int count_of_2(int n); 37 | If n <= 1, the function returns 0; 38 | Examples: 39 | input = 25 40 | output = 9 41 | because there are 9 2s in (2, 12, 20, 21, 22, 23, 24 and 25) 42 | Note: 43 | the number 22 counts as 2 because it has two 2s, number 202 count as 2, number 22022 count as 4 etc… 44 | */ -------------------------------------------------------------------------------- /1/count_alpha.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int isSmall(char c) { 4 | return 'a' <= c && c <= 'z'; 5 | } 6 | 7 | int isCapital(char c) { 8 | return 'A' <= c && c <= 'Z'; 9 | } 10 | 11 | int main(int ac, char* av[]) { 12 | if (ac == 2) { 13 | 14 | int tab[26] = {0}; 15 | char* s = av[1] - 1; 16 | int first = 1; 17 | 18 | while (*(++s)) { 19 | if (isCapital(*s)) { 20 | *s += 32; 21 | } 22 | if (isSmall(*s)) { 23 | tab[*s - 'a']++; 24 | } 25 | } 26 | s = av[1] - 1; 27 | while (*(++s)) { 28 | if (tab[*s - 'a'] > 0) { 29 | if (first) { 30 | first = 0; 31 | printf("%d%c", tab[*s - 'a'], *s); 32 | } 33 | else 34 | printf(", %d%c", tab[*s - 'a'], *s); 35 | tab[*s - 'a'] = 0; 36 | } 37 | } 38 | } 39 | printf("\n"); 40 | return 0; 41 | } 42 | 43 | /* 44 | COUNT_APLHA 45 | Assignment name : count_alpha 46 | Expected files : count_alpha.c 47 | Allowed functions: write, printf 48 | -------------------------------------------------------------------------------- 49 | 50 | Write a program called count_alpha that takes a string and displays the number 51 | of occurences of its alphabetical characters. Other characters are not counted. 52 | The order is the order of occurence in the string. The display must be ended by 53 | a newline. 54 | 55 | The format is in the examples. 56 | 57 | If the number of arguments is not 1, display only a newline. 58 | 59 | Examples : 60 | $> ./count_alpha abbcc 61 | 1a, 2b, 2c 62 | $> ./count_alpha "abbcc" 63 | 1a, 2b, 2c 64 | $> ./count_alpha "abbcc" "dddeef" | cat -e 65 | $ 66 | $> ./count_alpha "My Hyze 47y 7." | cat -e 67 | 1m, 3y, 1h, 1z, 1e$ 68 | $> ./count_alpha "" | cat -e 69 | $ 70 | */ -------------------------------------------------------------------------------- /2/reverse_tree.c: -------------------------------------------------------------------------------- 1 | typedef struct s_node { 2 | int value; 3 | struct s_node *right; 4 | struct s_node *left; 5 | } Node; 6 | 7 | void reverse_tree(struct s_node *root) { 8 | 9 | Node* tmp = root->left; 10 | root->left = root->right; 11 | root->right = tmp; 12 | 13 | if (root->left) 14 | reverse_tree(root->left); 15 | if (root->right) 16 | reverse_tree(root->right); 17 | } 18 | 19 | /* 20 | REVERSE_TREE 21 | Assignment name : reverse_tree 22 | Expected files : reverse_tree.c 23 | Allowed functions: 24 | -------------------------------------------------------------------------------- 25 | Implement a function to reverse a binary tree (i.e., flip it from right to left). 26 | You must declare the following node structure for the binary tree in your code: 27 | struct s_node { 28 | int value; 29 | struct s_node *right; 30 | struct s_node *left; 31 | }; 32 | The function must be declared as follows: 33 | void reverse_tree(struct s_node *root); 34 | You must include the struct in your file. 35 | EXAMPLE : 36 | The following tree : 37 | 94 38 | / \ 39 | / \ 40 | 34 52 41 | / \ 42 | / \ 43 | 1 99 44 | / / \ 45 | 20 / \ 46 | / \ 47 | 83 39 48 | \ / \ 49 | 61 / \ 50 | 37 67 51 | would become : 52 | 94 53 | / \ 54 | / \ 55 | 52 34 56 | / \ 57 | / \ 58 | 99 1 59 | / \ \ 60 | / \ 20 61 | / \ 62 | 39 83 63 | / \ / 64 | / \ 61 65 | 67 37 66 | */ -------------------------------------------------------------------------------- /0/equation.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void equation(int n) { 4 | for (int a = 0; a < 10; a++) 5 | for (int b = 0; b < 10; b++) 6 | for (int c = 0; c < 10; c++) 7 | if ((a * 10 + b) + (c * 10 + a) == n) 8 | printf("A = %d, B = %d, C = %d\n", a, b, c); 9 | } 10 | 11 | /************ 12 | Test Main 13 | ************/ 14 | 15 | #include 16 | int main(int ac, char* av[]) { 17 | if (ac == 2) 18 | equation(atoi(av[1])); 19 | return 0; 20 | } 21 | 22 | 23 | /* 24 | EQUATION 25 | Assignment name : equation 26 | Expected files : equation.c 27 | Allowed functions: printf 28 | ------------------------------------------------------------------------------- 29 | The goal of this exercise is to find all possible answers to the following 30 | equation : 31 | 32 | AB + CA = n 33 | 34 | where A, B, and C are individual digits [0-9] and n is an integer. 35 | Note that here AB is not the product of A and B. It is merely a two digit number 36 | with A being the first digit (tens place) and B the second digit (ones place). 37 | 38 | Implement a function that, given an integer n, prints on the standard 39 | output all the possible values of A, B, C for which the equation is true. 40 | 41 | Your function must be declared as follows: 42 | 43 | void equation(int n); 44 | 45 | If a solution could not be found, nothing is printed. 46 | Examples: 47 | For the value n = 42, the output would be : 48 | $> ./equation 42 49 | A = 0, B = 2, C = 4 50 | A = 1, B = 1, C = 3 51 | A = 2, B = 0, C = 2 52 | A = 3, B = 9, C = 0 53 | $> 54 | For the value n = 111, the output would be : 55 | $> ./equation 111 56 | A = 2, B = 9, C = 8 57 | A = 3, B = 8, C = 7 58 | A = 4, B = 7, C = 6 59 | A = 5, B = 6, C = 5 60 | A = 6, B = 5, C = 4 61 | A = 7, B = 4, C = 3 62 | A = 8, B = 3, C = 2 63 | A = 9, B = 2, C = 1 64 | $> 65 | For the value n = 0, the output would be : 66 | $> ./equation 0 | cat -e 67 | A = 0, B = 0, C = 0$ 68 | $> 69 | Note: 70 | - The displayed output will always be sorted in ascending order beginning with A, then B and then C. 71 | (as shown in the examples above) 72 | */ -------------------------------------------------------------------------------- /1/height_tree.c: -------------------------------------------------------------------------------- 1 | typedef struct s_node { 2 | int value; 3 | struct s_node **nodes; 4 | } Node; 5 | 6 | int height_tree(struct s_node *root) { 7 | 8 | if (!root) 9 | return 0; 10 | 11 | int max = 0; 12 | while (*root->nodes) { 13 | int tmp = 1 + height_tree(*root->nodes); 14 | if (max < tmp) 15 | max = tmp; 16 | root->nodes++; 17 | } 18 | return max; 19 | } 20 | 21 | /************ 22 | Test Main 23 | ************/ 24 | 25 | #include 26 | #include 27 | Node* b(int v) { 28 | Node* new = malloc(sizeof(Node)); 29 | new->value = v; 30 | new->nodes = malloc(100000); 31 | return new; 32 | } 33 | int main() { 34 | 35 | Node* r = b(94); 36 | r->nodes[0] = b(34); 37 | r->nodes[1] = b(52); 38 | 39 | r->nodes[0]->nodes[0] = b(1); 40 | r->nodes[0]->nodes[1] = b(99); 41 | r->nodes[0]->nodes[2] = b(11); 42 | 43 | r->nodes[0]->nodes[1]->nodes[0] = b(13); 44 | 45 | printf("%d\n", height_tree(r)); 46 | 47 | return 0; 48 | } 49 | 50 | /* 51 | HEIGHT_TREE 52 | Assignment name : height_tree 53 | Expected files : height_tree.c 54 | Allowed functions: 55 | -------------------------------------------------------------------------------- 56 | Implement a function to calculate the height of an n-ary tree. 57 | Your should use the following node structure in your code for the n-ary tree: 58 | struct s_node { 59 | int value; 60 | struct s_node **nodes; 61 | }; 62 | In this struct nodes is a null-terminated array. 63 | Note that the height of a tree is the number of EDGES on the longest path from 64 | the root node to a leaf. A tree with a single node will have a height of 0. 65 | An empty tree should have height -1; 66 | The function must be declared as follows: 67 | int height_tree(struct s_node *root); 68 | EXAMPLE: 69 | The Input Tree : 70 | 94 71 | / \ 72 | / \ 73 | 34 52 74 | / \ \ 75 | / \ \ 76 | 1 99 11 77 | / 78 | / 79 | 13 80 | Output : 3 81 | */ -------------------------------------------------------------------------------- /4/intersection.c: -------------------------------------------------------------------------------- 1 | typedef struct s_node { 2 | void *content; 3 | struct s_node *next; 4 | } Node; 5 | 6 | void* intersection(Node* lst1, Node* lst2) { 7 | 8 | while (lst1) { 9 | Node* tmp = lst2; 10 | while (tmp) { 11 | if (lst1 == tmp) 12 | return lst1; 13 | tmp = tmp->next; 14 | } 15 | lst1 = lst1->next; 16 | } 17 | return 0; 18 | } 19 | 20 | /************ 21 | Test Main 22 | ************/ 23 | 24 | #include 25 | #include 26 | Node* b(void* v) { 27 | Node* new = malloc(sizeof(Node)); 28 | new->content = v; 29 | new->next = 0; 30 | return new; 31 | } 32 | int main() { 33 | Node* a = b("a"); 34 | a->next = b("b"); 35 | a->next->next = b("c"); 36 | a->next->next->next = b("d"); 37 | a->next->next->next->next = b("e"); 38 | a->next->next->next->next->next = b("f"); 39 | 40 | Node* c = b("g"); 41 | c->next = b("h"); 42 | c->next->next = b("i"); 43 | c->next->next->next = b("j"); 44 | c->next->next->next->next = b("k"); 45 | c->next->next->next->next->next = b("l"); 46 | 47 | Node* ret = intersection(a, c); 48 | printf("%s\n", ret ? ret->content : 0); 49 | 50 | c->next->next = a->next->next->next; 51 | ret = intersection(a, c); 52 | printf("%s\n", ret ? ret->content : 0); 53 | 54 | return 0; 55 | } 56 | 57 | /* 58 | INTERSECTION 59 | Assignment name : intersection 60 | Expected files : intersection.c 61 | Allowed functions: 62 | -------------------------------------------------------------------------------- 63 | Given two singly linked lists, determine if the two lists intersect. 64 | Return the intersecting node. 65 | The intersection is defined based on reference, not value. 66 | That is, if the kth node of the first linked list is the exact same node 67 | (by reference) as the jth node of the second linked list, then they are 68 | intersecting. 69 | The linked lists will use the following structure : 70 | struct s_node { 71 | void *content; 72 | struct s_node *next; 73 | }; 74 | The function must be declared as follows: 75 | void *intersection(struct s_node *lst1, struct s_node *lst2); 76 | If the two linked lists are not intersecting, the function returns NULL. 77 | The function does not modify the two linked list. 78 | */ -------------------------------------------------------------------------------- /0/is_anagram.c: -------------------------------------------------------------------------------- 1 | int is_anagram(char* a, char*b) { 2 | 3 | int tab[126] = {0}; 4 | 5 | while (*a) 6 | tab[(int)*a++]++; 7 | while (*b) 8 | tab[(int)*b++]--; 9 | for (int i = 0; i < 126; i++) 10 | if (tab[i] != 0) 11 | return 0; 12 | return 1; 13 | } 14 | 15 | /************ 16 | Test Main 17 | ************/ 18 | 19 | #include 20 | int main() { 21 | char* a = "abcdef"; 22 | char* b = "fabcde"; 23 | 24 | printf("%d\n", is_anagram(a, b)); 25 | 26 | char* c = ".123?."; 27 | char* d = "?321.."; 28 | 29 | printf("%d\n", is_anagram(c, d)); 30 | 31 | char* e = "abca"; 32 | char* f = "bcab"; 33 | 34 | printf("%d\n", is_anagram(e, f)); 35 | 36 | char* g = "aaaaaaaaaa"; 37 | char* h = "aaaaaaaaaa"; 38 | 39 | printf("%d\n", is_anagram(g, h)); 40 | 41 | return 0; 42 | } 43 | 44 | /* 45 | IS_ANAGRAM 46 | Assignment name : is_anagram 47 | Expected files : is_anagram.c 48 | Allowed functions: 49 | -------------------------------------------------------------------------------- 50 | ALERT: OPTIMIZED SOLUTION REQUIRED. 51 | An anagram is a sequence of characters formed by rearranging the letters of 52 | another sequence, such as 'cinema', formed from 'iceman'. 53 | Given two strings as parameters, create a function able to tell whether or 54 | not the first string is an anagram of the second. 55 | The function must be declared as follows: 56 | int is_anagram(char *a, char *b); 57 | Considerations: 58 | - Be careful: the naive solution won't work on our big input, you have to 59 | find an optimized solution which will run in O(sa + sb) time (where sa is 60 | the length of a and sb length of b). 61 | - Our tested string will always be a sequence of ascii characters between 32 62 | and 126 inclusive. 63 | - The bigger test we will do is on 2 sequences of 1.000.000 characteres each. 64 | It should run in less than 2 seconds. 65 | Example 1: 66 | a='abcdef' 67 | b='fabcde' 68 | In this case, these two strings are anagrams, your function should return 1. 69 | Example 2: 70 | a='.123?.' 71 | b='?321..' 72 | In this case, these two strings are anagrams, your function should return 1. 73 | Example 3: 74 | a='abca' 75 | b='bcab' 76 | In this case, these two strings are not anagrams, your function should return 0. 77 | */ -------------------------------------------------------------------------------- /4/longest_subarray.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int findIt(char* arr) { 5 | 6 | int i = 0, odds = 0, evens = 0, len = 0; 7 | 8 | for (; i < (int)strlen(arr); i++) { 9 | if (arr[i] % 2) 10 | odds++; 11 | else 12 | evens++; 13 | len++; 14 | } 15 | i--; 16 | while (odds != evens && i >= 0) { 17 | if (arr[i] % 2) 18 | odds--; 19 | else 20 | evens--; 21 | i--; 22 | len--; 23 | } 24 | return len; 25 | } 26 | 27 | char* longest_subarray(char* arr) { 28 | 29 | int maxIdx = 0, maxLen = 0; 30 | 31 | for (int i = 0; i < (int)strlen(arr); i++) { 32 | int len = findIt(arr + i); 33 | if (maxLen < len) { 34 | maxLen = len; 35 | maxIdx = i; 36 | } 37 | if (maxLen > (int)strlen(arr) / 2) 38 | break; 39 | } 40 | char* ret = malloc(maxLen + 1); 41 | for (int i = 0; i < maxLen; i++) 42 | ret[i] = arr[i + maxIdx]; 43 | ret[maxLen] = 0; 44 | return ret; 45 | } 46 | 47 | /************ 48 | Test Main 49 | ************/ 50 | 51 | #include 52 | int main(int ac, char* av[]) { 53 | if (ac == 2) 54 | printf("%s\n", longest_subarray(av[1])); 55 | return 0; 56 | } 57 | 58 | /* 59 | LONGEST_SUBARRAY 60 | Assignment name : longest_subarray 61 | Expected files : longest_subarray.c 62 | Allowed functions: malloc free strlen 63 | -------------------------------------------------------------------------------- 64 | Given a null-terminated array of digit characters, implement a function which 65 | finds the longest subarray with an equal number of even and odd digits. 66 | The function returns a null-terminated array. 67 | Your function must be declared as follows: 68 | char *longest_subarray(char *arr); 69 | Example 1: 70 | input = 134 71 | output = 34 72 | In the above example, 1 and 3 is odd and 4 is even, 73 | the longest subarray with an equal number of odd and even digits is 34. 74 | Example 2: 75 | input = 454 76 | output = 45 77 | Example 3: 78 | input = 1357913579024680213579 79 | output = 79135790246802 80 | Example 4: 81 | input = 2010102 82 | output = 0101 83 | Note: 84 | - As a reminder, 0, 2, 4, 6, 8 are even digits and 1, 3, 5, 7, 9 are odd. 85 | - In case of more than one subarray with the same length, 86 | the expected output is the first one. 87 | */ -------------------------------------------------------------------------------- /4/volume_histogram.c: -------------------------------------------------------------------------------- 1 | #define MAX(a, b) (a > b ? a : b) 2 | #define MIN(a, b) (a < b ? a : b) 3 | 4 | int volume_histogram(int* histogram, int size) { 5 | 6 | int left[size], right[size]; 7 | int ret = 0; 8 | 9 | left[0] = histogram[0]; 10 | for (int i = 1; i < size; i++) 11 | left[i] = MAX(left[i - 1], histogram[i]); 12 | 13 | right[size - 1] = histogram[size - 1]; 14 | for (int i = size - 2; i >= 0; i--) 15 | right[i] = MAX(right[i + 1], histogram[i]); 16 | 17 | for (int i = 0; i < size; i++) 18 | ret += MIN(left[i], right[i]) - histogram[i]; 19 | 20 | return ret; 21 | } 22 | 23 | /************ 24 | Test Main 25 | ************/ 26 | 27 | #include 28 | int main() { 29 | 30 | int a[] = { 1, 0, 2, 0, 2 }; 31 | printf("%d\n", volume_histogram(a, 5)); 32 | 33 | int b[] = { 0, 0, 4, 0, 0, 6, 0, 0, 3, 0, 5, 0, 1, 0, 0, 0 }; 34 | printf("%d\n", volume_histogram(b, 16)); 35 | 36 | int c[] = { 1 }; 37 | printf("%d\n", volume_histogram(c, 1)); 38 | 39 | int d[] = {}; 40 | printf("%d\n", volume_histogram(d, 0)); 41 | 42 | return 0; 43 | } 44 | 45 | /* 46 | VOLUME_HISTOGRAM 47 | Assignment name : volume_histogram 48 | Expected files : volume_histogram.c 49 | Allowed functions: None 50 | -------------------------------------------------------------------------------- 51 | Implement a function which computes, for a given histogram (bar graph) 52 | of positive integers, the volume of water it could hold if someone poured 53 | water across the top. 54 | Each histogram bar has width 1. 55 | Your function must be declared as follows: 56 | int volume_histogram(int *histogram, int size); 57 | Example 1: 58 | With the following input: 59 | int histogram[] = {1, 0, 2, 0, 2}; 60 | int size = 5; 61 | ('#' bars are the histogram. '.' is water) 62 | # . # 63 | # . # . # 64 | --------- 65 | 1 0 2 0 2 66 | The function here returns 3 (because there is 3 emplacement of water). 67 | Example 2: 68 | With the following input: 69 | int histogram[] = {0, 0, 4, 0, 0, 6, 0, 0, 3, 0, 5, 0, 1, 0, 0, 0}; 70 | int size = 16; 71 | ('#' bars are the histogram. '.' is water) 72 | # 73 | # . . . . # 74 | # . . # . . . . # 75 | # . . # . . # . # 76 | # . . # . . # . # 77 | # . . # . . # . # . # 78 | ------------------------------- 79 | 0 0 4 0 0 6 0 0 3 0 5 0 1 0 0 0 80 | The function returns 26. 81 | */ -------------------------------------------------------------------------------- /5/infin_mult.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int myStrLen(char* s) { 5 | int ret = 0; 6 | while (*s++) 7 | ret++; 8 | return ret; 9 | } 10 | 11 | int main(int ac, char* av[]) { 12 | 13 | if (ac != 3) 14 | return 0; 15 | 16 | char* s1 = av[1]; 17 | char* s2 = av[2]; 18 | int neg = 0; 19 | 20 | if (*s1 == '-' && *s2 == '-') { 21 | s1++; 22 | s2++; 23 | } else if (*s1 == '-' && *s2 != '-') { 24 | s1++; 25 | neg = 1; 26 | } else if (*s1 != '-' && *s2 == '-') { 27 | s2++; 28 | neg = 1; 29 | } 30 | 31 | int len1 = myStrLen(s1); 32 | int len2 = myStrLen(s2); 33 | 34 | int ret[len1 + len2]; 35 | for (int i = 0; i < len1 + len2; i++) 36 | ret[i] = 0; 37 | 38 | int idx1 = 0, idx2 = 0; 39 | for (int i = len1 - 1; i >= 0; i--) { 40 | 41 | int carry = 0; 42 | int n1 = s1[i] - '0'; 43 | 44 | idx2 = 0; 45 | for (int j = len2 - 1; j >= 0; j--) { 46 | 47 | int n2 = s2[j] - '0'; 48 | int sum = (n1 * n2) + ret[idx1 + idx2] + carry; 49 | carry = sum / 10; 50 | ret[idx1 + idx2] = sum % 10; 51 | idx2++; 52 | } 53 | 54 | if (carry) 55 | ret[idx1 + idx2] += carry; 56 | 57 | idx1++; 58 | } 59 | int idx = len1 + len2 - 1; 60 | while (idx >= 0 && ret[idx] == 0) 61 | idx--; 62 | if (idx == -1) { 63 | write(1, "0\n", 2); 64 | return 0; 65 | } 66 | if (neg) 67 | write(1, "-", 1); 68 | while (idx >= 0) { 69 | char x = ret[idx] + '0'; 70 | write(1, &x, 1); 71 | idx--; 72 | } 73 | write(1, "\n", 1); 74 | return 0; 75 | } 76 | 77 | /* 78 | INFIN_MULT 79 | Assignment name : infin_mult 80 | Expected files : *.c, *.h 81 | Allowed functions: write, malloc, free 82 | -------------------------------------------------------------------------------- 83 | Write a program that takes as a parameter two strings that represent two 84 | numbers potentially infinit, and displays on stdout the result of the 85 | multiplication of these two numbers, followed by a '\n'. 86 | A negative number will always be prefixed by one and only one -. The only 87 | characters that can be part of the strings are digits and the sign -. 88 | Both parameters will always be well formated, and you will always have exactly 89 | two parameters, no tricks. 90 | Example: 91 | $> ./infin_mult "879879087" "67548976597" | cat -e 92 | 59434931855952726939$ 93 | $> ./infin_mult "-876435" "987143265" | cat -e 94 | -865166907460275$ 95 | $> ./infin_mult "-807965" "-34532" | cat -e 96 | 27900647380$ 97 | $> ./infin_mult "-807965" "0" 98 | 0 99 | $> 100 | */ -------------------------------------------------------------------------------- /0/find_pivot.c: -------------------------------------------------------------------------------- 1 | int find_pivot(int* arr, int n) { 2 | 3 | int sum = 0; 4 | for (int i = 0; i < n; i++) 5 | sum += arr[i]; 6 | 7 | int tmp = 0; 8 | for (int i = 0; i < n; i++) { 9 | if (tmp == sum - tmp - arr[i]) 10 | return i; 11 | tmp += arr[i]; 12 | } 13 | return -1; 14 | } 15 | 16 | /************ 17 | Test Main 18 | ************/ 19 | 20 | #include 21 | int main() { 22 | 23 | int a[] = {1, 2, 3, 4, 0, 6}; 24 | printf("%d\n", find_pivot(a, 6)); 25 | 26 | int b[] = {-5, 10, 2, 5}; 27 | printf("%d\n", find_pivot(b, 4)); 28 | 29 | int c[] = {1, 100, 0, 0, 1}; 30 | printf("%d\n", find_pivot(c, 5)); 31 | 32 | int d[] = {7, 9, 8}; 33 | printf("%d\n", find_pivot(d, 3)); 34 | 35 | int e[] = {1, 2}; 36 | printf("%d\n", find_pivot(e, 2)); 37 | 38 | return 0; 39 | } 40 | 41 | /* 42 | FIND_PIVOT 43 | Assignment name : find_pivot 44 | Expected files : find_pivot.c 45 | Allowed functions: 46 | -------------------------------------------------------------------------------- 47 | ALERT: OPTIMIZED SOLUTION REQUIRED. 48 | Given an array of integers and its size passed as parameters, 49 | create a function able to return the pivot index of this array. 50 | The pivot index is the index where the sum of the numbers on the left 51 | is equal to the sum of the numbers on the right. 52 | The function must be declared as follows: 53 | int find_pivot(int *arr, int n); 54 | If there is no pivot present, return -1. 55 | Considerations: 56 | - Be careful: the naive solution won't work on our big input, you have to 57 | find an optimized solution which will run in O(n) time (where n is the 58 | length of the array). 59 | - The array will always have a length bigger than 1. 60 | - You don't have to take care of overflow or underflow of sums, 61 | it will stay in an range of an int. 62 | - The bigger test we will do is on an array of 1.000.000 elements. 63 | It should run in less than 2 seconds. 64 | 65 | Example 1: 66 | arr = [ 1, 2, 3, 4, 0, 6 ] , n = 6 67 | In this case, your function should return 3. 68 | Because at index 3, the sum of the elements on the left is equals 69 | to the sum of the elements on the right: 70 | 71 | = 6 = 6 72 | _______ ____ 73 | [ 1, 2, 3, 4, 0, 6 ] 74 | ^ 75 | | 76 | with pivot = 3 77 | Example 2: 78 | arr = [ -5, 10, 2, 5 ] , n = 4 79 | In this case, your function should return 2. 80 | Example 3: 81 | arr = [ 1, 100, 0, 0, 1 ] , n = 5 82 | In this case, your function should return 1. 83 | Example 4: 84 | arr = [ 7, 9, 8 ] , n = 3 85 | In this case, your function should return -1. 86 | Example 5: 87 | arr = [ 1 , 2 ] , n = 2 88 | In this case, your function should return -1. 89 | */ -------------------------------------------------------------------------------- /4/range_comb.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int findPerms(int n) { 5 | int ret = 1; 6 | for (int i = 1; i <= n; i++) 7 | ret *= i; 8 | return ret; 9 | } 10 | 11 | void swap(int* a, int* b) { 12 | int tmp; 13 | tmp = *a; 14 | *a = *b; 15 | *b = tmp; 16 | } 17 | 18 | void sortRightSide(int* t, int size) { 19 | 20 | for (int i = 0; i < size - 1; i++) { 21 | if (t[i] > t[i + 1]) { 22 | int tmp = t[i]; 23 | t[i] = t[i + 1]; 24 | t[i + 1] = tmp; 25 | i = -1; 26 | } 27 | } 28 | } 29 | 30 | int findCeil(int* t, int first, int l, int n) { 31 | int ceilIndex = l; 32 | 33 | for (int i = l + 1; i < n; i++) 34 | if (t[i] > first && t[i] < t[ceilIndex]) 35 | ceilIndex = i; 36 | return ceilIndex; 37 | } 38 | 39 | void permute(int** ret, int* t, int* idx, int n) { 40 | 41 | while (1) { 42 | 43 | memcpy(ret[*idx], t, sizeof(int) * n); 44 | *idx += 1; 45 | 46 | int i; 47 | for (i = n - 2; i >= 0; i--) 48 | if (t[i] < t[i + 1]) 49 | break; 50 | if (i == -1) 51 | break; 52 | else { 53 | int ceilIndex = findCeil(t, t[i], i + 1, n); 54 | swap(t + i, t + ceilIndex); 55 | sortRightSide(t + i + 1, n - i - 1); 56 | } 57 | } 58 | } 59 | 60 | int **range_comb(int n) { 61 | 62 | int perms = findPerms(n); 63 | 64 | int** ret = malloc(sizeof(int*) * perms); 65 | for (int i = 0; i < perms; i++) 66 | ret[i] = malloc(sizeof(int) * n); 67 | 68 | int* template = malloc(sizeof(int) * n); 69 | for (int i = 0; i < n; i++) 70 | template[i] = i; 71 | 72 | int idx = 0; 73 | permute(ret, template, &idx, n); 74 | return ret; 75 | } 76 | 77 | /************ 78 | Test Main 79 | ************/ 80 | 81 | #include 82 | int main(int ac, char* av[]) { 83 | if (ac != 2) 84 | return 0; 85 | int n = atoi(av[1]); 86 | int** ret = range_comb(n); 87 | printf("perms: %d\n", findPerms(n)); 88 | for (int i = 0; i < findPerms(n); i++) { 89 | printf("{ "); 90 | for (int j = 0; j < n; j++) 91 | printf("%d ", ret[i][j]); 92 | puts("}"); 93 | } 94 | return 0; 95 | } 96 | 97 | /* 98 | RANGE_COMB 99 | Assignment name : range_comb 100 | Expected files : range_comb.c 101 | Allowed functions: malloc free memcpy 102 | -------------------------------------------------------------------------------- 103 | Implement a function which computes, for a given integer n, all 104 | the possible permutations of the numbers in the range from 0 to 105 | (n - 1) inclusive. 106 | The function returns a null-terminated array. 107 | Your function must be declared as follows: 108 | int **range_comb(int n); 109 | If n <= 0, the function returns -1; 110 | Examples: 111 | input = 2 112 | output = {{0, 1}, {1, 0}} 113 | input = 3 114 | output = {{0, 1, 2}, {0, 2, 1}, {1, 0, 2}, {1, 2, 0}, {2, 0, 1}, {2, 1, 0}} 115 | */ -------------------------------------------------------------------------------- /0/print_doublon.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void print_doublon(int *a, int na, int *b, int nb) { 4 | 5 | int i = 0, j = 0; 6 | int first = 1; 7 | while (i < na && j < nb) { 8 | 9 | if (a[i] == b[j]) { 10 | if (first) { 11 | first = 0; 12 | printf("%d", a[i]); 13 | } else { 14 | printf(" %d", a[i]); 15 | } 16 | i++; 17 | j++; 18 | } else { 19 | if (a[i] > b[j]) 20 | j++; 21 | else 22 | i++; 23 | } 24 | } 25 | printf("\n"); 26 | } 27 | 28 | /************ 29 | Test Main 30 | ************/ 31 | 32 | int main() { 33 | 34 | int a[] = {1, 2, 10, 15}; 35 | int b[] = {2, 20, 40, 70}; 36 | 37 | print_doublon(a, 4, b, 4); 38 | 39 | int c[] = {-5, 2, 10, 15, 50, 70, 100, 200, 300, 1200, 5000}; 40 | int d[] = {2, 4, 5, 6, 7, 10, 40, 70}; 41 | 42 | print_doublon(c, 11, d, 8); 43 | 44 | int e[] = {100, 200, 300}; 45 | int f[] = {1, 2, 3, 4}; 46 | 47 | print_doublon(e, 3, f, 4); 48 | return 0; 49 | } 50 | 51 | /* 52 | PRINT_DOUBLON 53 | Assignment name : print_doublon 54 | Expected files : print_doublon.c 55 | Allowed functions: printf 56 | -------------------------------------------------------------------------------- 57 | ALERT: OPTIMIZED SOLUTION REQUIRED. 58 | Given two sorted arrays passed as parameters, 59 | create a function able to print all the number that are present 60 | in one array and in the other, separated by a space. 61 | Then print a new line. 62 | The function must be declared as follows (with 'na' the length of the array 'a', 63 | and 'nb' the length of the array 'b'): 64 | void print_doublon(int *a, int na, int *b, int nb); 65 | Considerations: 66 | - Be careful: the naive solution won't work on our big input, you have to 67 | find an optimized solution which will run in O(n) time (where n is 68 | the length of the longest array between a and b). 69 | - All elements of an array are unique. The same number will not repeat in an array. 70 | - If there is no doublon, just print a new line '\n'. 71 | - The bigger test we will run will be on 2 arrays of 500 000 elements each, 72 | it should run in less than 2 seconds. 73 | Example 1: 74 | a = [ 1, 2, 10, 15 ] , na = 4 75 | b = [ 2, 20, 40, 70 ] , nb = 4 76 | In this case, by using a main file that use your function with the above input, 77 | the output should be (using cat -e): 78 | $> ./example1 | cat -e 79 | 2$ 80 | Example 2: 81 | a = [ -5, 2, 10, 15, 50, 70, 100, 200, 300, 1200, 5000 ] , na = 11 82 | b = [ 2, 4, 5, 6, 7, 10, 40, 70 ] , nb = 8 83 | In this case, by using a main file that use your function with the above input, 84 | the output should be (using cat -e): 85 | $> ./example2 | cat -e 86 | 2 10 70$ 87 | Example 3: 88 | a = [ 100, 200, 300 ] , na = 3 89 | b = [ 1, 2, 3, 4 ] , nb = 4 90 | In this case, by using a main file that use your function with the above input, 91 | the output should be (using cat -e): 92 | $> ./example3 | cat -e 93 | $ 94 | */ -------------------------------------------------------------------------------- /2/is_looping.c: -------------------------------------------------------------------------------- 1 | typedef struct s_node { 2 | int value; 3 | struct s_node *next; 4 | } Node; 5 | 6 | int is_looping(Node* node) { 7 | 8 | Node* n1 = node; 9 | Node* n2 = node; 10 | 11 | while (n1 && n2) { 12 | 13 | n1 = n1->next; 14 | n2 = n2->next; 15 | if (n2) 16 | n2 = n2->next; 17 | if (n1 && n2 && n1 == n2) 18 | return 1; 19 | } 20 | return 0; 21 | } 22 | 23 | /************ 24 | Test Main 25 | ************/ 26 | 27 | #include 28 | #include 29 | Node* b(int v) { 30 | Node* new = malloc(sizeof(Node)); 31 | new->value = v; 32 | new->next = 0; 33 | return new; 34 | } 35 | int main() { 36 | 37 | Node* a = b(1); 38 | 39 | a->next = b(2); 40 | a->next->next = b(3); 41 | a->next->next->next = b(4); 42 | a->next->next->next->next = a; 43 | 44 | printf("%d\n", is_looping(a)); 45 | 46 | Node* c = b(1); 47 | c->next = b(2); 48 | c->next->next = b(3); 49 | c->next->next->next = b(4); 50 | 51 | printf("%d\n", is_looping(c)); 52 | 53 | return 0; 54 | } 55 | 56 | /* 57 | IS_LOOPING 58 | Assignment name : is_looping 59 | Expected files : is_looping.c 60 | Allowed functions: 61 | -------------------------------------------------------------------------------- 62 | ALERT: OPTIMIZED SOLUTION REQUIRED. 63 | Given the first node of a linked list as parameter, create a function which 64 | returns 1 if the linked list is looping, otherwise 0. 65 | The linked list uses the following structure: 66 | struct s_node { 67 | int value; 68 | struct s_node *next; 69 | }; 70 | The function must be declared as follows: 71 | int is_looping(struct s_node *node); 72 | Considerations: 73 | - Be careful: the naive solution won't work on our big input, you have to 74 | find a solution with better complexity than O(N^2) time (where N is the 75 | number of nodes). 76 | - The values of each node does not matter. 77 | - The bigger test we will do is on a linked list of 500.000 nodes, with the 78 | beginning of the loop at the middle. It should run in less than 2 seconds. 79 | Example 1: 80 | 1 -> 2 -> 3 -> 4 -> 5 81 | ^ | 82 | | v 83 | | 6 84 | \ | 85 | \______/ 86 | In this case, it should return 1 (at the node 3 begins the loop). 87 | Example 2: 88 | 12 -> 150 -> 30 -> 50 -> 345 -> 120 89 | ^ | 90 | | v 91 | | 200 92 | \ / 93 | \____________________/ 94 | In this case, it should return 1 (the loop begins at node 150). 95 | Example 3: 96 | 12 -> 150 -> 30 -> 50 -> 345 -> 120 97 | In this case, it should return 0 (no loop begins). 98 | Example 4: 99 | 12 -> 19 -> 14 100 | ^ \ 101 | | | 102 | \/ 103 | In this case, it should return 1 (the loop begins at node 14). 104 | */ -------------------------------------------------------------------------------- /5/g_diam.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define LIM 100 5 | 6 | int myStrLen(char* s) { 7 | int ret = 0; 8 | while (*s++) 9 | ret++; 10 | return ret; 11 | } 12 | 13 | int isNum(char c) { 14 | return ('0' <= c && c <= '9'); 15 | } 16 | 17 | int cheapAtoi(char** s) { 18 | int ret = 0; 19 | while (isNum(**s)) { 20 | ret *= 10; 21 | ret += **s - '0'; 22 | (*s)++; 23 | } 24 | if (**s != 0) 25 | (*s)++; 26 | return ret; 27 | } 28 | 29 | char* cheapItoa(int n) { 30 | int tmp = n; 31 | int len = 0; 32 | while (tmp > 0) { 33 | tmp /= 10; 34 | len++; 35 | } 36 | char* ret = malloc(len + 2); 37 | ret[len - 1] = '\n'; 38 | ret[len] = 0; 39 | for (int i = len - 1; i >= 0; i--) { 40 | ret[i] = (n % 10) + '0'; 41 | n /= 10; 42 | } 43 | return ret; 44 | } 45 | 46 | void longestPath(char matrix[LIM][LIM], int path[LIM], int pos, int chain, int* longest) { 47 | 48 | path[pos] = 1; 49 | for (int i = 0; i < LIM; i++) { 50 | if (matrix[pos][i] && path[i] == 0) { 51 | if (*longest < chain + 1) 52 | *longest = chain + 1; 53 | longestPath(matrix, path, i, chain + 1, longest); 54 | } 55 | } 56 | path[pos] = 0; 57 | } 58 | 59 | int main(int ac, char* av[]) { 60 | 61 | if (ac != 2) { write(1, "\n", 1); return 0; } 62 | 63 | char matrix[LIM][LIM] = {{0}}; 64 | 65 | char* s = av[1]; 66 | while (*s) { 67 | int src = cheapAtoi(&s); 68 | int dest = cheapAtoi(&s); 69 | matrix[src][dest] = 1; 70 | matrix[dest][src] = 1; 71 | } 72 | 73 | int longest = 2; 74 | int path[LIM] = {0}; 75 | for (int i = 0; i < LIM; i++) { 76 | longestPath(matrix, path, i, 1, &longest); 77 | } 78 | 79 | char* ret = cheapItoa(longest); 80 | write(1, ret, myStrLen(ret)); 81 | write(1, "\n", 1); 82 | return 0; 83 | } 84 | 85 | /* 86 | G_DIAM 87 | Assignment name : g_diam 88 | Expected files : *.c, *.h 89 | Allowed functions: write, malloc, free 90 | -------------------------------------------------------------------------------- 91 | 92 | Write a programe that takes a string. This string represents a graph and is 93 | composed of series of links between this graph's nodes. Links are separated by 94 | a single space. Nodes are represented by numbers, and links by two nodes 95 | separated by a '-'. For exemple, if there is a link between nodes 2 96 | and 3, it could be written as "2-3" or "3-2". 97 | 98 | The program will display the number of nodes comprised in the longest chain, 99 | followed by a '\n', given it's impossible to pass through a node more than once. 100 | 101 | If the number of parameters is different from 1, the program displays a '\n'. 102 | 103 | Examples: 104 | 105 | $>./g_diam "17-5 5-8 8-2 2-8 2-8 17-21 21-2 5-2 2-6 6-14 6-12 12-19 19-14 14-42" | cat -e 106 | 10$ 107 | $>./g_diam "1-2 2-3 4-5 5-6 6-7 7-8 9-13 13-10 10-2 10-11 11-12 12-8 16-4 16-11 21-8 21-12 18-10 18-13 21-18" | cat -e 108 | 15$ 109 | */ -------------------------------------------------------------------------------- /3/convert_bst.c: -------------------------------------------------------------------------------- 1 | typedef struct s_node { 2 | int value; 3 | struct s_node *right; 4 | struct s_node *left; 5 | } Node; 6 | 7 | Node* recurse(Node* root) { 8 | 9 | if (!root) 10 | return 0; 11 | 12 | if (root->left) { 13 | 14 | Node* left = recurse(root->left); 15 | while (left->right) 16 | left = left->right; 17 | left->right = root; 18 | root->left = left; 19 | 20 | } 21 | if (root->right) { 22 | 23 | Node* right = recurse(root->right); 24 | while (right->left) 25 | right = right->left; 26 | right->left = root; 27 | root->right = right; 28 | } 29 | return root; 30 | } 31 | 32 | Node* convert_bst(Node* bst) { 33 | if (!bst) 34 | return 0; 35 | recurse(bst); 36 | Node* left = bst; 37 | Node* right = bst; 38 | while (left->left) 39 | left = left->left; 40 | while (right->right) 41 | right = right->right; 42 | left->left = right; 43 | right->right = left; 44 | return left; 45 | } 46 | 47 | /************ 48 | Test Main 49 | ************/ 50 | 51 | #include 52 | #include 53 | Node* b(int v) { 54 | Node* new = malloc(sizeof(Node)); 55 | new->value = v; 56 | new->left = new->right = 0; 57 | return new; 58 | } 59 | int main() { 60 | Node* r = b(8); 61 | r->left = b(4); 62 | r->left->left = b(2); 63 | r->left->left->left = b(1); 64 | r->left->left->right = b(3); 65 | 66 | r->left->right = b(6); 67 | r->left->right->left = b(5); 68 | r->left->right->right = b(7); 69 | 70 | r->right = b(12); 71 | r->right->left = b(10); 72 | r->right->left->left = b(9); 73 | r->right->left->right = b(11); 74 | 75 | r->right->right = b(14); 76 | r->right->right->left = b(13); 77 | r->right->right->right = b(15); 78 | 79 | r = convert_bst(r); 80 | for (int i = 0; i < 15; i++) { 81 | printf("%d\n", r->value); 82 | r = r->right; 83 | } 84 | for (int i = 0; i < 17; i++) { 85 | printf("%d\n", r->value); 86 | r = r->left; 87 | } 88 | } 89 | 90 | /* 91 | CONVERT_BST 92 | Assignment name : convert_bst 93 | Expected files : convert_bst.c 94 | Allowed functions: 95 | -------------------------------------------------------------------------------- 96 | A binary search tree (BST) is a binary tree in which every node fits 97 | a specific ordering property : 98 | all left descendants <= n < all right descendants 99 | This must be true for each node n. 100 | Implement a function to convert a binary search tree to a sorted, circular, 101 | doubly-linked list. 102 | This conversion must be in-place (using the tree nodes as the new list nodes). 103 | The binary search tree uses the following node structure : 104 | struct s_node { 105 | int value; 106 | struct s_node *right; 107 | struct s_node *left; 108 | }; 109 | The function must be declared as follows: 110 | struct s_node *convert_bst(struct s_node *bst); 111 | The function must return a pointer to the smallest element of the sorted, 112 | circular, doubly-linked list. 113 | For each node of the linked list, the right pointer points to the next node 114 | and the left pointer points to the previous node. 115 | The sort is in increasing order. 116 | */ -------------------------------------------------------------------------------- /1/stack.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct s_node { 4 | void *content; 5 | struct s_node *next; 6 | } Node; 7 | 8 | typedef struct s_stack { 9 | struct s_node *top; 10 | } Stack; 11 | 12 | Stack* init(void) { 13 | Stack* s = malloc(sizeof(Stack)); 14 | s->top = 0; 15 | return s; 16 | } 17 | 18 | void* pop(struct s_stack *stack) { 19 | if (!stack->top) 20 | return 0; 21 | Node* tmp = stack->top; 22 | void* content = tmp->content; 23 | stack->top = tmp->next; 24 | free(tmp); 25 | return content; 26 | } 27 | 28 | void push(struct s_stack *stack, void *content) { 29 | Node* new = malloc(sizeof(Node)); 30 | new->content = content; 31 | new->next = stack->top; 32 | stack->top = new; 33 | } 34 | 35 | void *peek(struct s_stack *stack) { 36 | if (!stack->top) 37 | return 0; 38 | return stack->top->content; 39 | } 40 | 41 | int isEmpty(struct s_stack *stack) { 42 | if (!stack->top) 43 | return 1; 44 | return 0; 45 | } 46 | 47 | /************ 48 | Test Main 49 | ************/ 50 | 51 | #include 52 | int main() { 53 | 54 | Stack* s = init(); 55 | 56 | printf("Empty? %d\n", isEmpty(s)); 57 | puts("Pushing 'Hello'"); 58 | push(s, "Hello"); 59 | printf("Empty? %d\n", isEmpty(s)); 60 | printf("Peeking: %s\n", peek(s)); 61 | puts("Pushing 'World'"); 62 | push(s, "World"); 63 | printf("Empty? %d\n", isEmpty(s)); 64 | printf("Peeking: %s\n", peek(s)); 65 | puts("Pushing ':)'"); 66 | push(s, ":)"); 67 | printf("Empty? %d\n", isEmpty(s)); 68 | printf("Peeking: %s\n", peek(s)); 69 | 70 | printf("Popped: %s\n", pop(s)); 71 | printf("Popped: %s\n", pop(s)); 72 | printf("Popped: %s\n", pop(s)); 73 | printf("Popped: %s\n", pop(s)); 74 | printf("Empty? %d\n", isEmpty(s)); 75 | 76 | return 0; 77 | } 78 | 79 | /* 80 | STACK 81 | Assignment name : stack 82 | Expected files : stack.c 83 | Allowed functions: malloc free 84 | -------------------------------------------------------------------------------- 85 | Implement a stack data structure in C, using the following structures in your 86 | code: 87 | struct s_node { 88 | void *content; 89 | struct s_node *next; 90 | }; 91 | struct s_stack { 92 | struct s_node *top; 93 | }; 94 | A stack uses LIFO (last-in fist-out) ordering : 95 | the most recent item added to the stack is the first item to be removed. 96 | Implement 5 functions for the following stack operations : 97 | - init() : Initialize the stack. 98 | The top pointer is set to NULL. 99 | - pop(stack) : Remove the top item from the stack and return it. 100 | If the stack is empty, the function returns NULL. 101 | - push(stack, item) : Add an item to the top of the stack. 102 | - peek(stack) : Return the top of the stack. 103 | If the stack is empty, the function returns NULL. 104 | - isEmpty(stack) : Return 1 if the stack is empty, 0 otherwise. 105 | These functions must be declared as follows: 106 | struct s_stack *init(void); 107 | void *pop(struct s_stack *stack); 108 | void push(struct s_stack *stack, void *content); 109 | void *peek(struct s_stack *stack); 110 | int isEmpty(struct s_stack *stack); 111 | */ -------------------------------------------------------------------------------- /2/longest_sequence.c: -------------------------------------------------------------------------------- 1 | typedef struct s_node { 2 | int value; 3 | struct s_node* left; 4 | struct s_node* right; 5 | } Node; 6 | 7 | #define MAX(a, b) (a > b ? a : b) 8 | 9 | int recurse(Node* node, int parentVal, int depth) { 10 | 11 | if (!node) 12 | return 0; 13 | 14 | int current = 1; 15 | 16 | if (node->value == parentVal + 1) 17 | current = depth + 1; 18 | 19 | return MAX(MAX(recurse(node->left, node->value, current), recurse(node->right, node->value, current)), current); 20 | } 21 | 22 | int longest_sequence(Node* root) { 23 | 24 | return recurse(root, ~0u >> 1, 0); 25 | } 26 | 27 | /************ 28 | Test Main 29 | ************/ 30 | 31 | #include 32 | #include 33 | Node* b(int v) { 34 | Node* new = malloc(sizeof(Node)); 35 | new->value = v; 36 | new->left = 0; 37 | new->right = 0; 38 | return new; 39 | } 40 | int main() { 41 | Node* n = b(10); 42 | n->left = b(5); 43 | n->left->left = b(6); 44 | n->left->left->left = b(7); 45 | n->left->left->right = b(13); 46 | n->left->right = b(9); 47 | printf("%d\n", longest_sequence(n)); 48 | 49 | Node* m = b(5); 50 | m->left = b(6); 51 | m->right = b(4); 52 | m->right->left = b(9); 53 | m->right->left->left = b(3); 54 | m->right->left->right = b(2); 55 | m->right->right = b(3); 56 | m->right->right->right = b(2); 57 | printf("%d\n", longest_sequence(m)); 58 | 59 | Node* o = b(30); 60 | o->left = b(15); 61 | o->left->left = b(61); 62 | o->right = b(41); 63 | o->right->right = b(80); 64 | printf("%d\n", longest_sequence(o)); 65 | 66 | printf("%d\n", longest_sequence(0)); 67 | 68 | return 0; 69 | } 70 | 71 | /* 72 | LONGEST_SEQUENCE 73 | Assignment name : longest_sequence 74 | Expected files : longest_sequence.c 75 | Allowed functions: 76 | -------------------------------------------------------------------------------- 77 | 78 | Given the root node of a binary tree, create a function that return the length of the longest path which comprises of nodes with consecutive values in increasing order. 79 | Every node is considered as a path of length 1. 80 | 81 | The binary tree uses the following node structure : 82 | 83 | struct s_node 84 | { 85 | int value; 86 | struct s_node *left; 87 | struct s_node *right; 88 | }; 89 | 90 | The function must be declared as follows: 91 | 92 | int longest_sequence(struct s_node *node); 93 | 94 | 95 | Example 1: 96 | 97 | 10 98 | / 99 | 5 100 | / \ 101 | / \ 102 | 6 9 103 | / \ 104 | / \ 105 | 7 13 106 | 107 | In this case, it should return 3 (because the longest consecutive sequence is: 5 -> 6 -> 7). 108 | 109 | Example 2: 110 | 111 | 5 112 | / \ 113 | / \ 114 | 6 4 115 | / \ 116 | 9 3 117 | / \ \ 118 | 3 2 2 119 | 120 | In this case, your function return 2 (because the longest consecutive sequence is: 5 -> 6 ). 121 | 122 | Example 3: 123 | 124 | 30 125 | / \ 126 | / \ 127 | 15 41 128 | / / 129 | 61 80 130 | 131 | In this case, it should return 1. 132 | 133 | Example 4: 134 | 135 | NULL 136 | 137 | In this case, as the root node is null, your function should return 0. 138 | */ -------------------------------------------------------------------------------- /2/str_maxlenoc.c: -------------------------------------------------------------------------------- 1 | /* 2 | This method is incorrect and will fail edge cases where there are multiple answers AND the first string contains them in different order. 3 | eg. strings { "abc", "ba" "aab" } 4 | The result is "b", whereas the question asks for "a". 5 | However, this method is simpler (does not require keeping track of stringlengths) and passes the current (2018-02-20) intermediate exam. 6 | */ 7 | 8 | #include 9 | #include 10 | 11 | int stringLength(char *s) { 12 | int ret = 0; 13 | while (*s++) 14 | ret++; 15 | return ret; 16 | } 17 | 18 | int getMinIndex(int ac, char* av[]) { 19 | 20 | int minLen = ~0u >> 1; 21 | int minIdx = 1; 22 | for (int i = 1; i < ac; i++) { 23 | int tmp = stringLength(av[i]); 24 | if (minLen > tmp) { 25 | minLen = tmp; 26 | minIdx = i; 27 | } 28 | } 29 | return minIdx; 30 | } 31 | 32 | int unfit(char* a, char* b, int len) { 33 | 34 | for (int i = 0; i < len; i++) { 35 | if (a[i] != b[i]) { 36 | if (*(b + 1)) { 37 | b++; 38 | i = -1; 39 | } else { 40 | return 1; 41 | } 42 | } 43 | } 44 | return 0; 45 | } 46 | 47 | int findLargestMatchSize(char* key, int ac, char* av[]) { 48 | 49 | int len = stringLength(key); 50 | 51 | for (int i = 0; i < ac; i++) { 52 | if (unfit(key, av[i], len)) { 53 | if (len > 1) { 54 | len--; 55 | i = -1; 56 | } else { 57 | return -1; 58 | } 59 | } 60 | } 61 | return len; 62 | } 63 | 64 | int main(int ac, char* av[]) { 65 | 66 | if (ac <= 2) { 67 | if (ac == 2) 68 | write(1, av[1], stringLength(av[1])); 69 | write(1, "\n", 1); 70 | return 0; 71 | } 72 | int minIdx = getMinIndex(ac, av); 73 | if (minIdx != 1) { 74 | char* tmp = av[minIdx]; 75 | av[minIdx] = av[1]; 76 | av[1] = tmp; 77 | } 78 | 79 | char* key = av[1]; // I hate using av[1] over and over 80 | int currIdx = 0; 81 | int maxLen = -1, maxIdx = -1; 82 | 83 | for (int i = 2; i < ac; i++) { 84 | int tmp = findLargestMatchSize(key + currIdx, ac - 2, av + 2); 85 | if (maxLen < tmp) { 86 | maxLen = tmp; 87 | maxIdx = currIdx; 88 | } 89 | currIdx++; 90 | i = 1; 91 | if (key[currIdx] == 0) 92 | break; 93 | } 94 | if (maxIdx > -1) 95 | write(1, key + maxIdx, maxLen); 96 | write(1, "\n", 1); 97 | return 0; 98 | } 99 | 100 | /* 101 | STR_MAXLENOC 102 | Assignment name : str_maxlenoc 103 | Expected files : str_maxlenoc.c 104 | Allowed functions: write, malloc, free 105 | -------------------------------------------------------------------------------- 106 | 107 | Write a program that takes one or more strings and displays, followed by a 108 | newline, the longest string that appears in every parameter. If more that one 109 | string qualifies, it will display the one that appears first in the first 110 | parameter. Note that the empty string technically appears in any string. 111 | 112 | If there are no parameters, the program displays \n. 113 | 114 | Examples: 115 | 116 | $>./str_maxlenoc ab bac abacabccabcb 117 | a 118 | $>./str_maxlenoc bonjour salut bonjour bonjour 119 | u 120 | $>./str_maxlenoc xoxAoxo xoxAox oxAox oxo A ooxAoxx oxooxo Axo | cat -e 121 | $ 122 | $>./str_maxlenoc bosdsdfnjodur atehhellosd afkuonjosurafg headfgllosf fghellosag afdfbosnjourafg 123 | os 124 | $>./str_maxlenoc | cat -e 125 | $ 126 | */ 127 | -------------------------------------------------------------------------------- /2/ord_alphlong.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int isAlpha(char c) { 5 | return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z'); 6 | } 7 | 8 | int arrLen(char **arr) { 9 | int ret = 0; 10 | while (*arr++) 11 | ret++; 12 | return ret; 13 | } 14 | 15 | char toSmall(char c) { 16 | if ('A' <= c && c <= 'Z') 17 | return c + 32; 18 | return c; 19 | } 20 | 21 | int stringLength(char *s) { 22 | int ret = 0; 23 | while (*s++) 24 | ret++; 25 | return ret; 26 | } 27 | 28 | char* stringDupe(char* src, int len) { 29 | 30 | char* dst = malloc(len + 1); 31 | for (int i = 0; i < len; i++) 32 | dst[i] = src[i]; 33 | dst[len] = 0; 34 | return dst; 35 | } 36 | 37 | int stringComp(char* a, char* b) { 38 | 39 | while (*a && *b) 40 | if (toSmall(*a++) - toSmall(*b++) != 0) 41 | return toSmall(*(a - 1)) - toSmall(*(b - 1)); 42 | return 0; 43 | } 44 | 45 | void sortArr(char** arr) { 46 | int len = arrLen(arr); 47 | for (int i = 0; i < len - 1; i++) { 48 | if (stringComp(arr[i], arr[i + 1]) > 0) { 49 | char* tmp = arr[i]; 50 | arr[i] = arr[i + 1]; 51 | arr[i + 1] = tmp; 52 | i = 0; 53 | } 54 | } 55 | } 56 | 57 | int main(int ac, char* av[]) { 58 | if (ac != 2) { 59 | write(1, "\n", 1); 60 | return 0; 61 | } 62 | char *arr[1000][1000] = {{0}}; 63 | char* s = av[1]; 64 | while (*s) { 65 | int len = 0; 66 | while (isAlpha(*s)) { 67 | len++; 68 | s++; 69 | } 70 | if (len > 0) { 71 | for (int i = 0; i < 1000; i++) { 72 | if (arr[len][i] == 0) { 73 | arr[len][i] = stringDupe(s - len, len); 74 | break; 75 | } 76 | } 77 | } 78 | if (*s) 79 | s++; 80 | } 81 | for (int i = 0; i < 1000; i++) { 82 | if (*arr[i]) { 83 | sortArr(arr[i]); 84 | int first = 1; 85 | for (int j = 0; j < 1000; j++) { 86 | if (arr[i][j]) { 87 | if (first) { 88 | first = 0; 89 | } else { 90 | write(1, " ", 1); 91 | } 92 | write(1, arr[i][j], i); 93 | } 94 | else 95 | break; 96 | } 97 | write(1, "\n", 1); 98 | } 99 | } 100 | return 0; 101 | } 102 | 103 | /* 104 | ORD_ALPHLONG 105 | Assignment name : ord_alphlong 106 | Expected files : *.c, *.h 107 | Allowed functions: write, malloc, free 108 | -------------------------------------------------------------------------------- 109 | Write a program that takes a string as a parameter and prints its words sorted 110 | in order of their length first and then in alphabetical order on each line: 111 | when we say alphabetical order we ignore the case of letters. 112 | For example aA and Aa are the same but the original order must remain 113 | (lower and upper case are the same in alphabetical order). If there are 114 | duplicates, they must remain. 115 | If number of parameters is different from 1, the program prints 116 | \n. 117 | There will be only spaces, tabs and alphanumeric caracters in strings. 118 | You'll print only one space between each word. Nothing before the first and 119 | after the last word of each line. 120 | Examples: 121 | $>./ord_alphlong 122 | $ 123 | $>./ord_alphlong "De son baton il frappa la pierre et l eau jaillit" | cat -e 124 | l$ 125 | De et il la$ 126 | eau son$ 127 | baton$ 128 | frappa pierre$ 129 | jaillit$ 130 | $>./ord_alphlong "A a b B cc ca cd" | cat -e 131 | A a b B$ 132 | ca cc cd$ 133 | $>./ord_alphlong "Pour l Imperium de l humanite" | cat -e 134 | l l$ 135 | de$ 136 | Pour$ 137 | humanite Imperium$ 138 | $> 139 | */ -------------------------------------------------------------------------------- /1/queue.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct s_node { 4 | void *content; 5 | struct s_node *next; 6 | } Node; 7 | 8 | typedef struct s_queue { 9 | struct s_node *first; 10 | struct s_node *last; 11 | } Queue; 12 | 13 | Queue* init(void) { 14 | Queue* q = malloc(sizeof(Queue)); 15 | q->first = 0; 16 | q->last = 0; 17 | return q; 18 | } 19 | 20 | void enqueue(struct s_queue *queue, void *content) { 21 | Node* new = malloc(sizeof(Node)); 22 | new->content = content; 23 | new->next = 0; 24 | if (!queue->first) 25 | queue->first = new; 26 | if (queue->last) 27 | queue->last->next = new; 28 | queue->last = new; 29 | } 30 | 31 | void* dequeue(struct s_queue *queue) { 32 | if (!queue->first) 33 | return 0; 34 | Node* tmp = queue->first; 35 | void* content = tmp->content; 36 | queue->first = tmp->next; 37 | if (!queue->first) 38 | queue->last = 0; 39 | free(tmp); 40 | return content; 41 | } 42 | 43 | void* peek(struct s_queue *queue) { 44 | if (!queue->first) 45 | return 0; 46 | return queue->first->content; 47 | } 48 | 49 | int isEmpty(struct s_queue *queue) { 50 | if (!queue->first) 51 | return 1; 52 | return 0; 53 | } 54 | 55 | /************ 56 | Test Main 57 | ************/ 58 | 59 | #include 60 | int main() { 61 | 62 | Queue* q = init(); 63 | 64 | printf("Empty? %d\n", isEmpty(q)); 65 | printf("Enqueueing 'Hello'\n"); 66 | enqueue(q, "Hello"); 67 | printf("Empty? %d\n", isEmpty(q)); 68 | printf("Peeking: %s\n", peek(q)); 69 | printf("Enqueueing 'World'\n"); 70 | enqueue(q, "World"); 71 | printf("Empty? %d\n", isEmpty(q)); 72 | printf("Peeking: %s\n", peek(q)); 73 | printf("Enqueueing ':)'\n"); 74 | enqueue(q, ":)"); 75 | printf("Empty? %d\n", isEmpty(q)); 76 | printf("Peeking: %s\n", peek(q)); 77 | printf("Dequeue: %s\n", dequeue(q)); 78 | printf("Dequeue: %s\n", dequeue(q)); 79 | printf("Dequeue: %s\n", dequeue(q)); 80 | printf("Dequeue: %s\n", dequeue(q)); 81 | printf("Empty? %d\n", isEmpty(q)); 82 | 83 | return 0; 84 | } 85 | 86 | 87 | /* 88 | QUEUE 89 | Assignment name : queue 90 | Expected files : queue.c 91 | Allowed functions: malloc free 92 | -------------------------------------------------------------------------------- 93 | Implement a queue data structure in C, using the following structures in your 94 | code: 95 | struct s_node { 96 | void *content; 97 | struct s_node *next; 98 | }; 99 | struct s_queue { 100 | struct s_node *first; 101 | struct s_node *last; 102 | }; 103 | A queue uses FIFO (first-in fist-out) ordering : 104 | items are removed from the data structure in the same order that they are added. 105 | Implement 5 functions for the following queue operations : 106 | - init() : Initialize the queue. 107 | The first and last pointers are set to NULL. 108 | - enqueue(queue, item) : Add an item to the end of the queue. 109 | - dequeue(queue) : Remove the first item from the queue and return it. 110 | If the queue is empty, the function returns NULL. 111 | - peek(queue) : Return the first item of the queue. 112 | If the queue is empty, the function returns NULL. 113 | - isEmpty(queue) : Return 1 if the queue is empty, 0 otherwise. 114 | These functions must be declared as follows: 115 | struct s_queue *init(void); 116 | void enqueue(struct s_queue *queue, void *content); 117 | void *dequeue(struct s_queue *queue); 118 | void *peek(struct s_queue *queue); 119 | int isEmpty(struct s_queue *queue); 120 | */ 121 | -------------------------------------------------------------------------------- /4/clone_list.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct s_node { 4 | int data; 5 | struct s_node *next; 6 | struct s_node *other; 7 | } Node; 8 | 9 | Node* clone_list(Node* node) { 10 | 11 | if (!node) 12 | return 0; 13 | 14 | Node* original = node; 15 | Node* temp; 16 | 17 | // Clone list in-between original 18 | while (original) { 19 | temp = original->next; 20 | original->next = malloc(sizeof(Node)); 21 | original->next->data = original->data; 22 | original->next->other = 0; 23 | original->next->next = temp; 24 | original = temp; 25 | } 26 | 27 | original = node; 28 | 29 | // Set other pointers for cloned list 30 | while (original) { 31 | if (original->other) 32 | original->next->other = original->other->next; 33 | if (original->next) 34 | original = original->next->next; 35 | else 36 | break; 37 | } 38 | 39 | original = node; 40 | Node* copy = node->next; 41 | Node* copyHead = copy; 42 | 43 | while (original && copy) { 44 | if (original->next) 45 | original->next = original->next->next; 46 | if (copy->next) 47 | copy->next = copy->next->next; 48 | original = original->next; 49 | copy = copy->next; 50 | } 51 | return copyHead; 52 | } 53 | 54 | /************ 55 | Test Main 56 | ************/ 57 | 58 | #include 59 | Node* b(int v) { 60 | Node* new = malloc(sizeof(Node)); 61 | new->data = v; 62 | new->next = 0; 63 | new->other = 0; 64 | return new; 65 | } 66 | int main() { 67 | Node* a = b(1); 68 | a->next = b(2); 69 | a->next->next = b(3); 70 | a->next->next->next = b(4); 71 | a->next->next->next->next = b(5); 72 | a->next->next->next->next->next = b(6); 73 | a->next->next->next->next->next->next = b(7); 74 | 75 | Node* a2 = a->next; 76 | Node* a3 = a2->next; 77 | Node* a4 = a3->next; 78 | Node* a5 = a4->next; 79 | Node* a6 = a5->next; 80 | Node* a7 = a6->next; 81 | 82 | a2->other = a7; 83 | a3->other = a; 84 | a5->other = a5; 85 | a7->other = a4; 86 | 87 | Node* clone = clone_list(a); 88 | Node* original = a; 89 | puts("Original:"); 90 | while (original) { 91 | printf("Val: %d | Other: %d\n", original->data, original->other ? original->other->data : -1); 92 | original = original->next; 93 | } 94 | puts("Clone:"); 95 | while (clone) { 96 | printf("Val: %d | Other: %d\n", clone->data, clone->other ? clone->other->data : -1); 97 | clone = clone->next; 98 | } 99 | return 0; 100 | } 101 | 102 | 103 | /* 104 | CLONE_LIST 105 | Assignment name : clone_list 106 | Expected files : clone_list.c 107 | Allowed functions: malloc 108 | -------------------------------------------------------------------------------- 109 | Given a linked list with the following structure : 110 | struct s_node { 111 | int data; 112 | struct s_node *next; 113 | struct s_node *other; 114 | }; 115 | where : 116 | - next pointer points to the next node. 117 | - other pointer points to any node in the list (another node, itself or NULL). 118 | Write a function to create a copy of this list (allocate new memory). 119 | You cannot modify the structure, you cannot modify the list you are given. 120 | The function must be declared as follows: 121 | struct s_node *clone_list(struct s_node *node); 122 | */ 123 | -------------------------------------------------------------------------------- /3/gold_gain.c: -------------------------------------------------------------------------------- 1 | #define MAX(a, b, c) (a > b && a > c ? a : b > c ? b : c) 2 | 3 | int gold_gain(int** mine, int n) { 4 | int max = 0; 5 | for (int col = 1; col < n; col++) { 6 | for (int row = 0; row < n; row++) { 7 | int a = 0, b = 0, c = 0; 8 | if (row > 0) 9 | a = mine[row - 1][col - 1]; 10 | b = mine[row][col - 1]; 11 | if (row < n - 1) 12 | c = mine[row + 1][col - 1]; 13 | mine[row][col] += MAX(a, b, c); 14 | if (col == n - 1) { 15 | if (max < mine[row][col]) 16 | max = mine[row][col]; 17 | } 18 | } 19 | } 20 | return max; 21 | } 22 | 23 | /************ 24 | Test Main 25 | ************/ 26 | 27 | #include 28 | #include 29 | int main() { 30 | 31 | int** a = malloc(sizeof(int*) * 3); 32 | int a1[3] = { 1, 0, 0 }; 33 | int a2[3] = { 0, 3, 4 }; 34 | int a3[3] = { 0, 0, 0 }; 35 | a[0] = a1; 36 | a[1] = a2; 37 | a[2] = a3; 38 | printf("%d\n", gold_gain(a, 3)); 39 | 40 | int** b = malloc(sizeof(int*) * 3); 41 | int b1[3] = { 1, 2, 3 }; 42 | int b2[3] = { 3, 4, 8 }; 43 | int b3[3] = { 9, 6, 7 }; 44 | b[0] = b1; 45 | b[1] = b2; 46 | b[2] = b3; 47 | printf("%d\n", gold_gain(b, 3)); 48 | 49 | int** c = malloc(sizeof(int*) * 4); 50 | int c1[4] = { 1, 3, 1, 5 }; 51 | int c2[4] = { 2, 2, 4, 1 }; 52 | int c3[4] = { 5, 0, 2, 3 }; 53 | int c4[4] = { 0, 6, 1, 2 }; 54 | c[0] = c1; 55 | c[1] = c2; 56 | c[2] = c3; 57 | c[3] = c4; 58 | printf("%d\n", gold_gain(c, 4)); 59 | 60 | return 0; 61 | } 62 | 63 | /* 64 | GOLD_GAIN 65 | Assignment name : gold_gain 66 | Expected files : gold_gain.c 67 | Allowed functions: malloc 68 | -------------------------------------------------------------------------------- 69 | ALERT: OPTIMIZED SOLUTION REQUIRED. 70 | Given a matrix which represent a gold mine of n*n dimensions. 71 | Each field in this mine contains a positive integer which is the 72 | amount of gold in tons. 73 | Initially the miner is at first column but can be at any row. 74 | He can move only (right->,right up /,right down\) that is from a given cell, 75 | the miner can move to the cell diagonally up towards the right or right or 76 | diagonally down towards the right. 77 | implement an algorithm able to return the maximum amount of gold he can collect. 78 | The function must be declared as follows: 79 | int gold_gain(int **mine, int n); 80 | Considerations: 81 | - Be careful: the brute force solution won't work on our big input, you have to 82 | find an optimized solution which use dynamic programming. 83 | - You don't have to handle error case, the matrix will be always squared. 84 | - The bigger test we will do is on matrix of 1 000 * 1 000, 85 | it should run in less than 2 seconds. 86 | Example 1: 87 | mine = [ 88 | [ 1, 0, 0 ], 89 | [ 0, 3, 4 ], 90 | [ 0, 0, 0 ] 91 | ] 92 | n = 3 93 | In this example, your function should return 8, 94 | because taking the following path gain 8: 95 | (0,0) -> (1,1) -> (1,2) 96 | 1 -> 3 -> 4 97 | Example 2: 98 | mine = [ 99 | [ 1, 2, 3 ], 100 | [ 3, 4, 8 ], 101 | [ 9, 6, 7 ] 102 | ] 103 | n = 3 104 | In this example, your function should return 23, 105 | because taking the following path gain 23: 106 | (2,0) -> (2,1) -> (1,3) 107 | Example 3: 108 | mine = [ 109 | [ 1, 3, 1, 5 ], 110 | [ 2, 2, 4, 1 ], 111 | [ 5, 0, 2, 3 ], 112 | [ 0, 6, 1, 2 ] 113 | ] 114 | n = 4 115 | In this example, your function should return 16, 116 | because there is 2 path which give this gain: 117 | (2,0) -> (1,1) -> (1,2) -> (0,3) 118 | or 119 | (2,0) -> (3,1) -> (2,2) -> (2,3) 120 | */ -------------------------------------------------------------------------------- /3/can_split.c: -------------------------------------------------------------------------------- 1 | typedef struct s_node 2 | { 3 | int value; 4 | struct s_node *left; 5 | struct s_node *right; 6 | } Node; 7 | 8 | int count(Node* n) { 9 | 10 | if (!n) 11 | return 0; 12 | return count(n->left) + count(n->right) + 1; 13 | } 14 | 15 | int checkIt(Node* n, int* canSplit, int totalNodes) { 16 | 17 | if (!n) 18 | return 0; 19 | 20 | int c = checkIt(n->left, canSplit, totalNodes) + checkIt(n->right, canSplit, totalNodes) + 1; 21 | if (totalNodes - c == c) 22 | *canSplit = 1; 23 | return c; 24 | } 25 | 26 | int can_split(struct s_node *n) { 27 | 28 | int totalNodes = count(n); 29 | if (totalNodes % 2) 30 | return 0; 31 | 32 | int canSplit = 0; 33 | checkIt(n, &canSplit, totalNodes); 34 | return canSplit; 35 | } 36 | 37 | /************ 38 | Test Main 39 | ************/ 40 | 41 | #include 42 | #include 43 | Node* b(int v) { 44 | Node* new = malloc(sizeof(Node)); 45 | new->value = v; 46 | new->left = new->right = 0; 47 | return new; 48 | } 49 | int main() { 50 | Node* ex1 = b(28); 51 | ex1->left = b(51); 52 | ex1->left->left = b(26); 53 | ex1->left->left->left = b(76); 54 | ex1->left->left->right = b(13); 55 | ex1->left->right = b(48); 56 | 57 | printf("%d\n", can_split(ex1)); 58 | 59 | Node* ex2 = b(30); 60 | ex2->left = b(15); 61 | ex2->left->left = b(61); 62 | ex2->right = b(41); 63 | ex2->right->right = b(80); 64 | 65 | printf("%d\n", can_split(ex2)); 66 | 67 | 68 | Node* ex3 = b(10); 69 | ex3->left = b(12); 70 | 71 | printf("%d\n", can_split(ex3)); 72 | 73 | Node* ex4 = b(5); 74 | ex4->left = b(1); 75 | ex4->right = b(6); 76 | ex4->right->left = b(7); 77 | ex4->right->left->left = b(3); 78 | ex4->right->left->left = b(2); 79 | ex4->right->right = b(4); 80 | ex4->right->right->right = b(8); 81 | 82 | printf("%d\n", can_split(ex4)); 83 | 84 | return 0; 85 | } 86 | /* 87 | CAN_SPLIT 88 | Assignment name : can_split 89 | Expected files : can_split.c 90 | Allowed functions: 91 | -------------------------------------------------------------------------------- 92 | ALERT: OPTIMIZED SOLUTION REQUIRED. 93 | Given the root node of a binary tree, create a function that returns 1 if, by 94 | removing one edge of the tree, it can be splitted in two trees with the same 95 | number of nodes (same 'size'). 96 | The binary tree uses the following node structure : 97 | struct s_node 98 | { 99 | int value; 100 | struct s_node *left; 101 | struct s_node *right; 102 | }; 103 | The function must be declared as follows: 104 | int can_split(struct s_node *n); 105 | Consideration: 106 | - Be careful: the naive solution won't work on our big input, you have to find 107 | an optimized solution which will run in O(N) time (where N is the number of nodes). 108 | - The bigger test we will do is about 250 000 nodes. It should run in less 109 | than 2 seconds. 110 | Example 1: 111 | 28 112 | / 113 | 51 114 | / \ 115 | / \ 116 | 26 48 117 | / \ 118 | / \ 119 | 76 13 120 | In this case, it should return 1 (remove the edge between 51 and 26 will split the tree 121 | in 2 trees with each a size of 3). 122 | Example 2: 123 | 30 124 | / \ 125 | / \ 126 | 15 41 127 | / / 128 | 61 80 129 | In this case, it should return 0 (you can't split the tree and make 2 trees with the 130 | same size). 131 | Example 3: 132 | 10 133 | \ 134 | 12 135 | In this case, your function return 1. 136 | Example 4: 137 | 5 138 | / \ 139 | / \ 140 | 1 6 141 | / \ 142 | 7 4 143 | / \ \ 144 | 3 2 8 145 | In this case, your function should return 0. 146 | */ -------------------------------------------------------------------------------- /3/width_tree.c: -------------------------------------------------------------------------------- 1 | typedef struct s_node { 2 | int value; 3 | struct s_node *left; 4 | struct s_node *right; 5 | } Node; 6 | 7 | #define MAX(a, b) (a > b ? a : b) 8 | 9 | int longest(Node* n) { 10 | if (!n) 11 | return 0; 12 | return MAX(longest(n->left), longest(n->right)) + 1; 13 | } 14 | 15 | int width_tree(Node* n) { 16 | 17 | if (!n) 18 | return 0; 19 | 20 | int width = longest(n->left) + longest(n->right) + 1; 21 | 22 | return MAX(MAX(width_tree(n->left), width_tree(n->right)), width); 23 | } 24 | 25 | /************ 26 | Test Main 27 | ************/ 28 | 29 | #include 30 | #include 31 | Node* b(int v) { 32 | Node* new = malloc(sizeof(Node)); 33 | new->value = v; 34 | new->left = new->right = 0; 35 | return new; 36 | } 37 | int main() { 38 | Node* r = b(1); 39 | 40 | r->left = b(2); 41 | r->left->left = b(3); 42 | r->left->right = b(4); 43 | r->left->right->left = b(6); 44 | 45 | r->right = b(5); 46 | r->right->left = b(7); 47 | r->right->right = b(8); 48 | 49 | printf("%d\n", width_tree(r)); 50 | 51 | Node* a = b(1); 52 | 53 | a->left = b(2); 54 | a->left->left = b(4); 55 | a->left->left->left = b(5); 56 | a->left->left->left->right = b(8); 57 | 58 | a->left->left->right = b(6); 59 | a->left->right = b(7); 60 | a->left->right->left = b(9); 61 | a->left->right->left->left = b(11); 62 | a->left->right->left->right = b(12); 63 | 64 | a->left->right->right = b(10); 65 | a->left->right->right->right = b(13); 66 | 67 | a->right = b(3); 68 | printf("%d\n", width_tree(a)); 69 | 70 | Node* c = b(10); 71 | c->right = b(12); 72 | printf("%d\n", width_tree(c)); 73 | 74 | Node *d = b(25); 75 | d->left = b(33); 76 | d->left->left = b(12); 77 | d->left->right = b(9); 78 | d->left->right->left = b(3); 79 | printf("%d\n", width_tree(d)); 80 | 81 | Node *e = b(10); 82 | printf("%d\n", width_tree(e)); 83 | 84 | return 0; 85 | } 86 | 87 | /* 88 | WIDTH_TREE 89 | 90 | Assignment name : width_tree 91 | Expected files : width_tree.c 92 | Allowed functions: 93 | -------------------------------------------------------------------------------- 94 | 95 | ALERT: OPTIMIZED SOLUTION REQUIRED. 96 | 97 | Given the root node of a binary tree, create a function that returns the 98 | 'width' of the tree, which is the number of node present on the longest 99 | path between two leaves in the tree. 100 | 101 | The binary tree uses the following node structure : 102 | 103 | struct s_node 104 | { 105 | int value; 106 | struct s_node *left; 107 | struct s_node *right; 108 | }; 109 | 110 | The function must be declared as follows: 111 | 112 | int width_tree(struct s_node *n); 113 | 114 | Consideration: 115 | 116 | - Be careful: the naive solution won't work on our big input, you have to find 117 | an optimized solution which will run in O(N) time (where N is the number of nodes). 118 | - The values of each node does not matter. 119 | - The bigger test we will do is about 250 000 nodes. It should run in less 120 | than 2 seconds. 121 | 122 | Example 1: 123 | 124 | 1 125 | / \ 126 | 2 \ 127 | / \ \ 128 | 3 4 5 129 | / / \ 130 | 6 7 8 131 | 132 | In this case, your function should return 6, 133 | 134 | because the longest path between two leaves is 6->4->2->1->5->7 (or finish by 8), 135 | which contains 6 nodes, so the tree have a 'width' of 6. 136 | 137 | Example 2: 138 | 139 | 1 140 | / \ 141 | 2 \ 142 | / \ 3 143 | 4 \ 144 | / \ \ 145 | 5 6 7 146 | \ / \ 147 | 8 9 10 148 | / \ \ 149 | 11 12 13 150 | 151 | In this case, your function should return 7, 152 | 153 | because the longest path between two leaves is 8->5->4->2->7->9->11 . 154 | 155 | Example 3: 156 | 157 | 10 158 | \ 159 | 12 160 | 161 | In this case, your function should return 2. 162 | 163 | Example 4: 164 | 165 | 25 166 | / 167 | 33 168 | / \ 169 | 12 9 170 | / 171 | 3 172 | In this case, your function should return 4. 173 | 174 | Example 5: 175 | 176 | 10 177 | (here is a root with no children) 178 | In this case, your function should return 1. 179 | */ -------------------------------------------------------------------------------- /5/infin_add.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define SWAP(x, y) do { typeof(x) SWAP = x; x = y; y = SWAP; } while (0) 5 | 6 | int myStrLen(char* s) { 7 | int ret = 0; 8 | while (*s++) 9 | ret++; 10 | return ret; 11 | } 12 | 13 | int biggest(char* s1, char* s2, int l1, int l2) { 14 | 15 | if (l1 > l2) { 16 | return 1; 17 | } else if (l1 < l2) { 18 | return 2; 19 | } else { 20 | while (*s1 == *s2) { 21 | if (*s1 == 0 && *s2 == 0) 22 | return -1; 23 | s1++; 24 | s2++; 25 | } 26 | if (*s1 > *s2) 27 | return 1; 28 | else 29 | return 2; 30 | } 31 | } 32 | 33 | void doSub(char* s1, char* s2) { 34 | 35 | int neg1 = 0, neg2 = 0; 36 | if (*s1 == '-') { 37 | s1++; 38 | neg1 = 1; 39 | } else { 40 | s2++; 41 | neg2 = 1; 42 | } 43 | while (*s1 == '0') 44 | s1++; 45 | while (*s2 == '0') 46 | s2++; 47 | 48 | int l1 = myStrLen(s1) - 1, l2 = myStrLen(s2) - 1; 49 | int big = biggest(s1, s2, l1 + 1, l2 + 1); 50 | 51 | int isNeg = 0; 52 | if (big == -1) { 53 | write(1, "0\n", 2); 54 | return; 55 | } else if (big == 1) { 56 | if (neg1) 57 | isNeg = 1; 58 | } else { 59 | SWAP(s1, s2); 60 | SWAP(l1, l2); 61 | if (neg2) 62 | isNeg = 1; 63 | } 64 | 65 | char ret[l1 + l2 + 2]; 66 | for (int i = 0; i < l1 + l2 + 2; i++) 67 | ret[i] = 0; 68 | 69 | int idx = 0; 70 | while (l1 >= 0 && l2 >= 0) { 71 | if (s1[l1] < s2[l2]) { 72 | int inc = 1; 73 | while (s1[l1 - inc] == '0') 74 | inc++; 75 | s1[l1 - inc--] -= 1; 76 | while (inc > 0) 77 | s1[l1 - inc--] += 9; 78 | s1[l1] += 10; 79 | } 80 | int a = s1[l1], b = s2[l2]; 81 | ret[idx++] = (a - b) + '0'; 82 | l1--; 83 | l2--; 84 | } 85 | 86 | while (l1 >= 0) 87 | ret[idx++] = s1[l1--]; 88 | 89 | while (ret[idx - 1] == '0' && idx > 1) 90 | ret[--idx] = 0; 91 | 92 | if (isNeg) 93 | ret[idx++] = '-'; 94 | 95 | idx--; 96 | while (idx >= 0) 97 | write(1, &ret[idx--], 1); 98 | write(1, "\n", 1); 99 | } 100 | 101 | void doAdd(char* s1, char* s2, int neg) { 102 | 103 | if (*s1 == '-') 104 | s1++; 105 | if (*s2 == '-') 106 | s2++; 107 | 108 | int l1 = myStrLen(s1) - 1, l2 = myStrLen(s2) - 1; 109 | char ret[l1 + l2 + 2]; 110 | for (int i = 0; i < l1 + l2 + 2; i++) 111 | ret[i] = 0; 112 | 113 | int idx = 0, carry = 0; 114 | while (l1 >= 0 && l2 >= 0) { 115 | int a = s1[l1] - '0', b = s2[l2] - '0'; 116 | int sum = a + b + carry; 117 | carry = sum / 10; 118 | ret[idx++] = sum % 10 + '0'; 119 | l1--; 120 | l2--; 121 | } 122 | 123 | if (l1 >= 0 || l2 >= 0) { 124 | char* s = l1 >= 0 ? s1 : s2; 125 | int l = l1 >= 0 ? l1 : l2; 126 | while (l >= 0) { 127 | int sum = s[l] - '0' + carry; 128 | carry = sum / 10; 129 | ret[idx++] = sum % 10 + '0'; 130 | l--; 131 | } 132 | } 133 | 134 | if (carry) 135 | ret[idx++] = carry + '0'; 136 | 137 | while (ret[idx - 1] == '0' && idx != 1) 138 | ret[--idx] = 0; 139 | 140 | if (neg) 141 | ret[idx++] = '-'; 142 | 143 | idx--; 144 | while (idx >= 0) 145 | write(1, &ret[idx--], 1); 146 | write(1, "\n", 1); 147 | } 148 | 149 | int main(int ac, char* av[]) { 150 | 151 | if (ac != 3) 152 | return 0; 153 | 154 | int neg1 = 0, neg2 = 0, isNeg = 0, hasNeg = 0; 155 | if (*av[1] == '-') { 156 | neg1 = 1; 157 | hasNeg = 1; 158 | } 159 | if (*av[2] == '-') { 160 | neg2 = 1; 161 | hasNeg = 1; 162 | } 163 | if ((neg1 && !neg2) || (!neg1 && neg2)) 164 | isNeg = 1; 165 | if (isNeg) 166 | doSub(av[1], av[2]); 167 | else 168 | doAdd(av[1], av[2], hasNeg); 169 | return 0; 170 | } 171 | 172 | /* 173 | INFIN_ADD 174 | Assignment name : infin_add 175 | Expected files : *.c, *.h 176 | Allowed functions: write, malloc, free 177 | -------------------------------------------------------------------------------- 178 | Write a program that takes as a parameter two strings that represent two 179 | numbers potentially infinit, and displays on stdout the result of the addition 180 | of these two numbers, followed by a '\n'. 181 | A negative number will always be prefixed by one and only one -. The only 182 | characters that can be part of the strings are digits and the sign -. 183 | Both parameters will always be well formated, and you will always have 184 | exactly two parameters, no tricks. 185 | Example: 186 | $> ./infin_add "879879087" "67548976597" | cat -e 187 | 68428855684$ 188 | $> ./infin_add "-876435" "987143265" | cat -e 189 | 986266830$ 190 | $> ./infin_add "-807965" "-34532" 191 | -842497 192 | $> 193 | */ -------------------------------------------------------------------------------- /3/perimeter.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | typedef struct s_node { 4 | int value; 5 | struct s_node *right; 6 | struct s_node *left; 7 | } Node; 8 | 9 | void doLeft(Node* root) { 10 | if (root->left) { 11 | printf(" %d", root->value); 12 | doLeft(root->left); 13 | } 14 | } 15 | 16 | void doBot(Node* root) { 17 | if (root->left) 18 | doBot(root->left); 19 | if (root->right) 20 | doBot(root->right); 21 | if (!root->left && !root->right) 22 | printf(" %d", root->value); 23 | } 24 | 25 | void doRight(Node* root) { 26 | if (root->right) { 27 | doRight(root->right); 28 | printf(" %d", root->value); 29 | } 30 | } 31 | 32 | void perimeter(Node* root) { 33 | 34 | if (root) 35 | printf("%d", root->value); 36 | if (root->left) { 37 | doLeft(root->left); 38 | doBot(root->left); 39 | } 40 | if (root->right) { 41 | doBot(root->right); 42 | doRight(root->right); 43 | } 44 | printf("\n"); 45 | } 46 | 47 | /************ 48 | Test Main 49 | ************/ 50 | #include 51 | Node* b(int v) { 52 | Node* new = malloc(sizeof(Node)); 53 | new->value = v; 54 | new->left = new->right = 0; 55 | return new; 56 | } 57 | int main() { 58 | 59 | Node* r = b(92); 60 | 61 | r->left = b(85); 62 | r->left->left = b(79); 63 | r->left->right = b(10); 64 | r->left->right->left = b(39); 65 | r->left->right->left->left = b(35); 66 | r->left->right->left->left->left = b(96); 67 | 68 | r->right = b(26); 69 | r->right->right = b(64); 70 | r->right->right->left = b(40); 71 | r->right->right->left->left = b(88); 72 | r->right->right->left->left->left = b(12); 73 | r->right->right->left->left->left->left = b(58); 74 | 75 | r->right->right->left->left->right = b(55); 76 | r->right->right->left->left->right->left = b(58); 77 | r->right->right->left->left->right->right = b(41); 78 | 79 | r->right->right->left->right = b(10); 80 | r->right->right->left->right->left = b(52); 81 | r->right->right->left->right->left->left = b(22); 82 | r->right->right->left->right->left->right = b(35); 83 | 84 | r->right->right->left->right->right = b(87); 85 | r->right->right->left->right->right->right = b(31); 86 | 87 | 88 | r->right->right->right = b(78); 89 | r->right->right->right->left = b(2); 90 | r->right->right->right->left->left = b(33); 91 | r->right->right->right->left->left->right = b(55); 92 | 93 | r->right->right->right->left->right = b(11); 94 | r->right->right->right->left->right->left = b(99); 95 | 96 | r->right->right->right->right = b(85); 97 | r->right->right->right->right->right = b(51); 98 | 99 | perimeter(r); 100 | return 0; 101 | } 102 | 103 | 104 | /* 105 | PERIMETER 106 | Assignment name : perimeter 107 | Expected files : perimeter.c 108 | Allowed functions: printf 109 | -------------------------------------------------------------------------------- 110 | Implement a function which prints the perimeter of a binary tree. 111 | The perimeter is defined as follows : 112 | - leftmost nodes from top to bottom 113 | - leaf nodes from left to right 114 | - rightmost nodes from bottom to top 115 | The binary tree uses the following node structure : 116 | struct s_node { 117 | int value; 118 | struct s_node *right; 119 | struct s_node *left; 120 | }; 121 | The function prints on the standard output the value of the nodes 122 | seperated by a single space and with a new line at the end. 123 | The function must be declared as follows: 124 | void perimeter(struct s_node *root); 125 | EXAMPLE : 126 | For the following tree : 127 | 92 128 | / \ 129 | / \ 130 | 85 26 131 | / \ 132 | 79 64 133 | \ / \ 134 | 10 / \ 135 | / / \ 136 | 39 / \ 137 | / / \ 138 | 35 / \ 139 | / / \ 140 | 96 / \ 141 | / \ 142 | 40 78 143 | / \ / \ 144 | / \ / \ 145 | / \ 2 85 146 | / \ / \ \ 147 | / \ / \ 51 148 | / \ / \ 149 | / \ 33 11 150 | 88 10 \ / 151 | / \ / \ 55 99 152 | / \ / \ 153 | 12 55 52 87 154 | / / \ / \ \ 155 | 58 / \ / \ 31 156 | 58 41 22 35 157 | the output would be : 158 | 92 85 79 96 58 58 41 22 35 31 55 99 51 85 78 64 26 159 | */ -------------------------------------------------------------------------------- /5/count_island.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define LIM 100000 6 | 7 | int errorCheck(char buf[LIM], int size, int width, int height) { 8 | 9 | if (size / height != width) { 10 | write(1, "\n", 1); 11 | return 0; 12 | } 13 | 14 | for (int i = 0; i < size; i++) { 15 | if (buf[i] != '.' && buf[i] != 'X' && buf[i] != '\n') 16 | return 0; 17 | } 18 | 19 | return 1; 20 | } 21 | 22 | void floodFill(char buf[LIM], int size, int width, int height, int i, char replacer) { 23 | 24 | buf[i] = replacer; 25 | 26 | if ((i > width) && (buf[i - width] == 'X')) 27 | floodFill(buf, size, width, height, i - width, replacer); 28 | 29 | if ((i < size - width - 1) && buf[i + width] == 'X') 30 | floodFill(buf, size, width, height, i + width, replacer); 31 | 32 | if (i && (i % width > 0) && buf[i - 1] == 'X') 33 | floodFill(buf, size, width, height, i - 1, replacer); 34 | 35 | if (i && (i % width < width - 1) && buf[i + 1] == 'X') 36 | floodFill(buf, size, width, height, i + 1, replacer); 37 | } 38 | 39 | void countIsland(char* file) { 40 | 41 | char buf[LIM] = {0}; 42 | int fd = open(file, O_RDONLY); 43 | 44 | int size = read(fd, buf, LIM); 45 | if (size < 0) { 46 | write(1, "\n", 1); 47 | return; 48 | } 49 | 50 | int width = 1; 51 | for (int i = 0; buf[i] != '\n'; i++) 52 | width++; 53 | 54 | int height = size / width; 55 | 56 | if (!errorCheck(buf, size, width, height)) 57 | return; 58 | 59 | char replacer = '0'; 60 | for (int i = 0; i < size; i++) { 61 | if (buf[i] == 'X') { 62 | floodFill(buf, size, width, height, i, replacer); 63 | replacer++; 64 | } 65 | } 66 | write(1, buf, size); 67 | } 68 | 69 | int main(int ac, char* av[]) { 70 | if (ac == 2) 71 | countIsland(av[1]); 72 | return 0; 73 | } 74 | 75 | /* 76 | COUNT_ISLAND 77 | Assignment name : count_island 78 | Expected files : *.c, *.h 79 | Allowed functions: open, close, read, write, malloc, free 80 | -------------------------------------------------------------------------------- 81 | Write a program that takes a file that contains lines of equal length. Those 82 | lines contain characters that are either '.' or 'X'. All those lines put 83 | together form rectangles of '.' containing "islands" of 'X'. 84 | The maximum size of a line is 1024 characters, including the terminating 85 | newline. 86 | A column if formed of the set of characters in the file that are separated from 87 | the start of their respective lines by the same number of characters. 88 | Two characters are said to be touching if they are contiguous and on the same 89 | line, or on contiguous lines and on the same column. 90 | An "island" of 'X' means a set of 'X' touching each other. 91 | The program must walk though the file and display it after replacing all the 92 | 'X' by a number corresponding to the position their island appears in the file, 93 | starting at the beginning of the file. 94 | There can be only one result. 95 | If the file is empty, or there is an error (Incoherent input, for example), or 96 | no parameters are passed, the program must display a newline. 97 | The file contains at most 10 islands. 98 | You will find examples in the subject directory. 99 | Examples: 100 | $>cat toto 101 | .................XXXXXXXX.......................................... 102 | ....................XXXXXXXXX.......XXXXXXXX....................... 103 | .................XXXXXXXX..............XXX...XXXXX................. 104 | .....................XXXXXX.....X...XXXXXXXXXXX.................... 105 | ................................X.................................. 106 | ......XXXXXXXXXXXXX.............X.................................. 107 | ..................X.............XXXXXXXXX.......................... 108 | ..................X.........XXXXXXXXXXXX........................... 109 | ..................X................................................ 110 | XX.............................................................XXXX 111 | XX..................XXXXXXXXXXXXX.................................X 112 | ................................................................... 113 | .................................................................X. 114 | .....................XXXXX.......................................XX 115 | $> 116 | $>./count_island toto 117 | .................00000000.......................................... 118 | ....................000000000.......11111111....................... 119 | .................00000000..............111...11111................. 120 | .....................000000.....2...11111111111.................... 121 | ................................2.................................. 122 | ......3333333333333.............2.................................. 123 | ..................3.............222222222.......................... 124 | ..................3.........222222222222........................... 125 | ..................3................................................ 126 | 44.............................................................5555 127 | 44..................6666666666666.................................5 128 | ................................................................... 129 | .................................................................7. 130 | .....................88888.......................................77 131 | $> 132 | $>cat qui_est_la 133 | ................................................................... 134 | ...X........X.....XXXXX......XXXXXXX...XXXXXXXXXX..XXXXXXXXXX...... 135 | ...XX......XX....XX...XX....XX.....XX.....XXXX.....XXXXXXXXXX...... 136 | ...XXXX..XXXX...XX.....XX...XX.....XX......XX......XX.............. 137 | ...XX.XXXX.XX...XX.....XX...XX.....XX......XX......XX.............. 138 | ...XX...X..XX...XX.....XX...XXXXXXXX.......XX......XXXXX........... 139 | ...XX......XX...XXXXXXXXX...XXXX...........XX......XXXXX........... 140 | ...XX......XX..XX.......XX..XX.XX..........XX......XX.............. 141 | ...XX......XX..XX.......XX..XX...X.........XX......XX.............. 142 | ...XX......XX..XX.......XX..XX....X......XXXXXX....XXXXXXXXXX...... 143 | ...XX......XX.XX.........XX.XX.....XX..XXXXXXXXXX..XXXXXXXXXX..X... 144 | ................................................................... 145 | $> 146 | $>./count_island qui_est_la 147 | ................................................................... 148 | ...0........0.....11111......2222222...3333333333..4444444444...... 149 | ...00......00....11...11....22.....22.....3333.....4444444444...... 150 | ...0000..0000...11.....11...22.....22......33......44.............. 151 | ...00.0000.00...11.....11...22.....22......33......44.............. 152 | ...00...0..00...11.....11...22222222.......33......44444........... 153 | ...00......00...111111111...2222...........33......44444........... 154 | ...00......00..11.......11..22.22..........33......44.............. 155 | ...00......00..11.......11..22...5.........33......44.............. 156 | ...00......00..11.......11..22....6......333333....4444444444...... 157 | ...00......00.11.........11.22.....77..3333333333..4444444444..8... 158 | ................................................................... 159 | $> 160 | $>cat -e rien 161 | $>./count_island rien | cat -e 162 | $ 163 | $> 164 | */ --------------------------------------------------------------------------------