42 Exam Solutions [dark]
* rank02 (55 questions, 44 solved) * rank03 (8 questions, 2 solved) * rank04 (5 questions, 0 solved) * rank05 (5 questions, 0 solved)
rank02/level0
* first_word [solved]
Assignment name : first_word Expected files : first_word.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and displays its first word, followed by a newline. A word is a section of string delimited by spaces/tabs or by the start/end of the string. If the number of parameters is not 1, or if there are no words, simply display a newline. Examples: $> ./first_word "FOR PONY" | cat -e FOR$ $> ./first_word "this ... is sparta, then again, maybe not" | cat -e this$ $> ./first_word " " | cat -e $ $> ./first_word "a" "b" | cat -e $ $> ./first_word " lorem,ipsum " | cat -e lorem,ipsum$ $>
solution
#include <unistd.h>

int is_space(char c) {
    return (c == ' ' || (c >= 9 && c <= 13));
}

int main(int ac, char **av) {
    if (ac == 2) {
        int i = 0;
        int start = 0;
        int end = 0;
        if (av[1][i]) {
            while (av[1][i] && is_space(av[1][i])) 
                i++;
            start = i;
            while (av[1][i] && !is_space(av[1][i]))
                i++;
            end = i;
            while (start < end) 
                write(1, &av[1][start++], 1);
        }
    }
    write(1, "\n", 1);
    return 0;
}
* fizzbuzz [solved]
Assignment name : fizzbuzz Expected files : fizzbuzz.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that prints the numbers from 1 to 100, each separated by a newline. If the number is a multiple of 3, it prints 'fizz' instead. If the number is a multiple of 5, it prints 'buzz' instead. If the number is both a multiple of 3 and a multiple of 5, it prints 'fizzbuzz' instead. Example: $>./fizzbuzz 1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz [...] 97 98 fizz buzz $>
solution
* ft_putstr [solved]
Assignment name : ft_putstr Expected files : ft_putstr.c Allowed functions: write -------------------------------------------------------------------------------- Write a function that displays a string on the standard output. The pointer passed to the function contains the address of the string's first character. Your function must be declared as follows: void ft_putstr(char *str);
solution
/* ************************************************************************** */
/*                                                                            */
/*                                                          :::      ::::::   */
/*   ft_putstr.c                                        :+:      :+:    :+:   */
/*                                                  +:+ +:+           +:+     */
/*   By: yiyuli <yy@eyuan.me>                     +#+  +:+         +#+        */
/*                                              +#+#+#+#+#+      +#+          */
/*   Created: 2025/12/21 14:22:32 by yiyuli           #+#      #+#            */
/*   Updated: 2025/12/21 14:22:53 by yiyuli         ###      ########.fr      */
/*                                                                            */
/* ************************************************************************** */

#include <stdio.h>

int	main(void)
{
	int	x;

	x = 10;
	while (x-- > 0)
		printf("%d ", x);
}
* ft_strcpy [solved]
Assignment name : ft_strcpy Expected files : ft_strcpy.c Allowed functions: -------------------------------------------------------------------------------- Reproduce the behavior of the function strcpy (man strcpy). Your function must be declared as follows: char *ft_strcpy(char *s1, char *s2);
solution
char    *ft_strcpy(char *s1, char *s2) {
   int i = 0;
   while (s2[i]) {
       s1[i] = s2[i];
       i++;
   }
   return s1;
}
* ft_strlen [solved]
Assignment name : ft_strlen Expected files : ft_strlen.c Allowed functions: -------------------------------------------------------------------------------- Write a function that returns the length of a string. Your function must be declared as follows: int ft_strlen(char *str);
solution
int	ft_strlen(char *str)
{
	int	len;

	len = 0;
	while (str[len])
		len++;
	return (len);
}
* ft_swap [solved]
Assignment name : ft_swap Expected files : ft_swap.c Allowed functions: -------------------------------------------------------------------------------- Write a function that swaps the contents of two integers the adresses of which are passed as parameters. Your function must be declared as follows: void ft_swap(int *a, int *b);
solution
* repeat_alpha [solved]
Assignment name : repeat_alpha Expected files : repeat_alpha.c Allowed functions: write -------------------------------------------------------------------------------- Write a program called repeat_alpha that takes a string and display it repeating each alphabetical character as many times as its alphabetical index, followed by a newline. 'a' becomes 'a', 'b' becomes 'bb', 'e' becomes 'eeeee', etc... Case remains unchanged. If the number of arguments is not 1, just display a newline. Examples: $>./repeat_alpha "abc" abbccc $>./repeat_alpha "Alex." | cat -e Alllllllllllleeeeexxxxxxxxxxxxxxxxxxxxxxxx.$ $>./repeat_alpha 'abacadaba 42!' | cat -e abbacccaddddabba 42!$ $>./repeat_alpha | cat -e $ $> $>./repeat_alpha "" | cat -e $ $>
solution
#include <unistd.h>

int main(int argc, char **argv) {
    if (argc == 2) {
        int i = 0;
        int j;
        int c;
        while (argv[1][i]) {
            c = 0;
            if (argv[1][i] >= 'a' && argv[1][i] <= 'z')
                c = argv[1][i] - 'a' + 1;
            else if (argv[1][i] >= 'A' && argv[1][i] <= 'Z')
                c = argv[1][i] - 'A' + 1;
            else
                c = 1;
            j = 0;
            while (j++ < c)
                write(1, &argv[1][i], 1);
            i++;
        }
    }
    write(1, "\n", 1);
    return 0;
}
* rev_print [solved]
Assignment name : rev_print Expected files : rev_print.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string, and displays the string in reverse followed by a newline. If the number of parameters is not 1, the program displays a newline. Examples: $> ./rev_print "zaz" | cat -e zaz$ $> ./rev_print "dub0 a POIL" | cat -e LIOP a 0bud$ $> ./rev_print | cat -e $
solution
#include <unistd.h>

int main(int ac, char **av) {
    if (ac == 2) {
        int i = 0;
        while(av[1][i])
            i++;
        i--;
        while(av[1][i]) {
            write(1, &av[1][i], 1);
            i--;
        }
    }
    write(1, "\n", 1);
    return 0;
}
* rot_13 [solved]
Assignment name : rot_13 Expected files : rot_13.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and displays it, replacing each of its letters by the letter 13 spaces ahead in alphabetical order. 'z' becomes 'm' and 'Z' becomes 'M'. Case remains unaffected. The output will be followed by a newline. If the number of arguments is not 1, the program displays a newline. Example: $>./rot_13 "abc" nop $>./rot_13 "My horse is Amazing." | cat -e Zl ubefr vf Nznmvat.$ $>./rot_13 "AkjhZ zLKIJz , 23y " | cat -e NxwuM mYXVWm , 23l $ $>./rot_13 | cat -e $ $> $>./rot_13 "" | cat -e $ $>
solution
#include <unistd.h>

int main(int ac, char **av) {
    if (ac == 2) {
       int i = 0;
       char c;
       while (av[1][i]) {
           c = av[1][i];
           if ((c >= 'a' && c <= 'm') || (c >= 'A' && c <= 'M'))
               c += 13;
           else if ((c >= 'n' && c <= 'z') || (c >= 'N' && c <= 'Z'))
               c -= 13;
           write(1, &c, 1);
           i++;
       }
    }
    write(1, "\n", 1);
    return 0;
}
* rotone [solved]
Assignment name : rotone Expected files : rotone.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and displays it, replacing each of its letters by the next one in alphabetical order. 'z' becomes 'a' and 'Z' becomes 'A'. Case remains unaffected. The output will be followed by a \n. If the number of arguments is not 1, the program displays \n. Example: $>./rotone "abc" bcd $>./rotone "Les stagiaires du staff ne sentent pas toujours tres bon." | cat -e Mft tubhjbjsft ev tubgg of tfoufou qbt upvkpvst usft cpo.$ $>./rotone "AkjhZ zLKIJz , 23y " | cat -e BlkiA aMLJKa , 23z $ $>./rotone | cat -e $ $> $>./rotone "" | cat -e $ $>
solution
#include <unistd.h>

int main(int argc, char *argv[]) {
    if (argc == 2) {
        int i = 0;
        char c;
        while (argv[1][i]) {
            c = argv[1][i];
            if ((c >= 'a' && c <= 'y') || (c >= 'A' && c <= 'Y'))
                c += 1;
            else if (c == 'z')
                c = 'a';
            else if (c == 'Z')
                c = 'A';
            write(1, &c, 1);
            i++;
        }
    }
    write(1, "\n", 1);
    return 0;
}
* search_and_replace [solved]
Assignment name : search_and_replace Expected files : search_and_replace.c Allowed functions: write, exit -------------------------------------------------------------------------------- Write a program called search_and_replace that takes 3 arguments, the first arguments is a string in which to replace a letter (2nd argument) by another one (3rd argument). If the number of arguments is not 3, just display a newline. If the second argument is not contained in the first one (the string) then the program simply rewrites the string followed by a newline. Examples: $>./search_and_replace "Papache est un sabre" "a" "o" Popoche est un sobre $>./search_and_replace "zaz" "art" "zul" | cat -e $ $>./search_and_replace "zaz" "r" "u" | cat -e zaz$ $>./search_and_replace "jacob" "a" "b" "c" "e" | cat -e $ $>./search_and_replace "ZoZ eT Dovid oiME le METol." "o" "a" | cat -e ZaZ eT David aiME le METal.$ $>./search_and_replace "wNcOre Un ExEmPle Pas Facilw a Ecrirw " "w" "e" | cat -e eNcOre Un ExEmPle Pas Facile a Ecrire $
solution
#include <unistd.h>

int main(int ac, char **av) {
    if (ac == 4 && av[2][0] && !av[2][1] && av[3][0] && !av[3][1]) {
        int i = 0;
        while (av[1][i]) {
            if (av[1][i] == av[2][0]) {
                write(1, &av[3][0], 1);
                i++;
            }
            write(1, &av[1][i], 1);
            i++;
        }
    }
    write(1, "\n", 1);
    return 0;
}
* ulstr [solved]
Assignment name : ulstr Expected files : ulstr.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and reverses the case of all its letters. Other characters remain unchanged. You must display the result followed by a '\n'. If the number of arguments is not 1, the program displays '\n'. Examples : $>./ulstr "L'eSPrit nE peUt plUs pRogResSer s'Il staGne et sI peRsIsTent VAnIte et auto-justification." | cat -e l'EspRIT Ne PEuT PLuS PrOGrESsER S'iL STAgNE ET Si PErSiStENT vaNiTE ET AUTO-JUSTIFICATION.$ $>./ulstr "S'enTOuRer dE sECreT eSt uN sIGnE De mAnQuE De coNNaiSSanCe. " | cat -e s'ENtoUrER De SecREt EsT Un SigNe dE MaNqUe dE COnnAIssANcE. $ $>./ulstr "3:21 Ba tOut moUn ki Ka di KE m'en Ka fe fot" | cat -e 3:21 bA ToUT MOuN KI kA DI ke M'EN kA FE FOT$ $>./ulstr | cat -e $
solution
#include <unistd.h>

