diff options
Diffstat (limited to 'rush02')
| -rw-r--r-- | rush02/ex00/Makefile | 38 | ||||
| -rw-r--r-- | rush02/ex00/convert.c | 67 | ||||
| -rw-r--r-- | rush02/ex00/dict.c | 114 | ||||
| -rw-r--r-- | rush02/ex00/error.c | 62 | ||||
| -rw-r--r-- | rush02/ex00/helper.c | 106 | ||||
| -rw-r--r-- | rush02/ex00/include.h | 72 | ||||
| -rw-r--r-- | rush02/ex00/main.c | 43 | ||||
| -rw-r--r-- | rush02/ex00/numbers.dict | 32 | ||||
| -rw-r--r-- | rush02/ex00/parse.c | 165 | ||||
| -rw-r--r-- | rush02/ex00/test.dict | 49 |
10 files changed, 748 insertions, 0 deletions
diff --git a/rush02/ex00/Makefile b/rush02/ex00/Makefile new file mode 100644 index 0000000..e299142 --- /dev/null +++ b/rush02/ex00/Makefile @@ -0,0 +1,38 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: cacharle <charles.cabergs@gmail.com> +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2019/07/20 07:26:11 by cacharle #+# #+# # +# Updated: 2019/07/21 11:46:43 by cacharle ### ########.fr # +# # +# **************************************************************************** # + +OUT = rush-02 +SRC = main.c helper.c parse.c error.c dict.c convert.c +OBJ = $(SRC:.c=.o) + +CC = gcc +CCFLAGS = -Wall -Wextra #-Werror + +.PHONY: all +all: $(OUT) + +$(OUT): $(OBJ) + $(CC) $(CCFLAGS) $(OBJ) -o $(OUT) + +%.o: %.c include.h + $(CC) $(CCFLAGS) -c $< -o $@ + +.PHONY: clean +clean: + rm -f $(OBJ) + +.PHONY: fclean +fclean: clean + rm -f $(OUT) + +.PHONY: re +re: fclean all diff --git a/rush02/ex00/convert.c b/rush02/ex00/convert.c new file mode 100644 index 0000000..6119f9c --- /dev/null +++ b/rush02/ex00/convert.c @@ -0,0 +1,67 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* convert.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: yiacono <yiacono@student.s19.be> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/07/20 11:14:59 by yiacono #+# #+# */ +/* Updated: 2019/07/21 15:03:02 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "include.h" +#include <unistd.h> + +static int check_arg(t_max_nbr nb, t_dict dict) +{ + if (nb < 0) + return (-1); + if (nb == 0) + { + while (dict->key > 0) + dict++; + ft_putstr(dict->value); + return (0); + } + if ((nb / dict->key) >= 1000) + return (-1); + return (0); +} + +static void effective_convert(t_max_nbr nb, t_dict dict) +{ + t_max_nbr div_result; + + while (nb > 0) + { + div_result = nb / dict->key; + if (div_result) + { + if (div_result == 1 && dict->key >= 100) + { + effective_convert(div_result, dict); + ft_putstr(" "); + } + else if (div_result > 1) + { + effective_convert(div_result, dict); + ft_putstr(" "); + } + ft_putstr(dict->value); + nb = nb % dict->key; + if (nb) + ft_putstr(" "); + } + dict++; + } +} + +int convert(t_max_nbr nb, t_dict dict) +{ + if (check_arg(nb, dict) < 0) + return (-1); + effective_convert(nb, dict); + ft_putstr("\n"); + return (0); +} diff --git a/rush02/ex00/dict.c b/rush02/ex00/dict.c new file mode 100644 index 0000000..f408dbc --- /dev/null +++ b/rush02/ex00/dict.c @@ -0,0 +1,114 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* dict.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle <charles.cabergs@gmail.com> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/07/20 18:44:04 by cacharle #+# #+# */ +/* Updated: 2019/07/21 15:01:26 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include <stdlib.h> +#include "include.h" + +static int is_sorted(t_dict dict) +{ + int i; + + i = 0; + while (dict[i + 1].key != -1) + { + if (dict[i].key < dict[i + 1].key) + return (FALSE); + i++; + } + return (TRUE); +} + +void sort_dict(t_dict dict) +{ + int i; + t_entry tmp; + + while (!is_sorted(dict)) + { + i = 0; + while (dict[i + 1].key != -1) + { + if (dict[i].key < dict[i + 1].key) + { + tmp = dict[i]; + dict[i] = dict[i + 1]; + dict[i + 1] = tmp; + } + i++; + } + } +} + +int as_uniq_keys(t_dict dict) +{ + int i; + + while (dict->value != NULL) + { + i = 1; + while (dict[i].value != NULL) + { + if (dict->key == dict[i].key) + return (FALSE); + i++; + } + dict++; + } + return (TRUE); +} + +int required_values(t_dict dict) +{ + int i; + t_max_nbr key; + int keys_checked; + + i = 0; + keys_checked = 0; + while (dict[i].key != -1) + { + key = dict[i].key; + if (key == 0 || key == 1 || key == 2 || key == 3 || key == 4 || key == 5 + || key == 6 || key == 7 || key == 8 || key == 9 || key == 10 + || key == 11 || key == 12 || key == 13 || key == 14 || key == 15 + || key == 16 || key == 17 || key == 18 || key == 19 || key == 20 + || key == 30 || key == 40 || key == 50 || key == 60 || key == 70 + || key == 80 || key == 90 || key == 100 || key == 1000 + || key == 1000000 || key == 1000000000) + keys_checked++; + i++; + } + return (keys_checked == REQUIRED_SIZE); +} + +/* +** destroy dict, by freeing each value and the dict itself +*/ + +void destroy_dict(t_dict dict, int size) +{ + int i; + + if (dict == NULL) + return ; + i = 0; + if (size == -1) + while (dict[i].key != -1) + { + free(dict[i].value); + i++; + } + else + while (--size > 0) + free(dict[size].value); + free(dict); +} diff --git a/rush02/ex00/error.c b/rush02/ex00/error.c new file mode 100644 index 0000000..27dba41 --- /dev/null +++ b/rush02/ex00/error.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* error.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: yiacono <yiacono@student.s19.be> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/07/20 10:55:27 by agassin #+# #+# */ +/* Updated: 2019/07/21 14:17:53 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "include.h" + +/* +** similar to atoi but doesn't allow anything before or after ('-' included) +** return the number or -1 in case of error +*/ + +t_max_nbr strict_atoi(char *str) +{ + t_max_nbr nb; + int i; + + nb = 0; + i = 0; + while (str[i]) + { + if (str[i] < '0' || str[i] > '9') + return (-1); + i++; + } + if (i == 0) + return (-1); + i = 0; + while (str[i]) + { + nb *= 10; + nb += str[i++] - '0'; + } + return (nb); +} + +int print_error_if(int status, t_dict dict) +{ + if (status) + { + ft_putstr("Error\n"); + destroy_dict(dict, -1); + } + return (status); +} + +int print_dict_error_if(int status, t_dict dict) +{ + if (status) + { + ft_putstr("Dict Error\n"); + destroy_dict(dict, -1); + } + return (status); +} diff --git a/rush02/ex00/helper.c b/rush02/ex00/helper.c new file mode 100644 index 0000000..e29eb47 --- /dev/null +++ b/rush02/ex00/helper.c @@ -0,0 +1,106 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* helper.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle <cacharle@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/07/20 07:25:21 by cacharle #+# #+# */ +/* Updated: 2019/07/21 08:23:41 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include <unistd.h> +#include <stdlib.h> +#include <fcntl.h> +#include "include.h" + +/* +** Read an already openned file in `file` +** return the file_size (-1 if a error occurs) +*/ + +int read_file(int fildes, char **file_ptr) +{ + char buf[BUF_SIZE]; + int file_size; + int read_size; + + file_size = 0; + while ((read_size = read(fildes, buf, BUF_SIZE))) + { + if (read_size < 0) + return (-1); + *file_ptr = ft_memcat(*file_ptr, buf, file_size, read_size); + file_size += read_size; + } + return (file_size); +} + +/* +** Concatenate buf[buf_size] into file[file_size] +** Create a copy of the file, free file, +** reallocate it with sufficient memory for the concatenation +** copy each character of file_copy then buf into file +** free file_copy +*/ + +char *ft_memcat(char *file, char buf[BUF_SIZE], int file_size, + int buf_size) +{ + int i; + char *file_copy; + + if ((file_copy = malloc(sizeof(char) * (file_size + 1))) == NULL) + return (NULL); + i = -1; + while (++i < file_size) + file_copy[i] = file[i]; + free(file); + if ((file = malloc(sizeof(char) * (file_size + buf_size + 1))) == NULL) + return (NULL); + i = 0; + while (i < file_size) + { + file[i] = file_copy[i]; + i++; + } + free(file_copy); + while (i < file_size + buf_size) + { + file[i] = buf[i - file_size]; + i++; + } + return (file); +} + +char *ft_strndup(char *src, int n) +{ + int i; + char *dup_ptr; + + dup_ptr = (char*)malloc(sizeof(char) * (n + 1)); + if (dup_ptr == NULL) + return (NULL); + i = 0; + while (src[i] && i < n) + { + dup_ptr[i] = src[i]; + i++; + } + dup_ptr[i] = '\0'; + return (dup_ptr); +} + +/* +** Print a string char by char on the standard output +*/ + +void ft_putstr(char *str) +{ + while (*str) + { + write(1, str, 1); + str++; + } +} diff --git a/rush02/ex00/include.h b/rush02/ex00/include.h new file mode 100644 index 0000000..f50f846 --- /dev/null +++ b/rush02/ex00/include.h @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* include.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: yiacono <yiacono@student.s19.be> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/07/20 07:31:47 by cacharle #+# #+# */ +/* Updated: 2019/07/21 14:51:26 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef INCLUDE_H +# define INCLUDE_H + +# define TRUE 1 +# define FALSE 0 +# define BUF_SIZE 1024 +# define REQUIRED_SIZE 32 + +typedef long long int t_max_nbr; +struct s_entry +{ + t_max_nbr key; + char *value; +}; +typedef struct s_entry t_entry; +typedef t_entry* t_dict; +/* +** helper.c - previously made functions +*/ + +int read_file(int fildes, char **file); +char *ft_memcat(char *file, char buf[BUF_SIZE], int file_size, + int buf_size); +char *ft_strndup(char *src, int n); +void ft_putstr(char *str); + +/* +** convert.c - Convert number to string +*/ + +int convert(t_max_nbr nb, t_dict dict); + +/* +** parse.c - Dictionnary reading and converting +*/ + +t_dict parse_dict(char *file, int file_size); +t_dict parse_dict_file(char *filename); +int set_entry(char *line, t_entry *entry); +char *filtered_value(char *str); +int count_lines(char *file); + +/* +** dict.c - operation on dict +*/ + +void sort_dict(t_dict dict); +int required_values(t_dict dict); +int as_uniq_keys(t_dict dict); +void destroy_dict(t_dict dict, int size); + +/* +** error.c - Error checking +*/ + +t_max_nbr strict_atoi(char *str); +int print_error_if(int status, t_dict dict); +int print_dict_error_if(int status, t_dict dict); + +#endif diff --git a/rush02/ex00/main.c b/rush02/ex00/main.c new file mode 100644 index 0000000..14085f6 --- /dev/null +++ b/rush02/ex00/main.c @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: yiacono <yiacono@student.s19.be> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/07/20 07:25:21 by cacharle #+# #+# */ +/* Updated: 2019/07/21 15:02:43 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include <stdlib.h> +#include "include.h" + +int main(int argc, char **argv) +{ + t_dict dict; + t_max_nbr nb; + + if (print_error_if(argc > 3 || argc == 1, NULL)) + return (1); + if (argc == 2) + { + dict = parse_dict_file("numbers.dict"); + nb = strict_atoi(argv[1]); + } + if (argc == 3) + { + dict = parse_dict_file(argv[1]); + nb = strict_atoi(argv[2]); + } + if (print_error_if(nb == -1, dict)) + return (1); + if (print_dict_error_if(dict == NULL || !required_values(dict) + || !as_uniq_keys(dict), dict)) + return (1); + sort_dict(dict); + if (print_error_if(convert(nb, dict), dict)) + return (1); + destroy_dict(dict, -1); + return (0); +} diff --git a/rush02/ex00/numbers.dict b/rush02/ex00/numbers.dict new file mode 100644 index 0000000..72e09c9 --- /dev/null +++ b/rush02/ex00/numbers.dict @@ -0,0 +1,32 @@ +0: zero +1: one +2: two +3: three +4: four +5: five +6: six +7: seven +8: eight +9: nine +10: ten +11: eleven +12: twelve +13: thirteen +14: fourteen +15: fifteen +16: sixteen +17: seventeen +18: eighteen +19: nineteen +20: twenty +30: thirty +40: forty +50: fifty +60: sixty +70: seventy +80: eighty +90: ninety +100: hundred +1000: thousand +1000000: million +1000000000: billion diff --git a/rush02/ex00/parse.c b/rush02/ex00/parse.c new file mode 100644 index 0000000..af3d43d --- /dev/null +++ b/rush02/ex00/parse.c @@ -0,0 +1,165 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* file.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: agassin <agassin@student.42.fr> +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2019/07/20 10:47:14 by cacharle #+# #+# */ +/* Updated: 2019/07/21 14:44:22 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include "include.h" + +/* +** Open the dictionnary file, pass it to `parse_dict` +** return the dict, NULL if an error occurs +*/ + +t_dict parse_dict_file(char *filename) +{ + char *file; + int fildes; + int file_size; + t_dict dict; + + if ((fildes = open(filename, O_RDONLY)) < 0) + return (NULL); + file = NULL; + if ((file_size = read_file(fildes, &file)) < 0) + return (NULL); + if ((dict = parse_dict(file, file_size)) == NULL) + { + destroy_dict(dict, -1); + free(file); + return (NULL); + } + free(file); + if (close(fildes) < 0) + return (NULL); + return (dict); +} + +/* +** Parse the file and return a dictionary where the keys are +** the numbers and the values the string attached to it +*/ + +t_dict parse_dict(char *file, int file_size) +{ + int i; + int j; + t_dict dict; + + dict = (t_dict)malloc(sizeof(t_entry) * (count_lines(file) + 1)); + if (dict == NULL) + return (NULL); + i = 0; + j = 0; + while (i < file_size) + { + while (file[i] && file[i] == '\n') + i++; + if (file[i] && (set_entry(&file[i], &dict[j++])) == -1) + { + destroy_dict(dict, j - 1); + return (NULL); + } + while (file[i] && file[i] != '\n') + i++; + } + dict[j].key = -1; + dict[j].value = NULL; + return (dict); +} + +/* +** Set the key and value of an entry based on the given line +** return -1 if an error occurs +*/ + +int set_entry(char *line, t_entry *entry) +{ + int i; + char *tmp; + + i = 0; + while (line[i] >= '0' && line[i] <= '9') + i++; + if (i == 0) + return (-1); + tmp = ft_strndup(line, i); + entry->key = strict_atoi(tmp); + free(tmp); + while (line[i] == ' ') + i++; + if (line[i] != ':') + return (-1); + i++; + while (line[i] == ' ') + i++; + entry->value = filtered_value(&line[i]); + if (entry->value == NULL) + return (-1); + return (0); +} + +/* +** Duplicate the line and compress spaces until there is only one left +*/ + +char *filtered_value(char *str) +{ + int i; + int j; + char *value; + + i = 0; + while (str[i] != '\n') + i++; + if (i == 0) + return (NULL); + if ((value = (char*)malloc(sizeof(char) * (i + 1))) == NULL) + return (NULL); + i = 0; + j = 0; + while (str[i] && str[i] != '\n') + { + value[j++] = str[i++]; + while (str[i] && str[i] == ' ') + { + if (str[i + 1] && str[i + 1] != ' ') + break ; + i++; + } + } + value[i] = '\0'; + return (value); +} + +/* +** count the number of line in the file +** without counting empty lines +*/ + +int count_lines(char *file) +{ + int counter; + + counter = 0; + while (*file) + { + if (*file == '\n') + { + counter++; + while (*file == '\n') + file++; + } + file++; + } + return (counter); +} diff --git a/rush02/ex00/test.dict b/rush02/ex00/test.dict new file mode 100644 index 0000000..bbd8b5b --- /dev/null +++ b/rush02/ex00/test.dict @@ -0,0 +1,49 @@ + +11: bonjour +13: thir +14 : fourteen + + + +0: zero +1 : one +2: two +3: three +5: five + + + + +6: six +12: twelve +4: four +7: seven +8: eight +9: nines +10: ten +15: fifteen +16: sixteen +17: seventeen +18: eighteen +19: nineteen +20: twenty +21 : bonjour je suis +30: thirty +40: forty +50: fifty +60: sixty +70: seventy +80: eighty +90: ninety +100 : hundred +1000: thousand +1000000 : million +1000000000 : billion +1000000000000 : trillion +1000000000000000 : quadrillion +1000000000000000000 : quintillion +1000000000000000000000 : hexillion +1000000000000000000000000 : heptillion + + + |