int main(int ac, char **av)
{
    int i = 0;
    char c;
    if (ac == 2) {
        while (av[1][i]) {
            c = av[1][i];
            if (av[1][i] >= 'a' && av[1][i] <= 'z')
                c -= 32;
            else if (av[1][i] >= 'A' && av[1][i] <= 'Z')
                c += 32;
            write(1, &c, 1);
            i++;
        }
    }
    write(1, "\n", 1);
    return 0;
}
rank02/level1
* alpha_mirror [unsolved]
Assignment name : alpha_mirror Expected files : alpha_mirror.c Allowed functions: write -------------------------------------------------------------------------------- Write a program called alpha_mirror that takes a string and displays this string after replacing each alphabetical character by the opposite alphabetical character, followed by a newline. 'a' becomes 'z', 'Z' becomes 'A' 'd' becomes 'w', 'M' becomes 'N' and so on. Case is not changed. If the number of arguments is not 1, display only a newline. Examples: $>./alpha_mirror "abc" zyx $>./alpha_mirror "My horse is Amazing." | cat -e Nb slihv rh Znzarmt.$ $>./alpha_mirror | cat -e $ $>
[no solution yet]
* camel_to_snake [solved]
Assignment name : camel_to_snake Expected files : camel_to_snake.c Allowed functions: malloc, free, realloc, write -------------------------------------------------------------------------------- Write a program that takes a single string in lowerCamelCase format and converts it into a string in snake_case format. A lowerCamelCase string is a string where each word begins with a capital letter except for the first one. A snake_case string is a string where each word is in lower case, separated by an underscore "_". Examples: $>./camel_to_snake "hereIsACamelCaseWord" here_is_a_camel_case_word $>./camel_to_snake "helloWorld" | cat -e hello_world$ $>./camel_to_snake | cat -e $
solution
#include <unistd.h>

int main(int ac, char **av)
{
	int i = 0;
	char c;

	if (ac == 2)
	{
		while (av[1][i])
		{
			if (av[1][i] >= 'A' && av[1][i] <= 'Z')
			{
				write(1, "_", 1);
				c = av[1][i] + 32;
				write(1, &c, 1);
			}
			else
				write(1, &av[1][i], 1);
			i++;
		}
	}
	write(1, "\n", 1);
	return 0;
}
* do_op [solved]
Assignment name : do_op Expected files : do_op.c Allowed functions: atoi, printf, write -------------------------------------------------------------------------------- Write a program that takes three strings: - The first and the third one are representations of base-10 signed integers that fit in an int. - The second one is an arithmetic operator chosen from: + - * / % The program must display the result of the requested arithmetic operation, followed by a newline. If the number of parameters is not 3, the program just displays a newline. You can assume the string have no mistakes or extraneous characters. Negative numbers, in input or output, will have one and only one leading '-'. The result of the operation fits in an int. Examples: $> ./do_op "123" "*" 456 | cat -e 56088$ $> ./do_op "9828" "/" 234 | cat -e 42$ $> ./do_op "1" "+" "-43" | cat -e -42$ $> ./do_op | cat -e $
solution
#include <stdio.h>
#include <stdlib.h>

int main(int ac, char **av) {
    if (ac == 4) {
       int num1 = atoi(av[1]); 
       int num2 = atoi(av[3]); 
       char op = av[2][0];
       if (op == '+')
           printf("%d\n", num1 + num2);
       else if (op == '-')
           printf("%d\n", num1 - num2);
       else if (op == '*')
           printf("%d\n", num1 * num2);
       else if (op == '/')
           printf("%d\n", num1 / num2);
       else if (op == '%')
           printf("%d\n", num1 % num2);
       else
           printf("\n");
    } else {
        printf("\n");
    }
    return 0;
}
* ft_atoi [solved]
Assignment name : ft_atoi Expected files : ft_atoi.c Allowed functions: None -------------------------------------------------------------------------------- Write a function that converts the string argument str to an integer (type int) and returns it. It works much like the standard atoi(const char *str) function, see the man. Your function must be declared as follows: int ft_atoi(const char *str);
solution
int is_space(char c) {
    return (c == ' ' || (c >= 9 && c <= 13));
}

int ft_atoi(const char *str) {
    int res;
    int sign = 1;

    while (*str && is_space(*str))
        str++;
    if (*str == '-' || *str == '+') {
        if (*str == '-')
            sign = -1;
        str++;
    }
    while (*str && (*str >= '0' && *str <= '9'))
    {
        res = res * 10 + (*str - '0');
        str++;
    }
    return res * sign;
}
* ft_strcmp [solved]
Assignment name : ft_strcmp Expected files : ft_strcmp.c Allowed functions: -------------------------------------------------------------------------------- Reproduce the behavior of the function strcmp (man strcmp). Your function must be declared as follows: int ft_strcmp(char *s1, char *s2);
solution
int ft_strcmp(char *s1, char *s2) {
    while (*s1 && (*s1 == *s2)) {
        s1++;
        s2++;
    }
    return (*s1 - *s2);
}
* ft_strcspn [solved]
Assignment name : ft_strcspn Expected files : ft_strcspn.c Allowed functions: None --------------------------------------------------------------- Reproduce exactly the behavior of the function strcspn (man strcspn). The function should be prototyped as follows: size_t ft_strcspn(const char *s, const char *reject);
solution
#include <stddef.h>

size_t  ft_strcspn(const char *s, const char *reject) {
    int i = 0;
    int j;
    while (s[i]) {
        j = 0;
        while (reject[j]) {
            if (s[i] == reject[j])
                return i;
            j++;
        }
        i++;
    }
    return i;
}
* ft_strdup [solved]
Assignment name : ft_strdup Expected files : ft_strdup.c Allowed functions: malloc -------------------------------------------------------------------------------- Reproduce the behavior of the function strdup (man strdup). Your function must be declared as follows: char *ft_strdup(char *src);
solution
#include <stdlib.h>

char    *ft_strdup(char *src) {
    int len = 0;
    char *dup;
    while (src[len])
        len++;
    dup = malloc(sizeof(char) * (len + 1));
    if (!dup)
        return NULL;
    int i = 0;
    while (src[i]) {
        dup[i] = src[i];
        i++;
    }
    dup[i] = '\0';
    return dup;
}
* ft_strrev [solved]
Assignment name : ft_strrev Expected files : ft_strrev.c Allowed functions: -------------------------------------------------------------------------------- Write a function that reverses (in-place) a string. It must return its parameter. Your function must be declared as follows: char *ft_strrev(char *str);
solution
char *ft_strrev(char *str) {
    int len = 0;
    int i = 0;
    while (str[len])
        len++;
    char tmp;
    while (i < len / 2) {
        tmp = str[i];
        str[i] = str[len - 1 - i];
        str[len - 1 - i] = tmp;
        i++;
    }
    return str;
}
* inter [solved]
Assignment name : inter Expected files : inter.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes two strings and displays, without doubles, the characters that appear in both strings, in the order they appear in the first one. The display will be followed by a \n. If the number of arguments is not 2, the program displays \n. Examples: $>./inter "padinton" "paqefwtdjetyiytjneytjoeyjnejeyj" | cat -e padinto$ $>./inter ddf6vewg64f gtwthgdwthdwfteewhrtag6h4ffdhsd | cat -e df6ewg4$ $>./inter "rien" "cette phrase ne cache rien" | cat -e rien$ $>./inter | cat -e $
solution
#include <unistd.h>

int main(int ac, char **av) {
    int i;
    int j;
    int found;
    int printed[256] = {0};
    if (ac == 3) {
        i = 0;
        while (av[1][i]) {
           if(!printed[(unsigned char)av[1][i]]) 
           {
               j = 0;
               found = 0;
               while (av[2][j]) {
                   if (av[1][i] == av[2][j]) {
                       found = 1;
                       break;
                   }
                   j++;
               }
               if (found) {
                   write(1, &av[1][i], 1);
                   printed[(unsigned char)av[1][i]] = 1;
               }
           }
           i++;
        }
    } 
    write(1, "\n", 1);
    return 0;
}
* is_power_of_2 [solved]
Assignment name : is_power_of_2 Expected files : is_power_of_2.c Allowed functions: None -------------------------------------------------------------------------------- Write a function that determines if a given number is a power of 2. This function returns 1 if the given number is a power of 2, otherwise it returns 0. Your function must be declared as follows: int is_power_of_2(unsigned int n);
solution
int         is_power_of_2(unsigned int n) {
    if (n == 0)
        return 0;
    return (n & (n - 1)) == 0;
}
* last_word [solved]
Assignment name : last_word Expected files : last_word.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and displays its last word followed by a \n. A word is a section of string delimited by spaces/tabs or by the start/end of the string. If the number of parameters is not 1, or there are no words, display a newline. Example: $> ./last_word "FOR PONY" | cat -e PONY$ $> ./last_word "this ... is sparta, then again, maybe not" | cat -e not$ $> ./last_word " " | cat -e $ $> ./last_word "a" "b" | cat -e $ $> ./last_word " lorem,ipsum " | cat -e lorem,ipsum$ $>
solution
#include <unistd.h>

int is_space(char c) {
    return (c == ' ' || (c >= 9 && c <= 13));
}

int main(int ac, char **av) {
    if (ac == 2) {
        int start = 0;
        int end = 0;
        int i = 0;

        while (av[1][i])
            i++;
        i--;
        while (i >= 0 && is_space(av[1][i]))
            i--;
        end = i + 1;
        while (i >= 0 && !is_space(av[1][i]))
            i--;
        start = i + 1;
        while (start < end) {
            write(1, &av[1][start++], 1);
        }
    }
    write(1, "\n", 1);
    return 0;
}
* max [unsolved]
Assignment name : max Expected files : max.c Allowed functions: -------------------------------------------------------------------------------- Write the following function: int max(int* tab, unsigned int len); The first parameter is an array of int, the second is the number of elements in the array. The function returns the largest number found in the array. If the array is empty, the function returns 0.
[no solution yet]
* print_bits [unsolved]
Assignment name : print_bits Expected files : print_bits.c Allowed functions: write -------------------------------------------------------------------------------- Write a function that takes a byte, and prints it in binary WITHOUT A NEWLINE AT THE END. Your function must be declared as follows: void print_bits(unsigned char octet); Example, if you pass 2 to print_bits, it will print "00000010"
[no solution yet]
* reverse_bits [solved]
Assignment name : reverse_bits Expected files : reverse_bits.c Allowed functions: -------------------------------------------------------------------------------- Write a function that takes a byte, reverses it, bit by bit (like the example) and returns the result. Your function must be declared as follows: unsigned char reverse_bits(unsigned char octet); Example: 1 byte _____________ 0010 0110 || \/ 0110 0100
solution
unsigned char reverse_bits(unsigned char octet)
{
	unsigned char res = 0;
	int i = 8;

	while (i--)
	{
		res = (res << 1) | (octet & 1);
		octet >>= 1;
	}
	return res;
}
* snake_to_camel [unsolved]
Assignment name : snake_to_camel Expected files : snake_to_camel.c Allowed functions: malloc, free, realloc, write -------------------------------------------------------------------------------- Write a program that takes a single string in snake_case format and converts it into a string in lowerCamelCase format. A snake_case string is a string where each word is in lower case, separated by an underscore "_". A lowerCamelCase string is a string where each word begins with a capital letter except for the first one. Examples: $>./snake_to_camel "here_is_a_snake_case_word" hereIsASnakeCaseWord $>./snake_to_camel "hello_world" | cat -e helloWorld$ $>./snake_to_camel | cat -e $
[no solution yet]
* swap_bits [solved]
Assignment name : swap_bits Expected files : swap_bits.c Allowed functions: -------------------------------------------------------------------------------- Write a function that takes a byte, swaps its halves (like the example) and returns the result. Your function must be declared as follows: unsigned char swap_bits(unsigned char octet); Example: 1 byte _____________ 0100 | 0001 \ / / \ 0001 | 0100
solution
unsigned char swap_bits(unsigned char octet) {
    return ((octet >> 4) | (octet << 4));
}
* union [solved]
Assignment name : union Expected files : union.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes two strings and displays, without doubles, the characters that appear in either one of the strings. The display will be in the order characters appear in the command line, and will be followed by a \n. If the number of arguments is not 2, the program displays \n. Example: $>./union zpadinton "paqefwtdjetyiytjneytjoeyjnejeyj" | cat -e zpadintoqefwjy$ $>./union ddf6vewg64f gtwthgdwthdwfteewhrtag6h4ffdhsd | cat -e df6vewg4thras$ $>./union "rien" "cette phrase ne cache rien" | cat -e rienct phas$ $>./union | cat -e $ $> $>./union "rien" | cat -e $ $>
solution
#include <unistd.h>

int main(int ac, char **av) {
    if (ac == 3) {
        int i = 0;
        int seen[256] = {0};

        while(av[1][i]) {
            if (!seen[(unsigned char)av[1][i]])
            {
                seen[(unsigned char)av[1][i]] = 1;
                write(1, &av[1][i], 1);
            }
            i++;
        }
        i = 0;
        while (av[2][i]) {
            if (!seen[(unsigned char)av[2][i]])
            {
                seen[(unsigned char)av[2][i]] = 1;
                write(1, &av[2][i], 1);
            }
            i++;
        }
    }
    write(1, "\n", 1);
    return 0;
}
* wdmatch [unsolved]
Assignment name : wdmatch Expected files : wdmatch.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes two strings and checks whether it's possible to write the first string with characters from the second string, while respecting the order in which these characters appear in the second string. If it's possible, the program displays the string, followed by a \n, otherwise it simply displays a \n. If the number of arguments is not 2, the program displays a \n. Examples: $>./wdmatch "faya" "fgvvfdxcacpolhyghbreda" | cat -e faya$ $>./wdmatch "faya" "fgvvfdxcacpolhyghbred" | cat -e $ $>./wdmatch "quarante deux" "qfqfsudf arzgsayns tsregfdgs sjytdekuoixq " | cat -e quarante deux$ $>./wdmatch "error" rrerrrfiiljdfxjyuifrrvcoojh | cat -e $ $>./wdmatch | cat -e $
[no solution yet]
rank02/level2
* add_prime_sum [unsolved]
Assignment name : add_prime_sum Expected files : add_prime_sum.c Allowed functions: write, exit -------------------------------------------------------------------------------- Write a program that takes a positive integer as argument and displays the sum of all prime numbers inferior or equal to it followed by a newline. If the number of arguments is not 1, or the argument is not a positive number, just display 0 followed by a newline. Yes, the examples are right. Examples: $>./add_prime_sum 5 10 $>./add_prime_sum 7 | cat -e 17$ $>./add_prime_sum | cat -e 0$ $>
[no solution yet]
* epur_str [solved]
Assignment name : epur_str Expected files : epur_str.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string, and displays this string with exactly one space between words, with no spaces or tabs either at the beginning or the end, followed by a \n. A "word" is defined as a part of a string delimited either by spaces/tabs, or by the start/end of the string. If the number of arguments is not 1, or if there are no words to display, the program displays \n. Example: $> ./epur_str "See? It's easy to print the same thing" | cat -e See? It's easy to print the same thing$ $> ./epur_str " this time it will be more complex . " | cat -e this time it will be more complex .$ $> ./epur_str "No S*** Sherlock..." "nAw S*** ShErLaWQ..." | cat -e $ $> ./epur_str "" | cat -e $ $> $> ./epur_str "vous voyez c'est facile d'afficher la meme chose" | cat -e vous voyez c'est facile d'afficher la meme chose$ $> ./epur_str " seulement la c'est plus dur " | cat -e seulement la c'est plus dur$ $> ./epur_str "comme c'est cocasse" "vous avez entendu, Mathilde ?" | cat -e $ $> ./epur_str "" | cat -e $ $>
solution
#include <unistd.h>

int is_space(char c) {
    return (c == ' ' || (c >= 9 && c <= 13));
}

int main(int ac, char **av) {
    if (ac == 2) {
        int i = 0;
        int first = 1;
        while (av[1][i]) {
            while (av[1][i] && is_space(av[1][i]))
                i++;
            if (av[1][i]) {
                if (!first)
                    write(1, " ", 1);
                first = 0;
                while (av[1][i] && !is_space(av[1][i])) {
                    write(1, &av[1][i], 1);
                    i++;
                }
            }
        }
    }
    write(1, "\n", 1);
    return 0;
}
* expand_str [solved]
Assignment name : expand_str Expected files : expand_str.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a string and displays it with exactly three spaces between each word, with no spaces or tabs either at the beginning or the end, followed by a newline. A word is a section of string delimited either by spaces/tabs, or by the start/end of the string. If the number of parameters is not 1, or if there are no words, simply display a newline. Examples: $> ./expand_str "See? It's easy to print the same thing" | cat -e See? It's easy to print the same thing$ $> ./expand_str " this time it will be more complex " | cat -e this time it will be more complex$ $> ./expand_str "No S*** Sherlock..." "nAw S*** ShErLaWQ..." | cat -e $ $> ./expand_str "" | cat -e $ $> $> ./expand_str "vous voyez c'est facile d'afficher la meme chose" | cat -e vous voyez c'est facile d'afficher la meme chose$ $> ./expand_str " seulement la c'est plus dur " | cat -e seulement la c'est plus dur$ $> ./expand_str "comme c'est cocasse" "vous avez entendu, Mathilde ?" | cat -e $ $> ./expand_str "" | cat -e $ $>
solution
#include <unistd.h>

int is_space(char c) {
    return (c == ' ' || (c >= 9 && c <= 13));
}

int main(int ac, char **av)
{
	int i = 0;
	int first = 1;

	if (ac == 2)
	{
		while (av[1][i])
		{
			while (is_space(av[1][i]))
				i++;
			if (av[1][i])
			{
				if (!first)
					write(1, "   ", 3);
				first = 0;
				while (av[1][i] && !is_space(av[1][i]))
					write(1, &av[1][i++], 1);
			}
		}
	}
	write(1, "\n", 1);
	return 0;
}
* ft_atoi_base [solved]
Assignment name : ft_atoi_base Expected files : ft_atoi_base.c Allowed functions: None -------------------------------------------------------------------------------- Write a function that converts the string argument str (base N <= 16) to an integer (base 10) and returns it. The characters recognized in the input are: 0123456789abcdef Those are, of course, to be trimmed according to the requested base. For example, base 4 recognizes "0123" and base 16 recognizes "0123456789abcdef". Uppercase letters must also be recognized: "12fdb3" is the same as "12FDB3". Minus signs ('-') are interpreted only if they are the first character of the string. Your function must be declared as follows: int ft_atoi_base(const char *str, int str_base);
solution
int ft_atoi_base(const char *str, int str_base)
{
	int res = 0;
	int sign = 1;
	int digit;

	while (*str == ' ' || (*str >= 9 && *str <= 13))
		str++;
	if (*str == '-' || *str == '+')
	{
		if (*str == '-')
			sign = -1;
		str++;
	}
	while (*str)
	{
		if (*str >= '0' && *str <= '9')
			digit = *str - '0';
		else if (*str >= 'a' && *str <= 'f')
			digit = *str - 'a' + 10;
		else if (*str >= 'A' && *str <= 'F')
			digit = *str - 'A' + 10;
		else
			break;
		if (digit >= str_base)
			break;
		res = res * str_base + digit;
		str++;
	}
	return res * sign;
}
* ft_list_size [solved]
Assignment name : ft_list_size Expected files : ft_list_size.c Allowed functions: -------------------------------------------------------------------------------- Write a function that returns the number of elements in the linked list that's passed to it. It must be declared as follows: int ft_list_size(t_list *begin_list); You must use the following structure in your program ft_list_size.c : typedef struct s_list { struct s_list *next; void *data; } t_list;
solution
* ft_range [solved]
Assignment name : ft_range Expected files : ft_range.c Allowed functions: malloc -------------------------------------------------------------------------------- Write the following function: int *ft_range(int start, int end); It must allocate (with malloc()) an array of integers, fill it with consecutive values that begin at start and end at end (Including start and end !), then return a pointer to the first value of the array. Examples: - With (1, 3) you will return an array containing 1, 2 and 3. - With (-1, 2) you will return an array containing -1, 0, 1 and 2. - With (0, 0) you will return an array containing 0. - With (0, -3) you will return an array containing 0, -1, -2 and -3.
solution
#include <stdlib.h>

int     *ft_range(int start, int end) {
    int *arr;
    int len;
    int i;
    int step;

    if (start > end)
        len = start - end + 1;
    else
        len = end - start + 1;
    arr = malloc(sizeof(int) * len);
    if (!arr)
        return NULL;
    i = 0;
    step = 1;
    if (start > end)
        step = -1;
    while (i < len) {
       arr[i] = start;
       start += step;
       i++;
    }
    return arr;
}
* ft_rrange [solved]
Assignment name : ft_rrange Expected files : ft_rrange.c Allowed functions: malloc -------------------------------------------------------------------------------- Write the following function: int *ft_rrange(int start, int end); It must allocate (with malloc()) an array of integers, fill it with consecutive values that begin at end and end at start (Including start and end !), then return a pointer to the first value of the array. Examples: - With (1, 3) you will return an array containing 3, 2 and 1 - With (-1, 2) you will return an array containing 2, 1, 0 and -1. - With (0, 0) you will return an array containing 0. - With (0, -3) you will return an array containing -3, -2, -1 and 0.
solution
#include <stdlib.h>

int     *ft_rrange(int start, int end) {
    int *arr;
    int len;
    int i;
    int step;

    if (start > end)
        len = start - end + 1;
    else
        len = end - start + 1;
    arr = malloc(sizeof(int) * len);
    if (!arr)
        return NULL;
    i = 0;
    step = 1;
    if (start > end)
        step = -1;
    while (i < len) {
       arr[i] = end;
       end -= step;
       i++;
    }
    return arr;
}
* hidenp [unsolved]
Assignment name : hidenp Expected files : hidenp.c Allowed functions: write -------------------------------------------------------------------------------- Write a program named hidenp that takes two strings and displays 1 followed by a newline if the first string is hidden in the second one, otherwise displays 0 followed by a newline. Let s1 and s2 be strings. We say that s1 is hidden in s2 if it's possible to find each character from s1 in s2, in the same order as they appear in s1. Also, the empty string is hidden in any string. If the number of parameters is not 2, the program displays a newline. Examples : $>./hidenp "fgex.;" "tyf34gdgf;'ektufjhgdgex.;.;rtjynur6" | cat -e 1$ $>./hidenp "abc" "2altrb53c.sse" | cat -e 1$ $>./hidenp "abc" "btarc" | cat -e 0$ $>./hidenp | cat -e $ $>
[no solution yet]
* lcm [unsolved]
Assignment name : lcm Expected files : lcm.c Allowed functions: -------------------------------------------------------------------------------- Write a function who takes two unsigned int as parameters and returns the computed LCM of those parameters. LCM (Lowest Common Multiple) of two non-zero integers is the smallest postive integer divisible by the both integers. A LCM can be calculated in two ways: - You can calculate every multiples of each integers until you have a common multiple other than 0 - You can use the HCF (Highest Common Factor) of these two integers and calculate as follows: LCM(x, y) = | x * y | / HCF(x, y) | x * y | means "Absolute value of the product of x by y" If at least one integer is null, LCM is equal to 0. Your function must be prototyped as follows: unsigned int lcm(unsigned int a, unsigned int b);
[no solution yet]
* paramsum [solved]
Assignment name : paramsum Expected files : paramsum.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that displays the number of arguments passed to it, followed by a newline. If there are no arguments, just display a 0 followed by a newline. Example: $>./paramsum 1 2 3 5 7 24 6 $>./paramsum 6 12 24 | cat -e 3$ $>./paramsum | cat -e 0$ $>
solution
#include <unistd.h>

void ft_putnum(int n) {
    char c;
    
    if (n >= 10)
        ft_putnum(n / 10);
    c = n % 10 + '0';
    write(1, &c, 1);
}

int main(int ac, char **av) {
    (void)av;
    int sum = ac - 1;
    ft_putnum(sum);
    write(1, "\n", 1);
    return 0;
}
* pgcd [solved]
Assignment name : pgcd Expected files : pgcd.c Allowed functions: printf, atoi, malloc, free -------------------------------------------------------------------------------- Write a program that takes two strings representing two strictly positive integers that fit in an int. Display their highest common denominator followed by a newline (It's always a strictly positive integer). If the number of parameters is not 2, display a newline. Examples: $> ./pgcd 42 10 | cat -e 2$ $> ./pgcd 42 12 | cat -e 6$ $> ./pgcd 14 77 | cat -e 7$ $> ./pgcd 17 3 | cat -e 1$ $> ./pgcd | cat -e $
solution
#include <stdio.h>
#include <stdlib.h>

int	main(int argc, char **argv)
{
	if (argc == 3)
	{
		int nbr1 = atoi(argv[1]);
		int nbr2 = atoi(argv[2]);

		if (nbr1 > 0 && nbr2 > 0)
		{
			while (nbr1 != nbr2)
			{
				if (nbr1 > nbr2)
					nbr1 -= nbr2;
				else
					nbr2 -= nbr1;
			}
			printf("%d", nbr1);
		}
	}
	printf("\n");
	return (0);
}
* print_hex [unsolved]
Assignment name : print_hex Expected files : print_hex.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes a positive (or zero) number expressed in base 10, and displays it in base 16 (lowercase letters) followed by a newline. If the number of parameters is not 1, the program displays a newline. Examples: $> ./print_hex "10" | cat -e a$ $> ./print_hex "255" | cat -e ff$ $> ./print_hex "5156454" | cat -e 4eae66$ $> ./print_hex | cat -e $
[no solution yet]
* rstr_capitalizer [solved]
Assignment name : rstr_capitalizer Expected files : rstr_capitalizer.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes one or more strings and, for each argument, puts the last character that is a letter of each word in uppercase and the rest in lowercase, then displays the result followed by a \n. A word is a section of string delimited by spaces/tabs or the start/end of the string. If a word has a single letter, it must be capitalized. A letter is a character in the set [a-zA-Z] If there are no parameters, display \n. Examples: $> ./rstr_capitalizer | cat -e $ $> ./rstr_capitalizer "a FiRSt LiTTlE TESt" | cat -e A firsT littlE tesT$ $> ./rstr_capitalizer "SecONd teST A LITtle BiT Moar comPLEX" " But... This iS not THAT COMPLEX" " Okay, this is the last 1239809147801 but not the least t" | cat -e seconD tesT A littlE biT moaR compleX$ but... thiS iS noT thaT compleX$ okay, thiS iS thE lasT 1239809147801 buT noT thE leasT T$ $>
solution
#include <unistd.h>

int ft_isSpaceEnd(char c){
	return(c == ' ' || c == '\t' || c == '\0');
}

int main(int argc, char **argv){
	if (argc == 1)
		write(1, "\n", 1);
	int x = 0;
	while (++x < argc){ 
		int i = 0;
		while(argv[x][i]){
			if (argv[x][i] >= 'A' && argv[x][i] <= 'Z' && !ft_isSpaceEnd(argv[x][i + 1]))
				argv[x][i] = argv[x][i] + 32; 
			else if (argv[x][i] >= 'a' && argv[x][i] <= 'z' && ft_isSpaceEnd(argv[x][i + 1]))
				argv[x][i] = argv[x][i] - 32;
			write(1, &argv[x][i], 1);
			i++;
		}
		write(1, "\n", 1);
	}
}
* str_capitalizer [solved]
Assignment name : str_capitalizer Expected files : str_capitalizer.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that takes one or several strings and, for each argument, capitalizes the first character of each word (If it's a letter, obviously), puts the rest in lowercase, and displays the result on the standard output, followed by a \n. A "word" is defined as a part of a string delimited either by spaces/tabs, or by the start/end of the string. If a word only has one letter, it must be capitalized. If there are no arguments, the progam must display \n. Example: $> ./str_capitalizer | cat -e $ $> ./str_capitalizer "a FiRSt LiTTlE TESt" | cat -e A First Little Test$ $> ./str_capitalizer "__SecONd teST A LITtle BiT Moar comPLEX" " But... This iS not THAT COMPLEX" " Okay, this is the last 1239809147801 but not the least t" | cat -e __second Test A Little Bit Moar Complex$ But... This Is Not That Complex$ Okay, This Is The Last 1239809147801 But Not The Least T$ $>
solution
#include <unistd.h>

int is_space(char c) { return (c == ' ' || (c >= 9 && c <= 13)); }

int main(int ac, char **av) {
  int i;
  int j;
  char c;

  if (ac < 2)
    write(1, "\n", 1);
  i = 1;
  while (i < ac) {
    j = 0;
    while (av[i][j]) {
      c = av[i][j];
      if (c >= 'A' && c <= 'Z') {
        if (j != 0 && !is_space(av[i][j - 1]))
          c += 32;
      } else if (c >= 'a' && c <= 'z') {
        if (j == 0 || is_space(av[i][j - 1]))
          c -= 32;
      }
      write(1, &c, 1);
      j++;
    }
    write(1, "\n", 1);
    i++;
  }
  return (0);
}
* tab_mult [solved]
Assignment name : tab_mult Expected files : tab_mult.c Allowed functions: write -------------------------------------------------------------------------------- Write a program that displays a number's multiplication table. The parameter will always be a strictly positive number that fits in an int, and said number times 9 will also fit in an int. If there are no parameters, the program displays \n. Examples: $>./tab_mult 9 1 x 9 = 9 2 x 9 = 18 3 x 9 = 27 4 x 9 = 36 5 x 9 = 45 6 x 9 = 54 7 x 9 = 63 8 x 9 = 72 9 x 9 = 81 $>./tab_mult 19 1 x 19 = 19 2 x 19 = 38 3 x 19 = 57 4 x 19 = 76 5 x 19 = 95 6 x 19 = 114 7 x 19 = 133 8 x 19 = 152 9 x 19 = 171 $> $>./tab_mult | cat -e $ $>
solution
#include <unistd.h>

void ft_putnbr(int n) {
    char c;
    if (n >= 10)
        ft_putnbr(n / 10);
    c = n % 10 + '0';
    write(1, &c, 1);
}

int ft_atoi(char *str) {
    int res = 0;
    while(*str) {
        res = res * 10 + (*str - '0');
        str++;
    }
    return res;
}

int main(int ac, char **av) {
    if (ac == 2) {
       int num = ft_atoi(av[1]);
       int i = 1;
       while (i <= 9) {
            ft_putnbr(i);
            write(1, " x ", 3);
            ft_putnbr(num);
            write(1, " = ", 3);
            ft_putnbr(i * num);
            write(1, "\n", 1);
            i++;
       }
    } else {
        write(1, "\n", 1);
    }
    return 0;
}
rank02/level3
* flood_fill [unsolved]
Assignment name : flood_fill Expected files : flood_fill.c Allowed functions: - -------------------------------------------------------------------------------- Write a function that takes a char ** as a 2-dimensional array of char, a t_point as the dimensions of this array and a t_point as the starting point. Starting from the given 'begin' t_point, this function fills an entire zone by replacing characters inside with the character 'F'. A zone is an group of the same character delimitated horizontally and vertically by other characters or the array boundry. The flood_fill function won't fill diagonally. The flood_fill function will be prototyped like this: void flood_fill(char **tab, t_point size, t_point begin); The t_point structure is prototyped like this: (put it in flood_fill.c) typedef struct s_point { int x; int y; } t_point; Example: $> cat test.c #include <stdlib.h> #include <stdio.h> char** make_area(char** zone, t_point size) { char** new; new = malloc(sizeof(char*) * size.y); for (int i = 0; i < size.y; ++i) { new[i] = malloc(size.x + 1); for (int j = 0; j < size.x; ++j) new[i][j] = zone[i][j]; new[i][size.x] = '\0'; } return new; } int main(void) { t_point size = {8, 5}; char *zone[] = { "11111111", "10001001", "10010001", "10110001", "11100001", }; char** area = make_area(zone, size); for (int i = 0; i < size.y; ++i) printf("%s\n", area[i]); printf("\n"); t_point begin = {7, 4}; flood_fill(area, size, begin); for (int i = 0; i < size.y; ++i) printf("%s\n", area[i]); return (0); } $> gcc flood_fill.c test.c -o test; ./test 11111111 10001001 10010001 10110001 11100001 FFFFFFFF F000F00F F00F000F F0FF000F FFF0000F $>
[no solution yet]
* fprime [unsolved]
Assignment name : fprime Expected files : fprime.c Allowed functions: printf, atoi -------------------------------------------------------------------------------- Write a program that takes a positive int and displays its prime factors on the standard output, followed by a newline. Factors must be displayed in ascending order and separated by '*', so that the expression in the output gives the right result. If the number of parameters is not 1, simply display a newline. The input, when there is one, will be valid. Examples: $> ./fprime 225225 | cat -e 3*3*5*5*7*11*13$ $> ./fprime 8333325 | cat -e 3*3*5*5*7*11*13*37$ $> ./fprime 9539 | cat -e 9539$ $> ./fprime 804577 | cat -e 804577$ $> ./fprime 42 | cat -e 2*3*7$ $> ./fprime 1 | cat -e 1$ $> ./fprime | cat -e $ $> ./fprime 42 21 | cat -e $
[no solution yet]
* ft_itoa [solved]
Assignment name : ft_itoa Expected files : ft_itoa.c Allowed functions: malloc -------------------------------------------------------------------------------- Write a function that takes an int and converts it to a null-terminated string. The function returns the result in a char array that you must allocate. Your function must be declared as follows: char *ft_itoa(int nbr);
solution
#include <stdlib.h>
int num_len(int n) {
    int len = 0;
    if (n <= 0)
        len++;
    while (n != 0) {
        n = n / 10;
        len++;
    }
    return len;
}

char    *ft_itoa(int nbr) {
    int len = num_len(nbr);
    long n = nbr;
    char *res = malloc(sizeof(char) * (len + 1));
    if (!res)
        return NULL;
    res[len] = '\0';
    if (n < 0)
        n = -n;
    if (n == 0)
        res[0] = '0';
    while (n > 0) {
        res[--len] = n % 10 + '0';
        n = n / 10;
    }
    if (nbr < 0)
        res[0] = '-';
    return res;
}
* ft_list_foreach [solved]
Assignment name : ft_list_foreach Expected files : ft_list_foreach.c, ft_list.h Allowed functions: -------------------------------------------------------------------------------- Write a function that takes a list and a function pointer, and applies this function to each element of the list. It must be declared as follows: void ft_list_foreach(t_list *begin_list, void (*f)(void *)); The function pointed to by f will be used as follows: (*f)(list_ptr->data); You must use the following structure, and turn it in as a file called ft_list.h: typedef struct s_list { struct s_list *next; void *data; } t_list;
solution
#include "ft_list.h"

void    ft_list_foreach(t_list *begin_list, void (*f)(void *)) {
    if (!begin_list)
        return ;
    while (begin_list) 
    {
        f(begin_list->data);
        begin_list = begin_list->next;
    }
}
* ft_list_remove_if [solved]
Assignment name : ft_list_remove_if Expected files : ft_list_remove_if.c Allowed functions: free -------------------------------------------------------------------------------- Write a function called ft_list_remove_if that removes from the passed list any element the data of which is "equal" to the reference data. It will be declared as follows : void ft_list_remove_if(t_list **begin_list, void *data_ref, int (*cmp)()); cmp takes two void* and returns 0 when both parameters are equal. You have to use the ft_list.h file, which will contain: $>cat ft_list.h typedef struct s_list { struct s_list *next; void *data; } t_list;
solution
#include <stdlib.h>
#include "ft_list.h"

void	ft_list_remove_if(t_list **begin_list, void *data_ref, int (*cmp)())
{
	t_list	*temp;
	int		(*compare)(void *, void *);

	if (begin_list == NULL || *begin_list == NULL)
		return ;
	compare = (int (*)(void *, void *))cmp;
	while (*begin_list)
	{
		if (compare((*begin_list)->data, data_ref) == 0)
		{
			temp = *begin_list;
			*begin_list = temp->next;
			free(temp);
		}
		else
		{
			begin_list = &(*begin_list)->next;
		}
	}
}
* ft_split [solved]
Assignment name : ft_split Expected files : ft_split.c Allowed functions: malloc -------------------------------------------------------------------------------- Write a function that takes a string, splits it into words, and returns them as a NULL-terminated array of strings. A "word" is defined as a part of a string delimited either by spaces/tabs/new lines, or by the start/end of the string. Your function must be declared as follows: char **ft_split(char *str);
solution
#include <stdlib.h>

int is_space(char c) {
    return (c == ' ' || (c >= 9 && c <= 13));
}

int count_words(char *str) {
    int count = 0;

    while (*str) {
        while (*str && is_space(*str))
            str++;
        if (*str) {
            count++;
            while (*str && !is_space(*str))
                str++;
        }
    }
    return count;
}

char *dup_word(char *str, int len) {
    char *word;
    int i;

    word = malloc(sizeof(char) * (len + 1));
    if (!word)
        return NULL;
    i = 0;
    while (i < len) {
        word[i] = str[i];
        i++;
    }
    word[i] = '\0';
    return word;
}

char **ft_split(char *str) {
    int words_count;
    int word_len;
    char **res;
    int i;

    if (!str)
        return NULL;
    words_count = count_words(str);
    res = malloc(sizeof(char *) * (words_count + 1));
    if (!res)
        return NULL;
    i = 0;
    while (i < words_count) {
        while(*str && is_space(*str))
            str++;
        word_len = 0;
        while (str[word_len] && !is_space(str[word_len]))
            word_len++;
        res[i] = dup_word(str, word_len);
        if (!res[i])
            return NULL;
        i++;
        str += word_len;
    }
    res[i] = NULL;
    return res;
}
* rev_wstr [solved]
Assignment name : rev_wstr Expected files : rev_wstr.c Allowed functions: write, malloc, free -------------------------------------------------------------------------------- Write a program that takes a string as a parameter, and prints its words in reverse order. A "word" is a part of the string bounded by spaces and/or tabs, or the begin/end of the string. If the number of parameters is different from 1, the program will display '\n'. In the parameters that are going to be tested, there won't be any "additional" spaces (meaning that there won't be additionnal spaces at the beginning or at the end of the string, and words will always be separated by exactly one space). Examples: $> ./rev_wstr "You hate people! But I love gatherings. Isn't it ironic?" | cat -e ironic? it Isn't gatherings. love I But people! hate You$ $>./rev_wstr "abcdefghijklm" abcdefghijklm $> ./rev_wstr "Wingardium Leviosa" | cat -e Leviosa Wingardium$ $> ./rev_wstr | cat -e $ $>
solution
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
	int i;
	int j;
	int len;

	if (argc == 2)
	{
        len = 0;
        while (argv[1][len])
            len++;

        i = len - 1;
        while (i >= 0)
        {
            j = i;
            while (j >= 0 && argv[1][j] != ' ' && argv[1][j] != '\t')
                j--;
            write(1, &argv[1][j + 1], i - j);
            if (j >= 0)
                write(1, " ", 1);
            i = j - 1;
        }
	}
	write(1, "\n", 1);
	return (0);
}
* rostring [solved]
Assignment name : rostring Expected files : rostring.c Allowed functions: write, malloc, free -------------------------------------------------------------------------------- Write a program that takes a string and displays this string after rotating it one word to the left. Thus, the first word becomes the last, and others stay in the same order. A "word" is defined as a part of a string delimited either by spaces/tabs, or by the start/end of the string. Words will be separated by only one space in the output. If there's less than one argument, the program displays \n. Example: $>./rostring "abc " | cat -e abc$ $> $>./rostring "Que la lumiere soit et la lumiere fut" la lumiere soit et la lumiere fut Que $> $>./rostring " AkjhZ zLKIJz , 23y" zLKIJz , 23y AkjhZ $> $>./rostring "first" "2" "11000000" first $> $>./rostring | cat -e $ $>
solution
#include <unistd.h>

int is_space(char c)
{
	return (c == ' ' || (c >= 9 && c <= 13));
}

int main(int ac, char **av)
{
	int i;
	int start;
	int end;
	int flag;
	char *str;

	if (ac >= 2)
	{
		i = 0;
		start = 0;
		end = 0;
		flag = 0;
		str = av[1];
		while (str[i] && is_space(str[i]))
			i++;
		start = i;
		while (str[i] && !is_space(str[i]))
			i++;
		end = i;
		while (str[i] && is_space(str[i]))
			i++;
		while (str[i])
		{
			if (flag == 1)
				write(1, " ", 1);
			flag = 1;
			while (str[i] && !is_space(str[i]))
			{
				write(1, &str[i], 1);
				i++;
			}
			while (str[i] && is_space(str[i]))
				i++;
		}
		if (start < end)
		{
			if (flag == 1)
				write(1, " ", 1);
			while (start < end)
			{
				write(1, &str[start], 1);
				start++;
			}
		}
	}
	write(1, "\n", 1);
	return (0);
}
* sort_int_tab [solved]
Assignment name : sort_int_tab Expected files : sort_int_tab.c Allowed functions: -------------------------------------------------------------------------------- Write the following function: void sort_int_tab(int *tab, unsigned int size); It must sort (in-place) the 'tab' int array, that contains exactly 'size' members, in ascending order. Doubles must be preserved. Input is always coherent.
solution
void sort_int_tab(int *tab, unsigned int size)
{
	unsigned int i, j;
	int tmp;

	for (i = 0; i < size; i++)
	{
		for (j = i + 1; j < size; j++)
		{
			if (tab[i] > tab[j])
			{
				tmp = tab[i];
				tab[i] = tab[j];
				tab[j] = tmp;
			}
		}
	}
}
* sort_list [solved]
Assignment name : sort_list Expected files : sort_list.c Allowed functions: -------------------------------------------------------------------------------- Write the following functions: t_list *sort_list(t_list* lst, int (*cmp)(int, int)); This function must sort the list given as a parameter, using the function pointer cmp to select the order to apply, and returns a pointer to the first element of the sorted list. Duplications must remain. Inputs will always be consistent. You must use the type t_list described in the file list.h that is provided to you. You must include that file (#include "list.h"), but you must not turn it in. We will use our own to compile your assignment. Functions passed as cmp will always return a value different from 0 if a and b are in the right order, 0 otherwise. For example, the following function used as cmp will sort the list in ascending order: int ascending(int a, int b) { return (a <= b); } LIST.H FILE: typedef struct s_list t_list; struct s_list { int data; t_list *next; }; YOU MUST TEST WITH YOUR LIST.H FILE JUST FOR THIS SHELL.
solution
#include "list.h"

t_list *sort_list(t_list *lst, int (*cmp)(int, int))
{
	t_list *a;
	t_list *b;
	int tmp;

	a = lst;
	while (a)
	{
		b = a->next;
		while (b)
		{
			if (!cmp(a->data, b->data))
			{
				tmp = a->data;
				a->data = b->data;
				b->data = tmp;
			}
			b = b->next;
		}
		a = a->next;
	}
	return lst;
}
rank03/level1
* broken_gnl [solved]
Assignment name : broken_GNL Expected files : get_next_line.c get_next_line.h Allowed functions : read, free, malloc -------------------------------------------------------------------------------- Repair the function ‘get_next_line’ in the file get_next_line.c, whose prototype should be: char *get_next_line(int fd); You may need to repair other functions as well. Description of the ‘get_next_line’ function: Your function must return a line that has been read from the file descriptor passed as a parameter. A ‘line that has been read’ is defined as a succession of 0 to n characters ending with ‘\n’ (ASCII code 0x0a) or with End of File (EOF). The line should be returned including the ‘\n’ if there is one at the end of the line that has been read. When you reach the EOF, you must store the current buffer in a char * and return it. If the buffer is empty, you must return NULL. In case of an error, return NULL. If not returning NULL, the pointer should be freeable. Your program will be compiled with the flag -D BUFFER_SIZE=xx, which must be used as the buffer size for the read calls in your functions. Your function must be free of memory leaks. When you reach the EOF, your function should not keep any memory allocated with malloc except for the line that has been returned. Calling your function get_next_line in a loop will allow you to read the text available on a file descriptor one line at a time until the end of the text, regardless of the size of the text or any of its lines. Make sure that your function behaves correctly when reading from a file, from the standard output, from a redirection etc. No call to another function will be done on the file descriptor between two calls of get_next_line. Finally, we consider that get_next_line has undefined behavior when reading from a binary file. --------------------------------------------------------------------------------
solution
/*
 * EXERCISE: BROKEN_GNL (Get Next Line)
 * 
 * DESCRIPTION:
 * Implement get_next_line that reads line by line from a file descriptor.
 * This version may contain special cases or intentional "bugs".
*/

#include "get_next_line.h"

char *ft_strchr(char *s, int c)
{
  int i = 0;
  while(s[i] != c)
    i++;
  if (s[i] == c)
    return s + i;
  else
    return NULL;
}

void *ft_memcpy(void *dest, const void *src, size_t n)
{
  while(--n > 0)
    ((char *)dest)[n - 1] = ((char *)src)[n - 1];
  return dest;
}

size_t ft_strlen(char *s)
{
  size_t res = 0;
  while (*s)
  {
    s++;
    res++;
  }
  return res;
}

int str_append_mem(char **s1, char *s2, size_t size2)
{
  size_t size1 = ft_strlen(*s1);
  char *tmp = malloc(size2 + size1 + 1);
  if (!tmp)
    return 0;
  ft_memcpy(tmp, *s1, size1);
  ft_memcpy(tmp + size1, s2, size2);
  tmp[size1 + size2] = '\0';
  free(*s1);
  *s1 = tmp;
  return 1; 
}

int str_append_str(char **s1, char *s2)
{
  return str_append_mem(s1, s2, ft_strlen(s2));
}

void *ft_memmove(void *dest, const void *src, size_t n)
{
  if (dest > src)
    return ft_memmove(dest, src, n);
  else if (dest == src)
    return dest;
  size_t i = ft_strlen((char *)src) - 1;
  while (i >= 0)
  {
    ((char *)dest)[i] = ((char *)src)[i];
    i--;
  }
  return dest;
}

char *get_next_line(int fd)
{
  static char b[BUFFER_SIZE + 1] = "";
  char *ret = NULL;
  char *tmp = ft_strchr(b, '\n');
  while(!tmp)
  {
    if (!str_append_str(&ret, b))
      return (NULL);
    int read_ret = read(fd, b, BUFFER_SIZE);
    if (read_ret == -1)
      return (NULL);
    b[read_ret] = 0;
  }
  if (!str_append_mem(&ret, b, tmp - b + 1))
  {
    free(ret);
    return NULL;
  }
  return ret;
}
* filter [unsolved]
Assignment name: filter Expected files: filter.c Allowed functions: read, write, strlen, memmem, memmove, malloc, calloc, realloc, free, printf, fprintf, stdout, stderr, perror -------------------------------------------------------------------------------- Write a program that will take one and only one argument. Your program will then read from stdin and write all the content read in stdout except that every occurrence of s must be replaced by '*' (as many as the length of s). Your program will be tested with random buffer sizes, using a custom read function. Therefore the buffer being set in your program will be filled with a different number of chars each new call. For example: ./filter bonjour will behave in the same way as: sed 's/bonjour/*******/g' ./filter abc will behave in the same way as: sed's/abc/***/g' More generally your program must be the equivalent of the shell script filter.sh present in this directory (you can compare your program with it). In case of error during a read or a malloc, you must write "Error: " followed by the error message in stderr and return 1. If the program is called without arguments or with an empty argument or with multiple arguments, it must return 1. For example this should work: $> echo 'abcdefaaaabcdeabcabcdabc' | ./filter abc | cat -e ***defaaa***de******d***$ $> echo 'ababcabababc' | ./filter ababc | cat -e *****ab*****$ $> NOTES: memmem includes: #define _GNU_SOURCE #include <string.h> perror includes: #include <errno.h> read includes: #include <fcntl.h>
[no solution yet]
* scanf [solved]
Assignment name : ft_scanf Expected files : ft_scanf.c Allowed functions: fgetc, ungetc, ferror, feof, isspace, isdigit, stdin, va_start, va_arg, va_copy, va_end -------------------------------------------------------------------------------- Write a function named `ft_scanf` that will mimic the real scanf with the following constraints: - It will manage only the following conversions: s, d, and c - You don't have to handle the options *, m and ' - You don't have to handle the maximum field width - You don't have to handle the types modifier characters (h, hh, l, etc.) - You don't have to handle the conversions beginning with %n$ Your function must be declared as follows: int ft_scanf(const char *, ... ); You will find in this directory a file containing a part of the code you will need, you just have to complete it. To test your program compare your results with the real scanf. Hint : You may need to read the man of scanf. #include <stdarg.h> #include <stdio.h> #include <ctype.h> int match_space(FILE *f) { // You may insert code here return (0); } int match_char(FILE *f, char c) { // You may insert code here return (0); } int scan_char(FILE *f, va_list ap) { // You may insert code here return (0); } int scan_int(FILE *f, va_list ap) { // You may insert code here return (0); } int scan_string(FILE *f, va_list ap) { // You may insert code here return (0); } int match_conv(FILE *f, const char **format, va_list ap) { switch (**format) { case 'c': return scan_char(f, ap); case 'd': match_space(f); return scan_int(f, ap); case 's': match_space(f); return scan_string(f, ap); case EOF: return -1; default: return -1; } } int ft_vfscanf(FILE *f, const char *format, va_list ap) { int nconv = 0; int c = fgetc(f); if (c == EOF) return EOF; ungetc(c, f); while (*format) { if (*format == '%') { format++; if (match_conv(f, &format, ap) != 1) break; else nconv++; } else if (isspace(*format)) { if (match_space(f) == -1) break; } else if (match_char(f, *format) != 1) break; format++; } if (ferror(f)) return EOF; return nconv; } int ft_scanf(const char *format, ...) { // ... int ret = ft_vfscanf(stdin, format, ap); // ... return ret; }
solution
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>

int match_space(FILE *f) {
  int c;

  while ((c = fgetc(f)) != EOF) {
    if (!isspace(c)) {
      ungetc(c, f);
      break;
    }
  }
  if (ferror(f))
    return (-1);
  return (1);
}

int match_char(FILE *f, char c) {
  int ch = fgetc(f);

  if (ch == EOF)
    return (-1);
  if (ch != (unsigned char)c) {
    ungetc(ch, f);
    return (0);
  }
  return (1);
}

int scan_char(FILE *f, va_list *ap) {
  int ch = fgetc(f);
  char *out;

  if (ch == EOF)
    return (0);
  out = va_arg(*ap, char *);
  *out = (char)ch;
  return (1);
}

int scan_int(FILE *f, va_list *ap) {
  int ch = fgetc(f);
  int sign = 1;
  int sign_read = 0;
  int sign_char = 0;
  int value = 0;
  int *out;

  if (ch == EOF)
    return (0);
  if (ch == '+' || ch == '-') {
    sign_read = 1;
    sign_char = ch;
    sign = (ch == '-') ? -1 : 1;
    ch = fgetc(f);
  }
  if (ch == EOF) {
    if (sign_read)
      ungetc(sign_char, f);
    return (0);
  }
  if (!isdigit(ch)) {
    ungetc(ch, f);
    if (sign_read)
      ungetc(sign_char, f);
    return (0);
  }
  while (ch != EOF && isdigit(ch)) {
    value = value * 10 + (ch - '0');
    ch = fgetc(f);
  }
  if (ch != EOF)
    ungetc(ch, f);
  out = va_arg(*ap, int *);
  *out = value * sign;
  return (1);
}

int scan_string(FILE *f, va_list *ap) {
  int ch = fgetc(f);
  char *out;
  int i = 0;

  if (ch == EOF)
    return (0);
  if (isspace(ch)) {
    ungetc(ch, f);
    return (0);
  }
  out = va_arg(*ap, char *);
  while (ch != EOF && !isspace(ch)) {
    out[i++] = (char)ch;
    ch = fgetc(f);
  }
  if (ch != EOF)
    ungetc(ch, f);
  out[i] = '\0';
  return (1);
}

int match_conv(FILE *f, const char **format, va_list *ap) {
  switch (**format) {
  case 'c':
    return scan_char(f, ap);
  case 'd':
    match_space(f);
    return scan_int(f, ap);
  case 's':
    match_space(f);
    return scan_string(f, ap);
  case EOF:
    return -1;
  default:
    return -1;
  }
}

int ft_vfscanf(FILE *f, const char *format, va_list ap) {
  int nconv = 0;

  int c = fgetc(f);
  if (c == EOF)
    return EOF;
  ungetc(c, f);

  while (*format) {
    if (*format == '%') {
      format++;
      if (match_conv(f, &format, &ap) != 1)
        break;
      else
        nconv++;
    } else if (isspace(*format)) {
      if (match_space(f) == -1)
        break;
    } else if (match_char(f, *format) != 1)
      break;
    format++;
  }

  if (ferror(f))
    return EOF;
  return nconv;
}

int ft_scanf(const char *format, ...) {
  va_list ap;
  int ret;

  va_start(ap, format);
  ret = ft_vfscanf(stdin, format, ap);
  va_end(ap);
  return (ret);
}
rank03/level2
* n_queens [unsolved]
Assignement name : n_queens Expected files : *.c *.h Allowed functions : atoi, fprintf, write, calloc, malloc, free, realloc, stdout, stderr ------------------------------------------------------------------------- Write a program that will print all the solutions to the n queens problem for a n given as argument. We will not test with negative values. The order of the solutions is not important. You will display the solutions under the following format : <p1> <p2> <p3> ... \n where pn are the line index of the queen in each colum starting from 0. For example this should work : $> ./n_queens 2 | cat -e $> ./n_queens 4 | cat -e 1 3 0 2$ 2 0 3 1$ $> ./n_queens 7 | cat -e 0 2 4 6 1 3 5$ 0 3 6 2 5 1 4$ etc...
[no solution yet]
* permutations [unsolved]
Assignment name : permutations Expected files : *.c *.h Allowed functions: puts, malloc, calloc, realloc, free, write --------------------------------------------------------------- Write a program that will print all the permutations of a string given as argument. The solutions must be given in alphabetical order. We will not try your program with strings containing duplicates (eg: 'abccd'). For example this should work: $> ./permutations a | cat -e a$ $> ./permutations ab | cat -e ab$ ba$ $> ./permutations abc | cat -e abc$ acb$ bac$ bca$ cab$ cba$
[no solution yet]
* powerset [unsolved]
Assignment name : powerset Expected files : *.c *.h Allowed functions: atoi, printf, fprintf, malloc, calloc, realloc, free, stdout, write -------------------------------------------------------------------------------- Write a program that will take as argument an integer n followed by a set s of distinct integers. Your program should display all the subsets of s whose sum of elements is n. The order of the lines is not important, but the order of the elements in a subset is: it must match the order in the initial set s. This way, you should not have any duplicates (eg: '1 2' and '2 1'). For example, using the command ./powerset 5 1 2 3 4 5 this output is valid: 1 4 2 3 5 this one is also valid: 2 3 5 1 4 but not this one: 4 1 3 2 5 In case of a malloc error your program will exit with the code 1. We will not test with invalid sets (for example '1 1 2'). Hint: the empty subset is a valid subset of any set. It will be displayed as an empty line. For example this should work: $> ./powerset 3 1 0 2 4 5 3 | cat -e 3$ 0 3$ 1 2$ 1 0 2$ $> ./powerset 12 5 2 1 8 4 3 7 11 | cat -e 8 4$ 1 11$ 1 4 7$ 1 8 3$ 2 3 7$ 5 7$ 5 4 3$ 5 2 1 4$ $> ./powerset 0 1 -1 | cat -e $ 1 -1$ $> ./powerset 7 3 8 2 | cat -e // Other tests: $> ./powerset 100 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | cat -e ... $> ./powerset -1 1 2 3 4 5 -10 | cat -e ... $> ./powerset 0 -1 1 2 3 -2 | cat -e ... $> ./powerset 13 65 23 3 4 6 7 1 2 | cat -e ... $> ./powerset 10 0 1 2 3 4 5 6 7 8 9 | cat -e ...
[no solution yet]
* rip [unsolved]
Assignment name : rip Expected files : *.c *.h Allowed functions: puts, write -------------------------------------------------------------------------------- Write a program that will take as argument a string containing only parenthesis. if the parenthesis are unbalanced (for example "())") your program shall remove the minimum number of parentheses for the expression to be balanced. By removing we mean replacing by spaces. You will then print all the solutions (can be more than one). The order of the solutions is not important. For example this should work: $> ./rip '(()' | cat -e ()$ ( )$ $> ./rip '((()()())())' | cat -e ((()()())())$ $> ./rip '()())()'| cat -e ()() ()$ ()( )()$ ( ())()$ $> ./rip '(()(()(' | cat -e (() ) $ ( )( ) $ ( ) () $ ()( ) $
[no solution yet]
* tsp [unsolved]
Assignment name: tsp Expected files: *.c *.h Allowed functions: write, sqrtf, getline, fseek, fscanf, ferror, feof, fabsf, memcpy, fprintf, fclose, malloc, calloc, realloc, free, fopen, errno, stderr, stdin, stdout ------------------------------------------------------- The first publication referring to this problem as the "traveling salesman problem" is found in the 1949 RAND Corporation report by Julia Robinson, "On the Hamiltonian game (a traveling salesman problem)." Here is how she defines the problem: "The purpose of this note is to give a method for solving a problem related to the traveling salesman problem. It seems worthwhile to give a description of the original problem. One formulation is to find the shortest route for a salesman starting from Washington, visiting all the state capitals and then returning to Washington. More generally, to find the shortest CLOSED CURVE containing n given points in the plane." for example with the following set of cities: 0, 0 1, 0 2, 0 0, 1 1, 1 2, 1 1, 2 2, 2 which can be presented as follows: + + + + + + + + the shortest path is: _____ |__ | |__| so you should print the length of this path that is: 8.00 Write a program that will read a set of city coordinates in the form '%f, %f\n' from the standard input and will print the length of the shortest possible path containing all these cities under the form '%.2f'. Your program will not be tested with more than 11 cities. You will find in this directory a file tsp.c containing all the boring parts of this exercise and example files to help you test your program. hint: in order to use sqrtf, add -lm at the end of your compilation command. For example this should work: $> cat square.txt 1, 1 0, 1 1, 0 0, 0 $> ./tsp < square.txt | cat -e 4.00$ Hint : in order to use sqrtf , add -lm at the end of your compilation command
[no solution yet]
rank04/level1
* ft_popen [unsolved]
Assignment name : ft_popen Expected files : ft_popen.c Allowed functions: pipe, fork, dup2, execvp, close, exit -------------------------------------------------------------------------------------- Write the following function: int ft_popen(const char *file, char *const argv[], char type); The function must launch the executable file with the arguments argv (using execvp). If type is 'r' the function must return a file descriptor connected to the output of the command. If type is 'w' the function must return a file descriptor connected to the input of the command. In case of error or invalid parameter the function must return -1. For example, the function could be used like that: int main() { int fd; char *line; fd = ft_popen("ls", (char *const []){"ls", NULL}, 'r'); while ((line = get_next_line(fd))) ft_putstr(line); return (0); } int main() { int fd = ft_popen("ls", (char *const []){"ls", NULL}, 'r'); dup2(fd, 0); fd = ft_popen("grep", (char *const []){"grep", "c", NULL}, 'r'); char *line; while ((line = get_next_line(fd))) printf("%s", line); } Hints: Do not leak file descriptors! This exercise is inspired by the libc's popen().
[no solution yet]
* picoshell [unsolved]
Assignment name: picoshell Expected files: picoshell.c Allowed functions: close, fork, wait, exit, execvp, dup2, pipe ___________________________________________________________________ Write the following function: int picoshell(char **cmds[]); The goal of this function is to execute a pipeline. It must execute each commands of cmds and connect the output of one to the input of the next command (just like a shell). e Cmds contains a null-terminated list of valid commands. Each rows of cmds are an argv array directly usable for a call to execvp. The first arguments of each command is the command name or path and can be passed directly as the first argument of execvp. If any error occur, The function must return 1 (you must of course close all the open fds before). otherwise the function must wait all child processes and return 0. You will find in this directory a file main.c which contain something to help you test your function. Examples: ./picoshell /bin/ls "|" /usr/bin/grep picoshell picoshell ./picoshell echo 'squalala' "|" cat "|" sed 's/a/b/g' squblblb ___________________________________________________________________ Old summary by a student: You are given a main function. It converts received arguments into cmds array of strings. When there is a pipe the commands after the pipe are in the next array of strings. You have to create a pipeline using the cmds you receive from the main, and execute them. If there is any error the function should return 1. Close all FFS before returning. If the cmds executed successfully wait all child processes and return 0.
[no solution yet]
* sandbox [unsolved]
Assignment name : sandbox Expected files : sandbox.c Allowed functions: fork, waitpid, exit, alarm, sigaction, kill, printf, strsignal, errno, sigaddset, sigemptyset, sigfillset, sigdelset, sigismember -------------------------------------------------------------------------------------- Write the following function: #include <stdbool.h> int sandbox(void (*f)(void), unsigned int timeout, bool verbose); This function must test if the function f is a nice function or a bad function, you will return 1 if f is nice, 0 if f is bad or -1 in case of an error in your function. A function is considered bad if it is terminated or stopped by a signal (segfault, abort...), if it exit with any other exit code than 0 or if it times out. If verbose is true, you must write the appropriate message among the following: "Nice function!\n" "Bad function: exited with code <exit_code>\n" "Bad function: <signal description>\n" "Bad function: timed out after <timeout> seconds\n" You must not leak processes (even in zombie state, this will be checked using wait). We will test your code with very bad functions.
[no solution yet]
rank04/level2
* argo [unsolved]
Assignment name: argo Expected files: argo.c Allowed functions: getc, ungetc, printf, malloc, calloc, realloc, free, isdigit, fscanf, write ----------------- Write a function argo that will parse a json file in the structure declared in argo.h: int argo(json *dst, FILE *stream); dst - is the pointer to the AST that you will create stream - is the file to parse (man FILE) Your function will return 1 for success and -1 for failure. If an unexpected token is found you will print the following message in stdout: "Unexpected token '%c'\n" or if the token is EOF: "Unexpected end of input\n" Only handle numbers, strings and maps. Numbers will only be basic ints like in scanf("%d") Handle escaping in the strings only for backslashes and quotation marks (no \n \u ...) Don't handle spaces -> consider them as invalid tokens. In case of doubt how to parse json, read rfc8259. But you won't need it as the format is simple. Tested with the main, the output should be exactly the same as the input (except for errors). There are some functions in argo.c that might help you. Examples that should work: $> echo -n '1' | ./argo /dev/stdin | cat -e 1$ $> echo -n '"bonjour"' | ./argo /dev/stdin | cat -e "bonjour"$ $> echo -n '"escape! \" "' | ./argo /dev/stdin | cat -e "escape! \" "$ $> echo -n '{"tomatoes":42,"potatoes":234}' | ./argo /dev/stdin | cat -e {"tomatoes":42,"potatoes":234}$ $> echo -n '{"recursion":{"recursion":{"recursion":{"recursion":"recursion"}}}}' | ./argo /dev/stdin | cat -e {"recursion":{"recursion":{"recursion":{"recursion":"recursion"}}}}$ $> echo -n '"unfinished string' | ./argo /dev/stdin | cat -e unexpected end of input$ $> echo -n '"unfinished string 2\"' | ./argo /dev/stdin | cat -e unexpected end of input$ $> echo -n '{"no value?":}' | ./argo /dev/stdin | cat -e unexpected token '}'$
[no solution yet]
* vbc [unsolved]
Assignment name : vbc Expected files : *.c *.h Allowed functions: malloc, calloc, realloc, free, printf, isdigit, write -------------------------------------------------------------------------------- Write a program that will print the result of a math expression given as argument. You must handle the operations + * and the parenthesis. You don't have to handle whitespaces in the expression. All the values in the expression will be between 0 and 9 included. In case of unexpected symbol or inappropriate parenthesis, you will print "Unexpected token '%c'\n" and exit with the code 1 (if the symbol is the end of input you will print: "Unexpected end of input\n"). In case of a syscall failure you will just exit with the code 1. You will find in this directory the beginning of the code you need to write. For example this should work: $> ./vbc '1' | cat -e 1$ $> ./vbc '2+3' | cat -e 5$ $> ./vbc '3*4+5' | cat -e 17$ $> ./vbc '3+4*5' | cat -e 23$ $> ./vbc '(3+4)*5' | cat -e 35$ $> ./vbc '(((((2+2)*2+2)*2+2)*2+2)*2+2)*2' | cat -e 188$ $> ./vbc '1+' | cat -e Unexpected end of input$ $> ./vbc '1+2)' | cat -e Unexpected token ')'$ $> ./vbc '1+2+3+4+5' | cat -e 15$ $> ./vbc '2*4+9+3+2*1+5+1+6+6*1*1+8*0+0+5+0*4*9*5*8+9*7+5*1+3+1+4*5*7*3+0*3+4*8+8+8+4*0*5*3+5+4+5*7+9+6*6+7+9*2*6*9+2+1*3*7*1*1*5+1+2+7+4+3*4*2+0+4*4*2*2+6+7*5+9+0+8*4+6*7+5+4*4+2+5*5+1+6+3*5*9*9+7*4*3+7+4*9+3+0+1*8+1+2*9*4*5*1+0*1*9+5*3*5+9*6+5*4+5+5*8*6*4*9*2+0+0+1*5*3+6*8*0+0+2*3+7*5*6+8+6*6+9+3+7+0*0+5+2*8+2*7*2+3+9*1*4*8*7*9+2*0+1*6*4*2+8*8*3*1+8+2*4+8*3+8*3+9*5+2*3+9*5*6*4+3*6*6+7+4*8+0+2+9*8*0*6*8*1*2*7+0*5+6*5+0*2+7+2+3+8*7+6+1*3+5+4*5*4*6*1+4*7+9*0+4+9*8+7+5+6+2+6+1+1+1*6*0*9+7+6*2+4*4+1*6*2*9+3+0+0*1*8+4+6*2+6+2*7+7+0*9+6+2*1+6*5*2*3*5*2*6*4+2*9*2*4*5*2*2*3+8+8*3*2*3+0*5+9*6+8+3*1+6*9+8+9*2*0+2' | cat -e 94305$ $> ./vbc '(1)' | cat -e 1$ $> ./vbc '(((((((3)))))))' | cat -e 3$ $> ./vbc '(1+2)*3' | cat -e 9$ $> ./vbc '((6*6+7+5+8)*(1+0+4*8+7)+2)+4*(1+2)' | cat -e 2254$ $> ./vbc '((1+3)*12+(3*(2+6))' | cat -e Unexpected token '2'$
[no solution yet]
rank05/level1
* bigint [unsolved]
[EN] Assignment name : bigint Expected files : bigint.hpp, bigint.cpp -------------------------------------------------------------------------------- In computer science a bignum is an object representing an arbitrary precision number, this is useful when you want to store a number bigger than SIZE_MAX without any loss of precision. This is often achieved by storing an array or a string containing the different "parts" of the number. Create a class called bigint that will store an arbitrary precision unsigned integer. Your class must support addition, comparison and "digitshift" (like bitshift but instead of shifting the bits you will shift the digits in base 10, e.g.: (42 << 3 == 42000) and (1337 >> 2 == 13)). Your bigint must be printable with the << operator (in base 10) and the output should not contain any leading zeros. You will find a main in this directory that must work with your class [TR] Bilgisayar bilimlerinde bignum, keyfi bir hassasiyetteki sayıyı temsil eden bir nesnedir. Bu, herhangi bir hassasiyet kaybı olmadan SIZE_MAX değerinden büyük bir sayıyı depolamak istediğinizde kullanışlıdır. Bu genellikle sayının farklı "kısımlarını" içeren bir dizi veya dize depolayarak elde edilir. keyfi bir hassasiyetteki işaretsiz tamsayıyı depolayacak bigint adlı bir sınıf oluşturun. Sınıfınız toplama, karşılaştırma ve "rakam kaydırma" işlemlerini desteklemelidir (bit kaydırma gibi, ancak bitleri kaydırmak yerine 10 tabanındaki rakamları kaydırırsınız örneğin: (42 << 3 == 42000) ve (1337 >> 2 == 13)). bigint değeriniz << operatörüyle (10 tabanında) yazdırılabilir olmalı ve çıktıda başta sıfır bulunmamalıdır. Bu dizinde, sınıfınızla uyumlu olması gereken bir main bulacaksınız. [SUBJECT MAIN] #include "bigint.hpp" #include <iostream> int main() { const bigint a(42); bigint b(21), c, d(1337), e(d); std::cout << "a = " << a << std::endl; std::cout << "b = " << b << std::endl; std::cout << "c = " << c << std::endl; std::cout << "d = " << d << std::endl; std::cout << "e = " << e << std::endl; std::cout << "a + b = " << a + b << std::endl; std::cout << "(c += a) = " << (c += a) << std::endl; std::cout << "b = " << b << std::endl; std::cout << "++b = " << ++b << std::endl; std::cout << "b++ = " << b++ << std::endl; std::cout << "(b << 10) + 42 = " << ((b << 10) + 42) << std::endl; std::cout << "(d <<= 4) = " << (d <<= 4) << std::endl; std::cout << "(d >>= 2) = " << (d >>= (const bigint)2) << std::endl; std::cout << "a =" << a << std::endl; std::cout << "d =" << d << std::endl; std::cout << "(d < a) = " << (d < a) << std::endl; std::cout << "(d <= a) = " << (d <= a) << std::endl; std::cout << "(d > a) = " << (d > a) << std::endl; std::cout << "(d >= a) = " << (d >= a) << std::endl; std::cout << "(d == a) = " << (d == a) << std::endl; std::cout << "(d != a) = " << (d != a) << std::endl; }
[no solution yet]
* polyset [unsolved]
Assigment name: Polyset Expected File: searchable_array_bag.cpp, searchable_array_bag.hpp, searchable_tree_bg.cpp, searchable_tree_bag.hpp, set.cpp, set.hpp You will find in this directory some classes: - bag: an abstract class representing a bag - searchable_bag: an abstract class representing a bag with the ability to search in it. - array_bag: an implementation of a bag with an array an underlying data structure. - tree_bag: an implementation of a bag with a binary search tree as underlying data structure. If you don't know what is a set or a bag (shame!) you can read the attached file shame.en.txt First Part: Since a bag without a searching function isn't very useful, implement two classes searchable_array_bag and searchable_tree_bag, that will inherit from array_bag and tree_bag and implement the searchable bag abstract class. Second Part: Implement the class set that will wrap a searchable_bag and turn it into a set. You will find in this dir a main that must compile with your code. All classes should be under orthodox canonical form. Don't forget the const.
[no solution yet]
* vect2 [unsolved]
Assignement name: vect2 Expected files: vect2.cpp, vect2.hpp ------------------------------------------------------------------------------------------- Create a class vect2 representing a mathematical vector of dimension 2 containing ints. It must support addition, substraction and multiplication by a scalar (such as the expression (vect2(2,2) * 2 == vect2(4,4)) is true). the operator [] can be used to access the component of your vector (with 0 and 1), no bound checking is required. Your function must be printable with the << operator such as: std::cout << v << std::endl; produce the same output as: std::cout << "{" << v[0] << ", " << v[1] << "}" << std::endl; You will find a main in this directory that must work with your class. #include "vect2.hpp" #include <iostream> int main() { vect2 v1; // 0, 0 vect2 v2(1, 2); // 1, 2 const vect2 v3(v2); // 1, 2 vect2 v4 = v2; // 1, 2 std::cout << "v1: " << v1 << std::endl; std::cout << "v1: " << "{" << v1[0] << ", " << v1[1] << "}" << std::endl; std::cout << "v2: " << v2 << std::endl; std::cout << "v3: " << v3 << std::endl; std::cout << "v4: " << v4 << std::endl; std::cout << v4++ << std::endl; // 2, 3 std::cout << ++v4 << std::endl; // 3, 4 std::cout << v4-- << std::endl; // 2, 3 std::cout << --v4 << std::endl; // 1, 2 v2 += v3; // 2, 4 v1 -= v2; // -2, -4 v2 = v3 + v3 *2; // 3, 6 v2 = 3 * v2; // 9, 18 v2 += v2 += v3; // 20, 40 v1 *= 42; // -84, -168 v1 = v1 - v1 +v1; std::cout << "v1: " << v1 << std::endl; std::cout << "v2: " << v2 << std::endl; std::cout << "-v2: " << -v2 << std::endl; std::cout << "v1[1]: " << v1[1] << std::endl; v1[1] = 12; std::cout << "v1[1]: " << v1[1] << std::endl; std::cout << "v3[1]: " << v3[1] << std::endl; std::cout << "v1 == v3: " << (v1 == v3) << std::endl; std::cout << "v1 == v1: " << (v1 == v1) << std::endl; std::cout << "v1 != v3: " << (v1 != v3) << std::endl; std::cout << "v1 != v1: " << (v1 != v1) << std::endl; }
[no solution yet]
rank05/level2
* bsq [unsolved]
Assignment name : bsq Expected files : *.c *.h Allowed functions and globals: malloc, calloc, realloc, free, fopen, fclose, getline, fscanf, fputs, fprintf, stderr, stdout, stdin, errno -------------------------------------------------------------------------------- The aim of this program is to find the biggest square on a map, avoiding obstacles. A file containing the map will be provided. It'll have to be passed as an argument for your program. The first line of the map contains information on how to read the map (space separated) : - The number of lines on the map; - The "empty" character; - The "obstacle" character; - The "full" character. The map is made up of '"empty" characters', lines and '"obstacle" characters'. The aim of the program is to replace '"empty" characters' by '"full" characters' in order to represent the biggest square possible. In the case that more than one solution exists, we'll choose to represent the square that's closest to the top of the map, then the one that's most to the left. When your program receives more than one map in argument, each solution or "map error" must be followed by a line break. Should there be no passed arguments, your program must be able to read on the standard input. Definition of a valid map : - All lines must have the same length. - There's at least one line of at least one box. - At each end of line, there's a line break. - The characters on the map can only be those introduced in the first line. - The map is invalid if a character is missing from the first line, or if two characters (of empty, full and obstacle) are identical. - The characters can be any printable character, even numbers. - In case of an invalid map, your program should display "map error" on the error output followed by a line break. Your program will then move on to the next map. example: %>cat example_file 9 . o x ........................... ....o...................... ............o.............. ........................... ....o...................... ...............o........... ........................... ......o..............o..... ..o.......o................ %>./bsq example_file .....xxxxxxx............... ....oxxxxxxx............... .....xxxxxxxo.............. .....xxxxxxx............... ....oxxxxxxx............... .....xxxxxxx...o........... .....xxxxxxx............... ......o..............o..... ..o.......o................ %>
[no solution yet]
* life [unsolved]
Assignment name : life Expected files : *.c *.h Allowed functions: atoi, read, putchar, malloc, calloc, realloc, free -------------------------------------------------------------------------------- You must write a program that will simulate a game of life. The prototype of this program is the following: ./life width height iterations Width and height are the dimensions of the board and iterations is the number of iterations of the game of life. the initial configuration of the board will be drawn by a sequence of commands in the standard input. Imagine a pen starting in the top left corner of the board. Each command is one of these characters: w a s d -> move the pen up, left, bottom, and right. x -> lift or lower the pen in order to start or stop drawing. Once end of file is reached, your program must simulate a game of life on this board and print the result in stdout (each cell alive will be represented by the character 'O' and each dead cell will be represented by a space) each cell outside of the array will be considered dead Example: $> echo 'sdxddssaaww' | ./a.out 5 5 0 | cat -e $ OOO $ O O $ OOO $ $ $> echo 'sdxssdswdxddddsxaadwxwdxwaa' | ./a.out 10 6 0 | cat -e $ O OOO $ O O $ OOO O $ O OOO $ $ $> echo 'dxss' | ./a.out 3 3 0 | cat -e O $ O $ O $ $> echo 'dxss' | ./a.out 3 3 1 | cat -e $ OOO$ $ $> echo 'dxss' | ./a.out 3 3 2 | cat -e O $ O $ O $
[no solution yet]