├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── assets ├── push_swap_large.gif └── push_swap_small.gif ├── build-targets ├── debug.inc ├── profile.inc └── release.inc ├── include ├── checker.h ├── general.h └── push_swap.h ├── libft ├── Makefile ├── include │ ├── get_next_line.h │ └── libft.h └── src │ ├── ft_atoi.c │ ├── ft_bzero.c │ ├── ft_calloc.c │ ├── ft_isalnum.c │ ├── ft_isalpha.c │ ├── ft_isascii.c │ ├── ft_isdigit.c │ ├── ft_isprint.c │ ├── ft_isspace.c │ ├── ft_itoa.c │ ├── ft_lstadd_back.c │ ├── ft_lstadd_front.c │ ├── ft_lstclear.c │ ├── ft_lstdelone.c │ ├── ft_lstfirst.c │ ├── ft_lstiter.c │ ├── ft_lstlast.c │ ├── ft_lstmap.c │ ├── ft_lstnew.c │ ├── ft_lstsize.c │ ├── ft_memccpy.c │ ├── ft_memchr.c │ ├── ft_memcmp.c │ ├── ft_memcpy.c │ ├── ft_memmove.c │ ├── ft_memset.c │ ├── ft_putchar_fd.c │ ├── ft_putendl_fd.c │ ├── ft_putnbr_fd.c │ ├── ft_putstr_fd.c │ ├── ft_split.c │ ├── ft_strchr.c │ ├── ft_strcspn.c │ ├── ft_strdup.c │ ├── ft_streq.c │ ├── ft_strjoin.c │ ├── ft_strlcat.c │ ├── ft_strlcpy.c │ ├── ft_strlen.c │ ├── ft_strmapi.c │ ├── ft_strncmp.c │ ├── ft_strnstr.c │ ├── ft_strrchr.c │ ├── ft_strreplace.c │ ├── ft_strspn.c │ ├── ft_strtok.c │ ├── ft_strtok_r.c │ ├── ft_strtrim.c │ ├── ft_substr.c │ ├── ft_tolower.c │ ├── ft_toupper.c │ └── get_next_line.c ├── libstack ├── include │ └── stack.h └── src │ ├── initialize.c │ ├── max.c │ ├── min.c │ ├── push.c │ ├── rotate.c │ └── swap.c ├── pyviz.py ├── runner.pl ├── src ├── checker │ ├── checker.c │ ├── execute.c │ └── get_line.c ├── free.c ├── get_stack.c ├── push_swap │ ├── index.c │ ├── move.c │ ├── push_swap.c │ ├── run.c │ ├── smart.c │ ├── sort.c │ ├── sort_complex.c │ └── sort_small.c ├── search.c ├── utils.c └── utils_sort.c └── test ├── include └── minunit.h └── src └── test.c /.gitignore: -------------------------------------------------------------------------------- 1 | ##################### 2 | ### Project files ### 3 | ##################### 4 | 5 | checker 6 | push_swap 7 | build 8 | .clangd/ 9 | .cache/ 10 | .build-target 11 | compile_commands.json 12 | !src/checker/ 13 | !src/push_swap/ 14 | 15 | ################### 16 | ### C.gitignore ### 17 | ################### 18 | 19 | # Prerequisites 20 | *.d 21 | 22 | # Object files 23 | *.o 24 | *.ko 25 | *.obj 26 | *.elf 27 | 28 | # Linker output 29 | *.ilk 30 | *.map 31 | *.exp 32 | 33 | # Precompiled Headers 34 | *.gch 35 | *.pch 36 | 37 | # Libraries 38 | *.lib 39 | **.a 40 | *.la 41 | *.lo 42 | 43 | # Shared objects (inc. Windows DLLs) 44 | *.dll 45 | *.so 46 | *.so.* 47 | *.dylib 48 | 49 | # Executables 50 | *.exe 51 | *.out 52 | *.app 53 | *.i*86 54 | *.x86_64 55 | *.hex 56 | 57 | # Debug files 58 | *.dSYM/ 59 | *.su 60 | *.idb 61 | *.pdb 62 | 63 | # Kernel Module Compile Results 64 | *.mod* 65 | *.cmd 66 | .tmp_versions/ 67 | modules.order 68 | Module.symvers 69 | Mkfile.old 70 | dkms.conf 71 | 72 | ##################### 73 | ### Vim.gitignore ### 74 | ##################### 75 | 76 | # Swap 77 | [._]*.s[a-v][a-z] 78 | !*.svg # comment out if you don't need vector files 79 | [._]*.sw[a-p] 80 | [._]s[a-rt-v][a-z] 81 | [._]ss[a-gi-z] 82 | [._]sw[a-p] 83 | 84 | # Session 85 | Session.vim 86 | Sessionx.vim 87 | 88 | # Temporary 89 | .netrwhist 90 | *~ 91 | # Auto-generated tag files 92 | tags 93 | # Persistent undo 94 | [._]*.un~ 95 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Adrian W. Roque 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # This Makefile has improved a lot from the tips given by Lunderberg. 2 | # While his main focus was to build projects with C++, we could take 3 | # a lot of great ideas to use here as well. Check out his work on 4 | # http://www.lunderberg.com/2015/08/24/cpp-makefile-multiple-libraries/ 5 | 6 | # Default build variables, can be overridden by command line options. 7 | 8 | NAME = checker push_swap 9 | 10 | CC = clang 11 | CPPFLAGS = 12 | CFLAGS = 13 | LDFLAGS = 14 | LDLIBS = 15 | RM = rm -f 16 | BUILD = default 17 | 18 | ifneq ($(BUILD),default) 19 | include build-targets/$(BUILD).inc 20 | endif 21 | 22 | # Additional flags that are necessary to compile. 23 | # Even if not specified on the command line, these should be present. 24 | 25 | override CPPFLAGS += -Iinclude 26 | override CFLAGS += -Wall -Wextra -Werror 27 | override LDFLAGS += -Llib -Wl,-rpath,\$$ORIGIN/../lib -Wl,--no-as-needed 28 | override LDLIBS += 29 | 30 | .SECONDARY: 31 | .SECONDEXPANSION: 32 | .PHONY: all clean fclean re force test 33 | 34 | # Source and object files for the executable 35 | vpath %.c src src/checker src/push_swap libft/src libstack/src 36 | 37 | SRC_FILES = get_stack.c \ 38 | search.c \ 39 | free.c \ 40 | utils.c \ 41 | utils_sort.c 42 | O_FILES = $(patsubst %.c,build/$(BUILD)/build/%.o,$(SRC_FILES)) 43 | 44 | CHECKER_SRC_FILES = checker.c \ 45 | search.c \ 46 | get_line.c \ 47 | execute.c 48 | CHECKER_O_FILES = $(patsubst %.c,build/$(BUILD)/build/%.o,$(CHECKER_SRC_FILES)) $(O_FILES) 49 | 50 | PUSH_SWAP_SRC_FILES = push_swap.c \ 51 | sort.c \ 52 | sort_small.c \ 53 | sort_complex.c \ 54 | smart.c \ 55 | index.c \ 56 | move.c \ 57 | run.c 58 | PUSH_SWAP_O_FILES = $(patsubst %.c,build/$(BUILD)/build/%.o,$(PUSH_SWAP_SRC_FILES)) $(O_FILES) 59 | 60 | # Build and link of multiple libraries 61 | LIBRARY_FOLDERS = libft libstack 62 | LIBRARY_INCLUDES = $(patsubst %,-I%/include,$(LIBRARY_FOLDERS)) 63 | override CPPFLAGS += $(LIBRARY_INCLUDES) 64 | LIBRARY_FLAGS = $(patsubst lib%,-l%,$(LIBRARY_FOLDERS)) 65 | override LDLIBS += $(LIBRARY_FLAGS) 66 | library_src_files = ft_atoi.c \ 67 | ft_bzero.c \ 68 | ft_calloc.c \ 69 | ft_isalnum.c \ 70 | ft_isalpha.c \ 71 | ft_isascii.c \ 72 | ft_isdigit.c \ 73 | ft_isprint.c \ 74 | ft_isspace.c \ 75 | ft_itoa.c \ 76 | ft_lstadd_front.c \ 77 | ft_lstdelone.c \ 78 | ft_lstfirst.c \ 79 | ft_lstmap.c \ 80 | ft_lstnew.c \ 81 | ft_lstsize.c \ 82 | ft_memccpy.c \ 83 | ft_strtrim.c \ 84 | ft_memcpy.c \ 85 | ft_strtok_r.c \ 86 | ft_memcmp.c \ 87 | ft_memset.c \ 88 | ft_putchar_fd.c \ 89 | ft_putendl_fd.c \ 90 | ft_putnbr_fd.c \ 91 | ft_putstr_fd.c \ 92 | ft_strchr.c \ 93 | ft_strcspn.c \ 94 | ft_strdup.c \ 95 | ft_strlcat.c \ 96 | ft_strlcpy.c \ 97 | ft_memmove.c \ 98 | ft_strmapi.c \ 99 | ft_strnstr.c \ 100 | ft_strrchr.c \ 101 | ft_strspn.c \ 102 | ft_split.c \ 103 | ft_lstiter.c \ 104 | ft_substr.c \ 105 | ft_tolower.c \ 106 | ft_toupper.c \ 107 | ft_strjoin.c \ 108 | ft_strtok.c \ 109 | ft_lstadd_back.c \ 110 | ft_lstlast.c \ 111 | ft_memchr.c \ 112 | ft_strlen.c \ 113 | ft_strncmp.c \ 114 | ft_strreplace.c \ 115 | ft_streq.c \ 116 | ft_lstclear.c \ 117 | get_next_line.c \ 118 | initialize.c \ 119 | push.c \ 120 | max.c \ 121 | min.c \ 122 | rotate.c \ 123 | swap.c 124 | library_o_files = $(patsubst %.c,build/$(BUILD)/build/%.o,$(call library_src_files,$(1))) 125 | STATIC_LIBRARY_OUTPUT = $(patsubst %,lib/%.a,$(LIBRARY_FOLDERS)) 126 | 127 | # Source and object files for unit tests 128 | TEST_FOLDER = test 129 | TEST_INCLUDES = $(patsubst %,-I%/include,$(TEST_FOLDER)) 130 | override CPPFLAGS += $(TEST_INCLUDES) 131 | TEST_SRC_FILES = $(TEST_FOLDER)/src/test.c 132 | TEST_O_FILES = $(patsubst %.c,build/$(BUILD)/build/%.o, $(TEST_SRC_FILES)) 133 | TEST_O_FILES += $(O_FILES) 134 | TEST_O_FILES += $(filter-out %/checker.o, $(CHECKER_O_FILES)) 135 | TEST_O_FILES += $(filter-out %/push_swap.o, $(PUSH_SWAP_O_FILES)) 136 | 137 | 138 | ################ 139 | # SOURCE FILES # 140 | ################ 141 | 142 | all: $(NAME) 143 | 144 | override CPPFLAGS += -MMD 145 | -include $(shell find build -name "*.d" 2> /dev/null) 146 | 147 | .build-target: force 148 | echo $(BUILD) | cmp -s - $@ || echo $(BUILD) > $@ 149 | 150 | checker: build/$(BUILD)/bin/checker .build-target $(STATIC_LIBRARY_OUTPUT) 151 | mkdir -p $(@D) 152 | cp -f $< $@ 153 | 154 | push_swap: build/$(BUILD)/bin/push_swap .build-target $(STATIC_LIBRARY_OUTPUT) 155 | mkdir -p $(@D) 156 | cp -f $< $@ 157 | 158 | lib/%: build/$(BUILD)/lib/% .build-target 159 | mkdir -p $(@D) 160 | cp -f $< $@ 161 | 162 | build/$(BUILD)/bin/checker: $(CHECKER_O_FILES) $(STATIC_LIBRARY_OUTPUT) 163 | mkdir -p $(@D) 164 | $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ 165 | 166 | build/$(BUILD)/bin/push_swap: $(PUSH_SWAP_O_FILES) $(STATIC_LIBRARY_OUTPUT) 167 | mkdir -p $(@D) 168 | $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ 169 | 170 | build/$(BUILD)/build/%.o: %.c 171 | mkdir -p $(@D) 172 | $(CC) -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 173 | 174 | ################## 175 | # LIBRARIES ZONE # 176 | ################## 177 | 178 | define library_variables 179 | CPPFLAGS_LIB = 180 | CFLAGS_LIB = 181 | LDFLAGS_LIB = 182 | -include $(1)/Makefile.inc 183 | build/$(1)/%.o: CPPFLAGS := $$(CPPFLAGS) $$(CPPFLAGS_LIB) 184 | build/$(1)/%.o: CFLAGS := $$(CFLAGS) $$(CFLAGS_LIB) 185 | lib/$(1).a: LDFLAGS := $$(ALL_LDFLAGS) $$(LDFLAGS_LIB) 186 | endef 187 | 188 | $(foreach lib,$(LIBRARY_FOLDERS),$(eval $(call library_variables,$(lib)))) 189 | 190 | build/$(BUILD)/lib/lib%.a: $$(call library_o_files,%) 191 | mkdir -p $(@D) 192 | $(AR) rcs $@ $^ 193 | 194 | ############# 195 | # TEST ZONE # 196 | ############# 197 | 198 | build/$(BUILD)/bin/test: $(TEST_O_FILES) $(STATIC_LIBRARY_OUTPUT) 199 | mkdir -p $(@D) 200 | $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ 201 | 202 | test: build/$(BUILD)/bin/test 203 | ./$< 204 | 205 | ######### 206 | # UTILS # 207 | ######### 208 | 209 | clean: 210 | $(RM) -r bin build lib .build-target 211 | 212 | fclean: clean 213 | $(RM) $(NAME) 214 | 215 | re: fclean all 216 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # push\_swap 2 | 3 | _Swap push is strange, isn't it???_ 4 | 5 | ![A visual example of push_swap with a small stack](./assets/push_swap_small.gif) 6 | 7 | ## Introduction 8 | 9 | This project comprises an interesting case study regarding sorting algorithms and its performances, being part of the core curriculum of all 42 schools worldwide. The task is simple: given a sequence of random numbers disposed in a stack data structure (**stack A**), sort them with the help of an empty auxiliary stack (**stack B**) and a set of specific stack operations. The operations allowed are described as follows, as written in our task: 10 | 11 | - **`sa`** : **swap a** - Swap the first 2 elements at the top of stack A. Do nothing if there is only one or no elements). 12 | - **`sb`** : **swap b** - Swap the first 2 elements at the top of stack B. Do nothing if there is only one or no elements). 13 | - **`ss`** : **`sa`** and **`sb`** at the same time. 14 | - **`pa`** : **push a** - take the first element at the top of b and put it at the top of a. Do nothing if B is empty. 15 | - **`pb`** : **push b** - take the first element at the top of a and put it at the top of b. Do nothing if A is empty. 16 | - **`ra`** : **rotate a** - shift up all elements of stack A by 1. The first element becomes the last one. 17 | - **`rb`** : **rotate b** - shift up all elements of stack B by 1. The first element becomes the last one. 18 | - **`rr`** : **`ra`** and **`rb`** at the same time. 19 | - **`rra`** : **reverse rotate a** - shift down all elements of stack A by 1. The last element becomes the first one. 20 | - **`rrb`** : **reverse rotate b** - shift down all elements of stack B by 1. The last element becomes the first one. 21 | - **`rrr`** : **`rra`** and **`rrb`** at the same time. 22 | 23 | ### The Push Swap Program 24 | 25 | The main objective of the `push_swap` is to print to `STDOUT` the instructions required to sort the **stack A**, which must be given as the program's argument. Each instruction must be followed by a line break (`\n`). The **stack A** must be sorted with its lowest element at the top, while **stack B** must be empty. 26 | 27 | ```shell 28 | $ ARG='4 0 1 3 2'; ./push_swap $ARG 29 | 30 | pb 31 | pb 32 | sa 33 | ra 34 | pa 35 | pa 36 | ra 37 | ``` 38 | 39 | ### The Checker Program 40 | 41 | To help identify if a set of instructions is valid or not, you can run the `checker` program with the same stack as the `push_swap` program. The `checker` program will then accept the sorting instructions on `STDIN`, giving us the result `OK`, if the stack was indeed sorted, or `KO` otherwise. 42 | 43 | 44 | ```shell 45 | $ ARG='4 0 1 3 2'; ./push_swap $ARG | ./checker $ARG 46 | 47 | OK 48 | ``` 49 | 50 | Both the `checker` or `push_swap` executables will result in an error if a stack has non-numerical arguments, a number is repeated or if a number is out of the 8-bit integer range. 51 | 52 | --- 53 | 54 | ## Compilation 55 | 56 | You must have installed `make` and `clang` to compile this project. The execution of the `make` command will generate the binaries for both `checker` and `push_swap` and the libraries needed to the compilation. 57 | 58 | --- 59 | 60 | ## Testing 61 | 62 | To run the integrated tests, you must have installed the `Python 3.6+`, `perl` and `libipc-run3-perl` packages on your system. The unit tests may be executed by running the `make test` command. To run the simple integrated tests on your system, you can use the `runner.pl` helper script. 63 | 64 | ```shell 65 | perl runner.pl 100 66 | perl runner.pl 100 --checker 67 | perl runner.pl 100 --count 68 | ``` 69 | 70 | In this example, a stack of 100 random integers is generated, and the `push_swap` command is used to sort the sequence. 71 | 72 | - Running the script without arguments will print the instructions to `STDOUT`; 73 | - Running with the `--checker` option will invoke the `checker` program to check if the instructions will sort the stack correctly; 74 | - Running with the `--count` option will count the number of instructions needed to sort the stack with the `wc` program. 75 | 76 | The visual tests can be seen with the help of Emmanuel Ruaud testing Python script. His work is truly helpful, and I encourage you to star it at [push_swap_visualizer](https://github.com/o-reo/push_swap_visualizer). To run it, simply run the following command: 77 | 78 | ```shell 79 | ### Change with the stack size to sort 80 | 81 | python3 pyviz.py `perl -e "use List::Util 'shuffle'; print join(' ', shuffle(0..( - 1)))"` 82 | ``` 83 | 84 | --- 85 | 86 | ## The Algorithm 87 | 88 | I was heavily inspired with the works of Jamie Dawson and Anya Schukin to get to the final version of this project. Let's start with Jamie's article [Push_Swap: The least amount of moves with two stacks](https://medium.com/@jamierobertdawson/push-swap-the-least-amount-of-moves-with-two-stacks-d1e76a71789a), which explains how we can sort a stack with 5 numbers or fewer. 89 | 90 | ### Sorting of a Small Stack 91 | 92 | Given that we have 0 or 1 numbers at the stack, we don't need to do anything, as we can assume that a stack of a single number is already sorted. At 2 numbers, we may have only two scenarios: 93 | 94 | 1. The stack is already sorted; or 95 | 2. if not, swap the numbers of stack A. 96 | 97 | When we have 3 numbers, the situation is a little more complex, but it's still easy. In this case, a sequence of 3 numbers only allow `3! = 6` permutations of elements. Given that one these permutations is the sorted sequence, we only have to bother with 5 permutations, each one of them with a different set of instructions required to sort. The details are explained in Jamie's article, and the implementation may be found at the `sort_small.c` source file. 98 | 99 | When we have 4 or 5 elements, we just need to push the top two elements to stack B and run the sorting algorithm on the remaining stack. To finish the sorting process, we just need to push the last two or less elements on stack B, finding the correct position on the stack A before running the push operation. 100 | 101 | ### Sorting of a Large Stack 102 | 103 | The former algorithm wasn't able to deal with a large stack, with more than 100 or 500 elements. Therefore, we would need to change our strategy a little bit. First of all, I'd like to cite Anya's work [Push_Swap](https://github.com/anyaschukin/Push_Swap), which is the basis for this section of the project. 104 | 105 | The best way to deal with a large number of elements is to split them in smaller chunks. As we have an auxiliary stack to make operations, we could transfer the elements in between of a certain range of minimal and maximal limits, without bothering with their order at this point. After pushing all the elements of a chunk, let's push them back, but at this time, they must be pushed in the correct order. The use of rotation operations is of great importance right now. 106 | 107 | Here, it's interesting to have some kind of `smart_rotate` function, which will rotate the stack according to the number we want at the top. This way, we may select the canonical or reverse rotation, and apply the one which will grant us the fewer amount of moves required. 108 | 109 | We can then proceed to sort the remaining chunks, until we have the stack A completely sorted. At the end, it's important to move the smaller element with the help of `smart_rotate`. 110 | 111 | ![A visual example of push_swap with a large stack](./assets/push_swap_large.gif) 112 | -------------------------------------------------------------------------------- /assets/push_swap_large.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdrianWR/push_swap/c61876a7474420fae3d15379546a5cd12db69cc8/assets/push_swap_large.gif -------------------------------------------------------------------------------- /assets/push_swap_small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AdrianWR/push_swap/c61876a7474420fae3d15379546a5cd12db69cc8/assets/push_swap_small.gif -------------------------------------------------------------------------------- /build-targets/debug.inc: -------------------------------------------------------------------------------- 1 | CFLAGS = -g -fsanitize=address 2 | LDFLAGS = -fsanitize=address 3 | -------------------------------------------------------------------------------- /build-targets/profile.inc: -------------------------------------------------------------------------------- 1 | CPPFLAGS += -pg 2 | LDFLAGS += -pg 3 | -------------------------------------------------------------------------------- /build-targets/release.inc: -------------------------------------------------------------------------------- 1 | CPPFLAGS = -O3 2 | LDFLAGS = -s 3 | -------------------------------------------------------------------------------- /include/checker.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* checker.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/02 23:23:49 by aroque #+# #+# */ 9 | /* Updated: 2021/05/04 23:40:11 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef CHECKER_H 14 | # define CHECKER_H 15 | 16 | # include "stack.h" 17 | 18 | # define INSTRUCTIONS_BUFFER_SIZE 4096 19 | 20 | int binary_search(int n, int *data, int size); 21 | int get_instructions(char ***instructions); 22 | int execute(char **instructions, t_stack *stack); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /include/general.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* general.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/06 21:00:27 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:47:21 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef GENERAL_H 14 | # define GENERAL_H 15 | 16 | # include "stack.h" 17 | 18 | # define SPACE ' ' 19 | # define STACK_BUFFER 1024 20 | 21 | int abs(int n); 22 | bool atoiv(const char *str, int *overflow); 23 | void free_array(void **array); 24 | void free_stack(t_stack *stack); 25 | void message_and_exit(t_stack *stack, char **ops, int status); 26 | void reverse_array(int *array, size_t size); 27 | bool is_sorted(t_stack *stack); 28 | void insertion_sort(int array[], size_t size); 29 | t_stack *get_stack(int size, char **args); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /include/push_swap.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* push_swap.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/06 21:09:58 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:46:58 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef PUSH_SWAP_H 14 | # define PUSH_SWAP_H 15 | 16 | # include "stack.h" 17 | 18 | # define SA "sa" 19 | # define SB "sb" 20 | # define PA "pa" 21 | # define PB "pb" 22 | # define RA "ra" 23 | # define RB "rb" 24 | # define RRA "rra" 25 | # define RRB "rrb" 26 | 27 | # define CHUNK_CONSTANT 50 28 | # define SORT_COMPLEX_LIMIT 5 29 | 30 | int _index(t_stack *stack, int n); 31 | void sort(t_stack *stack); 32 | void run(char *op, t_stack *a, t_stack *b); 33 | void run_n(char *op, t_stack *a, t_stack *b, int n); 34 | void index_stack(t_stack **stack); 35 | void sort_small(t_stack *a, t_stack *b); 36 | void sort_complex(t_stack *a, t_stack *b); 37 | void smart_rotate_a(t_stack *a, int n); 38 | void smart_rotate_b(t_stack *b, int n); 39 | int closest_above(t_stack *a, int n); 40 | int closest_below(t_stack *a, int n); 41 | void move_to_top(t_stack *a, int min, int max); 42 | void move_min_or_max_to_top(t_stack *b); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /libft/Makefile: -------------------------------------------------------------------------------- 1 | # **************************************************************************** # 2 | # # 3 | # ::: :::::::: # 4 | # Makefile :+: :+: :+: # 5 | # +:+ +:+ +:+ # 6 | # By: aroque +#+ +:+ +#+ # 7 | # +#+#+#+#+#+ +#+ # 8 | # Created: 2020/01/21 11:20:51 by aroque #+# #+# # 9 | # Updated: 2021/02/01 00:30:52 by aroque ### ########.fr # 10 | # # 11 | # **************************************************************************** # 12 | 13 | NAME = libft.a 14 | 15 | CC = gcc 16 | CC_FLAGS = -Wall \ 17 | -Wextra \ 18 | -Werror 19 | 20 | LD_FLAGS = 21 | 22 | INCLUDES = . 23 | 24 | SRC_DIR = . 25 | SRC = ${SRC_DIR}/ft_memset.c \ 26 | ${SRC_DIR}/ft_bzero.c \ 27 | ${SRC_DIR}/ft_memcpy.c \ 28 | ${SRC_DIR}/ft_memccpy.c \ 29 | ${SRC_DIR}/ft_memmove.c \ 30 | ${SRC_DIR}/ft_memchr.c \ 31 | ${SRC_DIR}/ft_memcmp.c \ 32 | ${SRC_DIR}/ft_strlen.c \ 33 | ${SRC_DIR}/ft_strlcpy.c \ 34 | ${SRC_DIR}/ft_strlcat.c \ 35 | ${SRC_DIR}/ft_strchr.c \ 36 | ${SRC_DIR}/ft_strrchr.c \ 37 | ${SRC_DIR}/ft_strnstr.c \ 38 | ${SRC_DIR}/ft_strncmp.c \ 39 | ${SRC_DIR}/ft_atoi.c \ 40 | ${SRC_DIR}/ft_isalpha.c \ 41 | ${SRC_DIR}/ft_isdigit.c \ 42 | ${SRC_DIR}/ft_isalnum.c \ 43 | ${SRC_DIR}/ft_isalnum_or_uscore.c \ 44 | ${SRC_DIR}/ft_isascii.c \ 45 | ${SRC_DIR}/ft_isprint.c \ 46 | ${SRC_DIR}/ft_toupper.c \ 47 | ${SRC_DIR}/ft_tolower.c \ 48 | ${SRC_DIR}/ft_calloc.c \ 49 | ${SRC_DIR}/ft_strdup.c \ 50 | ${SRC_DIR}/ft_substr.c \ 51 | ${SRC_DIR}/ft_strjoin.c \ 52 | ${SRC_DIR}/ft_strtrim.c \ 53 | ${SRC_DIR}/ft_strreplace.c \ 54 | ${SRC_DIR}/ft_split.c \ 55 | ${SRC_DIR}/ft_itoa.c \ 56 | ${SRC_DIR}/ft_strmapi.c \ 57 | ${SRC_DIR}/ft_putchar_fd.c \ 58 | ${SRC_DIR}/ft_putstr_fd.c \ 59 | ${SRC_DIR}/ft_putendl_fd.c \ 60 | ${SRC_DIR}/ft_putnbr_fd.c \ 61 | ${SRC_DIR}/ft_lstnew.c \ 62 | ${SRC_DIR}/ft_lstadd_front.c\ 63 | ${SRC_DIR}/ft_lstsize.c \ 64 | ${SRC_DIR}/ft_lstfirst.c \ 65 | ${SRC_DIR}/ft_lstlast.c \ 66 | ${SRC_DIR}/ft_lstadd_back.c \ 67 | ${SRC_DIR}/ft_lstdelone.c \ 68 | ${SRC_DIR}/ft_lstclear.c \ 69 | ${SRC_DIR}/ft_lstiter.c \ 70 | ${SRC_DIR}/ft_lstmap.c \ 71 | ${SRC_DIR}/ft_isspace.c \ 72 | ${SRC_DIR}/get_next_line.c 73 | 74 | OBJ_DIR = . 75 | OBJ = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRC)) 76 | 77 | all: $(NAME) 78 | 79 | $(NAME): $(OBJ) 80 | ar rcs $@ $^ 81 | 82 | $(OBJ_DIR)/%.o: $(SRC_DIR)/%.c 83 | $(CC) $(CC_FLAGS) -c -I$(INCLUDES) $< -o $@ 84 | 85 | clean: 86 | $(RM) $(OBJ) 87 | 88 | fclean: clean 89 | $(RM) $(NAME) 90 | 91 | re: fclean all 92 | 93 | test: all 94 | $(MAKE) -C test 95 | -------------------------------------------------------------------------------- /libft/include/get_next_line.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_next_line.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/02/14 11:12:57 by aroque #+# #+# */ 9 | /* Updated: 2020/09/15 11:59:07 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef GET_NEXT_LINE_H 14 | # define GET_NEXT_LINE_H 15 | 16 | # include 17 | # include 18 | # include 19 | 20 | # define GNL_SUCCESS 1 21 | # define GNL_FAILURE -1 22 | # define GNL_EOF 0 23 | 24 | # define LBREAK '\n' 25 | # define STR_EMPTY "" 26 | 27 | # define OPEN_MAX 16 28 | # define BUFFER_SIZE 1024 29 | 30 | int get_next_line(int fd, char **line); 31 | 32 | /* 33 | ** ░░░░░░░█▐▓▓░████▄▄▄█▀▄▓▓▓▌█ 34 | ** ░░░░░▄█▌▀▄▓▓▄▄▄▄▀▀▀▄▓▓▓▓▓▌█ 35 | ** ░░░▄█▀▀▄▓█▓▓▓▓▓▓▓▓▓▓▓▓▀░▓▌█ 36 | ** ░░█▀▄▓▓▓███▓▓▓███▓▓▓▄░░▄▓▐█▌ 37 | ** ░█▌▓▓▓▀▀▓▓▓▓███▓▓▓▓▓▓▓▄▀▓▓▐█ 38 | ** ▐█▐██▐░▄▓▓▓▓▓▀▄░▀▓▓▓▓▓▓▓▓▓▌█▌ 39 | ** █▌███▓▓▓▓▓▓▓▓▐░░▄▓▓███▓▓▓▄▀▐█ 40 | ** █▐█▓▀░░▀▓▓▓▓▓▓▓▓▓██████▓▓▓▓▐█ 41 | ** ▌▓▄▌▀░▀░▐▀█▄▓▓██████████▓▓▓▌█▌ 42 | ** ▌▓▓▓▄▄▀▀▓▓▓▀▓▓▓▓▓▓▓▓█▓█▓█▓▓▌█▌ 43 | ** █▐▓▓▓▓▓▓▄▄▄▓▓▓▓▓▓█▓█▓█▓█▓▓▓▐█ 44 | */ 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /libft/include/libft.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* libft.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/20 11:24:25 by aroque #+# #+# */ 9 | /* Updated: 2021/04/04 22:30:51 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef LIBFT_H 14 | # define LIBFT_H 15 | 16 | # include 17 | # include 18 | 19 | /* 20 | ** ---------------------- 21 | ** --- Libc Functions --- 22 | ** ---------------------- 23 | */ 24 | 25 | void ft_bzero(void *s, size_t n); 26 | void *ft_memset(void *b, int c, size_t len); 27 | int ft_atoi(const char *str); 28 | void *ft_memcpy(void *dst, const void *src, size_t n); 29 | void *ft_memccpy(void *dst, const void *src, int c, size_t n); 30 | void *ft_memmove(void *dst, const void *src, size_t len); 31 | void *ft_memchr(const void *s, int c, size_t n); 32 | int ft_memcmp(const void *s1, const void *s2, size_t n); 33 | int ft_strncmp(const char *s1, const char *s2, size_t n); 34 | size_t ft_strlen(const char *s); 35 | size_t ft_strlcpy(char *dst, const char *src, size_t dstsize); 36 | size_t ft_strlcat(char *dst, const char *src, size_t dstsize); 37 | char *ft_strchr(const char *s, int c); 38 | char *ft_strrchr(const char *s, int c); 39 | char *ft_strnstr(const char *haystack, 40 | const char *needle, size_t len); 41 | char *ft_strdup(const char *s1); 42 | void *ft_calloc(size_t count, size_t size); 43 | int ft_isalpha(int c); 44 | int ft_isdigit(int c); 45 | int ft_isalnum(int c); 46 | int ft_isascii(int c); 47 | int ft_isprint(int c); 48 | int ft_toupper(int c); 49 | int ft_tolower(int c); 50 | int ft_atoi(const char *str); 51 | 52 | /* 53 | ** ---------------------------- 54 | ** --- Additional Functions --- 55 | ** ---------------------------- 56 | */ 57 | 58 | char *ft_itoa(int n); 59 | char *ft_substr(char const *s, unsigned int start, size_t len); 60 | char *ft_strjoin(char const *s1, char const *s2); 61 | char *ft_strtrim(char const *s1, char const *set); 62 | char *ft_strmapi(char const *s, char (*f)(unsigned int, char)); 63 | char **ft_split(char const *s, char c); 64 | void ft_putchar_fd(char const c, int fd); 65 | void ft_putstr_fd(char const *s, int fd); 66 | void ft_putendl_fd(char *s, int fd); 67 | void ft_putnbr_fd(int n, int fd); 68 | 69 | /* 70 | ** ----------------------------- 71 | ** --- Linked List Functions --- 72 | ** ----------------------------- 73 | */ 74 | 75 | typedef struct s_list 76 | { 77 | void *content; 78 | struct s_list *previous; 79 | struct s_list *next; 80 | } t_list; 81 | 82 | t_list *ft_lstnew(void *content); 83 | void ft_lstadd_front(t_list **lst, t_list *new); 84 | void ft_lstadd_back(t_list **lst, t_list *new); 85 | int ft_lstsize(t_list *lst); 86 | t_list *ft_lstfirst(t_list *lst); 87 | t_list *ft_lstlast(t_list *lst); 88 | void ft_lstdelone(t_list *lst, void (*del)(void*)); 89 | void ft_lstclear(t_list **lst, void (*del)(void*)); 90 | void ft_lstiter(t_list *lst, void (*f)(void *)); 91 | t_list *ft_lstmap(t_list *lst, void *(*f)(void *), 92 | void (*del)(void *)); 93 | 94 | /* 95 | ** ----------------------- 96 | ** --- Other Functions --- 97 | ** ----------------------- 98 | */ 99 | 100 | int ft_isspace(char str); 101 | size_t ft_strspn(const char *s, const char *accept); 102 | size_t ft_strcspn(const char *s, const char *reject); 103 | char *ft_strtok(char *str, const char *delim); 104 | char *ft_strtok_r(char *str, const char *delim, char **ptr); 105 | char *ft_strreplace(char **str, const char *s, const char *r); 106 | int ft_isalnum_or_uscore(int c); 107 | bool ft_streq(const char *s1, const char *s2); 108 | 109 | /* 110 | ** ░░░░░░░█▐▓▓░████▄▄▄█▀▄▓▓▓▌█ 111 | ** ░░░░░▄█▌▀▄▓▓▄▄▄▄▀▀▀▄▓▓▓▓▓▌█ 112 | ** ░░░▄█▀▀▄▓█▓▓▓▓▓▓▓▓▓▓▓▓▀░▓▌█ 113 | ** ░░█▀▄▓▓▓███▓▓▓███▓▓▓▄░░▄▓▐█▌ 114 | ** ░█▌▓▓▓▀▀▓▓▓▓███▓▓▓▓▓▓▓▄▀▓▓▐█ 115 | ** ▐█▐██▐░▄▓▓▓▓▓▀▄░▀▓▓▓▓▓▓▓▓▓▌█▌ 116 | ** █▌███▓▓▓▓▓▓▓▓▐░░▄▓▓███▓▓▓▄▀▐█ 117 | ** █▐█▓▀░░▀▓▓▓▓▓▓▓▓▓██████▓▓▓▓▐█ 118 | ** ▌▓▄▌▀░▀░▐▀█▄▓▓██████████▓▓▓▌█▌ 119 | ** ▌▓▓▓▄▄▀▀▓▓▓▀▓▓▓▓▓▓▓▓█▓█▓█▓▓▌█▌ 120 | ** █▐▓▓▓▓▓▓▄▄▄▓▓▓▓▓▓█▓█▓█▓█▓▓▓▐█ 121 | */ 122 | 123 | #endif 124 | -------------------------------------------------------------------------------- /libft/src/ft_atoi.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_atoi.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/20 11:14:54 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:31:04 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | /* 16 | ** Converts a string of characters to integer. An arbitrary amount 17 | ** of white spaces can be added at string start, followed by any 18 | ** amount of '+' or '-' signals. An even number of '-' cancels each 19 | ** other. The conversion is then made while the following chars are 20 | ** numeric, stopping at any other char identified. If no numeric char 21 | ** os identified, the function returns 0 (zero). 22 | */ 23 | 24 | int ft_atoi(const char *str) 25 | { 26 | int n; 27 | int aux; 28 | int signal; 29 | 30 | n = 0; 31 | aux = 0; 32 | signal = -1; 33 | while (ft_isspace(*str)) 34 | str++; 35 | if (*str == '+' || *str == '-') 36 | if (*str++ == '-') 37 | signal = 1; 38 | while (*str >= '0' && *str <= '9') 39 | { 40 | n = n * 10 - (*str++ - '0'); 41 | if (aux < n) 42 | { 43 | if (signal < 0) 44 | return (-1); 45 | return (0); 46 | } 47 | aux = n; 48 | } 49 | return (n * signal); 50 | } 51 | -------------------------------------------------------------------------------- /libft/src/ft_bzero.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_bzero.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/20 19:14:59 by aroque #+# #+# */ 9 | /* Updated: 2020/01/21 16:18:03 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_bzero(void *s, size_t n) 16 | { 17 | ft_memset(s, 0, n); 18 | } 19 | -------------------------------------------------------------------------------- /libft/src/ft_calloc.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_calloc.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 14:06:33 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:45:52 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_calloc(size_t count, size_t size) 16 | { 17 | void *ptr; 18 | 19 | ptr = malloc(count * size); 20 | if (!ptr) 21 | return (NULL); 22 | ft_bzero(ptr, count * size); 23 | return (ptr); 24 | } 25 | -------------------------------------------------------------------------------- /libft/src/ft_isalnum.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isalnum.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 13:49:43 by aroque #+# #+# */ 9 | /* Updated: 2020/01/22 13:51:25 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_isalnum(int c) 16 | { 17 | if (ft_isalpha(c) || ft_isdigit(c)) 18 | return (1); 19 | else 20 | return (0); 21 | } 22 | -------------------------------------------------------------------------------- /libft/src/ft_isalpha.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isalpha.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 13:32:12 by aroque #+# #+# */ 9 | /* Updated: 2020/01/24 22:13:47 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_isalpha(int c) 14 | { 15 | return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); 16 | } 17 | -------------------------------------------------------------------------------- /libft/src/ft_isascii.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isascii.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 13:52:14 by aroque #+# #+# */ 9 | /* Updated: 2020/01/23 19:30:30 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_isascii(int c) 14 | { 15 | if (c >= 0000 && c <= 0177) 16 | return (1); 17 | return (0); 18 | } 19 | -------------------------------------------------------------------------------- /libft/src/ft_isdigit.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isdigit.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 13:43:06 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:45:19 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_isdigit(int c) 14 | { 15 | return (c >= '0' && c <= '9'); 16 | } 17 | -------------------------------------------------------------------------------- /libft/src/ft_isprint.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isprint.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 13:56:34 by aroque #+# #+# */ 9 | /* Updated: 2020/01/22 13:58:33 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_isprint(int c) 14 | { 15 | if (c >= 0040 && c <= 0176) 16 | return (1); 17 | return (0); 18 | } 19 | -------------------------------------------------------------------------------- /libft/src/ft_isspace.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isspace.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/09/11 23:21:57 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:45:16 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | /* 14 | ** Check if a char is ASCII space, tabulation, carriage return 15 | ** or another space character as defined in isspace(3). 16 | */ 17 | 18 | int ft_isspace(char str) 19 | { 20 | return (str == 0x20 || (str >= 0x09 && str <= 0x0d)); 21 | } 22 | -------------------------------------------------------------------------------- /libft/src/ft_itoa.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_itoa.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 09:55:56 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:44:54 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | static size_t ft_digit_counter(int n) 16 | { 17 | if (!(n / 10)) 18 | return (1); 19 | else 20 | return (ft_digit_counter(n / 10) + 1); 21 | } 22 | 23 | /* 24 | ** Convert an int to its string 25 | ** representation. 26 | */ 27 | 28 | char *ft_itoa(int n) 29 | { 30 | unsigned int nbr; 31 | size_t len; 32 | char *s; 33 | 34 | len = ft_digit_counter(n); 35 | if (n < 0) 36 | { 37 | nbr = -(unsigned int)n; 38 | len++; 39 | } 40 | else 41 | nbr = (unsigned int)n; 42 | s = malloc((len + 1) * sizeof(*s)); 43 | if (!s) 44 | return (NULL); 45 | s[len] = '\0'; 46 | while (len--) 47 | { 48 | s[len] = nbr % 10 + '0'; 49 | nbr = nbr / 10; 50 | } 51 | if (n < 0) 52 | s[0] = '-'; 53 | return (s); 54 | } 55 | -------------------------------------------------------------------------------- /libft/src/ft_lstadd_back.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstadd_back.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 18:39:17 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:35:55 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | /* 16 | ** Push new element to the linked list 17 | ** end, without changing its head. 18 | */ 19 | 20 | void ft_lstadd_back(t_list **lst, t_list *new) 21 | { 22 | t_list *last; 23 | 24 | if (!*lst) 25 | *lst = new; 26 | else 27 | { 28 | last = ft_lstlast(*lst); 29 | new->previous = last; 30 | last->next = new; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /libft/src/ft_lstadd_front.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstadd_front.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 17:00:06 by aroque #+# #+# */ 9 | /* Updated: 2020/01/23 23:35:29 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_lstadd_front(t_list **lst, t_list *new) 16 | { 17 | new->next = *lst; 18 | *lst = new; 19 | } 20 | -------------------------------------------------------------------------------- /libft/src/ft_lstclear.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstclear.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/23 20:18:37 by aroque #+# #+# */ 9 | /* Updated: 2020/09/13 15:27:31 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | /* 16 | ** This function completely erases a linked 17 | ** list t_list with a delete function (*del), 18 | ** which deletes the content of the node. The 19 | ** head then returns as a NULL pointer. 20 | */ 21 | 22 | void ft_lstclear(t_list **lst, void (*del)(void*)) 23 | { 24 | if (!(*lst)) 25 | return ; 26 | if ((*lst)->next) 27 | ft_lstclear(&(*lst)->next, del); 28 | ft_lstdelone(*lst, del); 29 | *lst = NULL; 30 | } 31 | -------------------------------------------------------------------------------- /libft/src/ft_lstdelone.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstdelone.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/23 19:22:00 by aroque #+# #+# */ 9 | /* Updated: 2020/01/23 22:16:20 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | /* 16 | ** Deletes the content of a linked 17 | ** list node. The node may be passed 18 | ** by reference for test purposes. 19 | */ 20 | 21 | void ft_lstdelone(t_list *lst, void (*del)(void*)) 22 | { 23 | del(lst->content); 24 | free(lst); 25 | } 26 | -------------------------------------------------------------------------------- /libft/src/ft_lstfirst.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstfirst.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/08/16 17:42:24 by aroque #+# #+# */ 9 | /* Updated: 2020/08/16 17:49:30 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | /* 16 | ** Returns the first element 17 | ** of the linked list lst. 18 | */ 19 | 20 | t_list *ft_lstfirst(t_list *lst) 21 | { 22 | if (!lst) 23 | return (NULL); 24 | else if (!(lst->previous)) 25 | return (lst); 26 | return (ft_lstfirst(lst->previous)); 27 | } 28 | -------------------------------------------------------------------------------- /libft/src/ft_lstiter.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstiter.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/23 22:16:59 by aroque #+# #+# */ 9 | /* Updated: 2020/01/24 15:28:36 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | /* 16 | ** Iterates over all list elements, 17 | ** applying the f function to each 18 | ** element content. 19 | */ 20 | 21 | void ft_lstiter(t_list *lst, void (*f)(void *)) 22 | { 23 | if (lst) 24 | { 25 | f(lst->content); 26 | ft_lstiter(lst->next, f); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /libft/src/ft_lstlast.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstlast.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 17:49:08 by aroque #+# #+# */ 9 | /* Updated: 2020/01/25 22:13:03 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | /* 16 | ** Returns the last element 17 | ** of the linked list lst. 18 | */ 19 | 20 | t_list *ft_lstlast(t_list *lst) 21 | { 22 | if (!lst) 23 | return (NULL); 24 | else if (!(lst->next)) 25 | return (lst); 26 | return (ft_lstlast(lst->next)); 27 | } 28 | -------------------------------------------------------------------------------- /libft/src/ft_lstmap.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstmap.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/23 22:22:05 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:44:16 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *)) 16 | { 17 | t_list *map; 18 | 19 | if (!lst) 20 | return (NULL); 21 | else 22 | { 23 | map = ft_lstnew(f(lst->content)); 24 | if (!map) 25 | { 26 | ft_lstclear(&map, del); 27 | return (NULL); 28 | } 29 | map->next = ft_lstmap(lst->next, f, del); 30 | return (map); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /libft/src/ft_lstnew.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstnew.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 16:46:42 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:43:46 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | t_list *ft_lstnew(void *content) 16 | { 17 | t_list *lst; 18 | 19 | lst = malloc(sizeof(t_list)); 20 | if (!lst) 21 | return (0); 22 | lst->content = content; 23 | lst->previous = NULL; 24 | lst->next = NULL; 25 | return (lst); 26 | } 27 | -------------------------------------------------------------------------------- /libft/src/ft_lstsize.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_lstsize.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 17:15:57 by aroque #+# #+# */ 9 | /* Updated: 2020/01/22 17:42:27 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_lstsize(t_list *lst) 16 | { 17 | if (!lst) 18 | return (0); 19 | return (ft_lstsize(lst->next) + 1); 20 | } 21 | -------------------------------------------------------------------------------- /libft/src/ft_memccpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memccpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/20 20:04:31 by aroque #+# #+# */ 9 | /* Updated: 2020/01/22 16:29:11 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memccpy(void *dst, const void *src, int c, size_t n) 16 | { 17 | size_t i; 18 | unsigned char *s; 19 | unsigned char *d; 20 | 21 | i = -1; 22 | s = (unsigned char *)src; 23 | d = (unsigned char *)dst; 24 | while (++i < n) 25 | { 26 | d[i] = s[i]; 27 | if (s[i] == (unsigned char)c) 28 | return (dst + i + 1); 29 | } 30 | return (0); 31 | } 32 | -------------------------------------------------------------------------------- /libft/src/ft_memchr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memchr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/21 20:24:23 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:35:33 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memchr(const void *s, int c, size_t n) 16 | { 17 | if (!n) 18 | return (0); 19 | else if (*(unsigned char *)s == (unsigned char)c) 20 | return ((void *)s); 21 | return (ft_memchr(++s, c, --n)); 22 | } 23 | -------------------------------------------------------------------------------- /libft/src/ft_memcmp.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memcmp.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/21 22:47:51 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:41:57 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_memcmp(const void *s1, const void *s2, size_t n) 16 | { 17 | unsigned char *c1; 18 | unsigned char *c2; 19 | 20 | c1 = (unsigned char *)s1; 21 | c2 = (unsigned char *)s2; 22 | if (!n) 23 | return (0); 24 | else if (*c1 != *c2) 25 | return (*c1 - *c2); 26 | return (ft_memcmp(++s1, ++s2, --n)); 27 | } 28 | -------------------------------------------------------------------------------- /libft/src/ft_memcpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memcpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/20 19:23:00 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:42:28 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memcpy(void *dst, const void *src, size_t n) 16 | { 17 | unsigned char *s; 18 | unsigned char *d; 19 | 20 | s = (unsigned char *)src; 21 | d = (unsigned char *)dst; 22 | while (n-- && dst != src) 23 | *d++ = *s++; 24 | return (dst); 25 | } 26 | -------------------------------------------------------------------------------- /libft/src/ft_memmove.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memmove.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/21 17:53:39 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:40:19 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memmove(void *dst, const void *src, size_t len) 16 | { 17 | unsigned char *d; 18 | unsigned char *s; 19 | 20 | d = (unsigned char *)dst; 21 | s = (unsigned char *)src; 22 | if (d < s) 23 | return (ft_memcpy(dst, src, len)); 24 | else 25 | while (len-- && dst != src) 26 | d[len] = s[len]; 27 | return (dst); 28 | } 29 | -------------------------------------------------------------------------------- /libft/src/ft_memset.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memset.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/20 17:00:16 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:41:52 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memset(void *b, int c, size_t len) 16 | { 17 | unsigned char *ptr; 18 | 19 | ptr = (unsigned char *)b; 20 | while (len--) 21 | *ptr++ = (unsigned char)c; 22 | return (b); 23 | } 24 | -------------------------------------------------------------------------------- /libft/src/ft_putchar_fd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_putchar_fd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 11:27:22 by aroque #+# #+# */ 9 | /* Updated: 2020/12/29 11:05:18 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | 15 | void ft_putchar_fd(const char c, int fd) 16 | { 17 | write(fd, &c, 1); 18 | } 19 | -------------------------------------------------------------------------------- /libft/src/ft_putendl_fd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_putendl_fd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 11:30:44 by aroque #+# #+# */ 9 | /* Updated: 2020/01/22 11:37:22 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_putendl_fd(char *s, int fd) 16 | { 17 | ft_putstr_fd(s, fd); 18 | ft_putchar_fd('\n', fd); 19 | } 20 | -------------------------------------------------------------------------------- /libft/src/ft_putnbr_fd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_putnbr_fd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 11:37:51 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:41:41 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_putnbr_fd(int n, int fd) 16 | { 17 | unsigned int nb; 18 | 19 | nb = 0; 20 | if (n < 0) 21 | { 22 | ft_putchar_fd('-', fd); 23 | nb = -n; 24 | } 25 | else 26 | nb = n; 27 | if (nb >= 10) 28 | ft_putnbr_fd(nb / 10, fd); 29 | ft_putchar_fd((nb % 10) + '0', fd); 30 | } 31 | -------------------------------------------------------------------------------- /libft/src/ft_putstr_fd.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_putstr_fd.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 11:28:59 by aroque #+# #+# */ 9 | /* Updated: 2020/12/29 11:05:25 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void ft_putstr_fd(const char *s, int fd) 16 | { 17 | if (!s) 18 | return ; 19 | if (*s) 20 | { 21 | ft_putchar_fd(*s, fd); 22 | ft_putstr_fd(++s, fd); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /libft/src/ft_split.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_split.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 06:04:57 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:38:59 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | /* 16 | ** Count how many words a string has, 17 | ** with character c as a space character. 18 | */ 19 | 20 | static int word_count(const char *str, char c) 21 | { 22 | int i; 23 | int trigger; 24 | 25 | i = 0; 26 | trigger = 0; 27 | while (*str) 28 | { 29 | if (*str != c && trigger == 0) 30 | { 31 | trigger = 1; 32 | i++; 33 | } 34 | else if (*str == c) 35 | trigger = 0; 36 | str++; 37 | } 38 | return (i); 39 | } 40 | 41 | /* 42 | ** Returns a substring from str, with 43 | ** char zero at index start and finishing 44 | ** the copy at index finish. 45 | */ 46 | 47 | static char *word_dup(const char *str, int start, int finish) 48 | { 49 | char *word; 50 | int i; 51 | 52 | i = 0; 53 | word = malloc((finish - start + 1) * sizeof(char)); 54 | while (start < finish) 55 | word[i++] = str[start++]; 56 | word[i] = '\0'; 57 | return (word); 58 | } 59 | 60 | /* 61 | ** Split a string into one or more substrings, 62 | ** returning an array of substrings. The split 63 | ** is made according the separator c. 64 | */ 65 | 66 | char **ft_split(char const *s, char c) 67 | { 68 | size_t i; 69 | size_t j; 70 | int index; 71 | char **split; 72 | 73 | i = 0; 74 | j = 0; 75 | index = -1; 76 | split = malloc((word_count(s, c) + 1) * sizeof(*split)); 77 | if (!split) 78 | return (NULL); 79 | while (i <= ft_strlen(s)) 80 | { 81 | if (s[i] != c && index < 0) 82 | index = i; 83 | else if ((s[i] == c || i == ft_strlen(s)) && index >= 0) 84 | { 85 | split[j++] = word_dup(s, index, i); 86 | index = -1; 87 | } 88 | i++; 89 | } 90 | split[j] = NULL; 91 | return (split); 92 | } 93 | -------------------------------------------------------------------------------- /libft/src/ft_strchr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strchr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 13:03:15 by aroque #+# #+# */ 9 | /* Updated: 2020/01/22 13:30:43 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strchr(const char *s, int c) 16 | { 17 | if (*s == (char)c) 18 | return ((char *)s); 19 | else if (!*s) 20 | return (0); 21 | else 22 | return (ft_strchr(++s, c)); 23 | } 24 | -------------------------------------------------------------------------------- /libft/src/ft_strcspn.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strcspn.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/01/03 23:21:03 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:41:26 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | size_t ft_strcspn(const char *s, const char *reject) 16 | { 17 | size_t i; 18 | size_t n; 19 | 20 | i = 0; 21 | n = ft_strlen(reject) + 1; 22 | while (!ft_memchr(reject, s[i], n)) 23 | i++; 24 | return (i); 25 | } 26 | -------------------------------------------------------------------------------- /libft/src/ft_strdup.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strdup.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 14:09:14 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:41:07 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strdup(const char *s1) 16 | { 17 | int i; 18 | char *s; 19 | 20 | i = -1; 21 | s = malloc((ft_strlen(s1) + 1) * sizeof(*s)); 22 | if (!s1 || !s) 23 | return (NULL); 24 | while (s1[++i]) 25 | s[i] = s1[i]; 26 | s[i] = '\0'; 27 | return (s); 28 | } 29 | -------------------------------------------------------------------------------- /libft/src/ft_streq.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_streq.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/03/06 18:58:33 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:31:32 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include "libft.h" 15 | 16 | bool ft_streq(const char *s1, const char *s2) 17 | { 18 | return (!(ft_strncmp(s1, s2, ft_strlen(s2) + 1))); 19 | } 20 | -------------------------------------------------------------------------------- /libft/src/ft_strjoin.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strjoin.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 02:30:11 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:37:39 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strjoin(char const *s1, char const *s2) 16 | { 17 | int i; 18 | int len1; 19 | int len2; 20 | char *join; 21 | 22 | if (!s1 || !s2) 23 | return (NULL); 24 | i = -1; 25 | len1 = ft_strlen(s1); 26 | len2 = ft_strlen(s2); 27 | join = malloc((len1 + len2 + 1) * sizeof(*join)); 28 | if (!join) 29 | return (NULL); 30 | while (s1[++i]) 31 | join[i] = s1[i]; 32 | i = -1; 33 | while (s2[++i]) 34 | join[len1++] = s2[i]; 35 | join[len1] = '\0'; 36 | return (join); 37 | } 38 | -------------------------------------------------------------------------------- /libft/src/ft_strlcat.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlcat.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 11:44:53 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:40:38 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | size_t ft_strlcat(char *dst, const char *src, size_t dstsize) 16 | { 17 | size_t len; 18 | size_t i; 19 | 20 | i = 0; 21 | len = ft_strlen(src); 22 | while (*dst && dstsize) 23 | { 24 | dst++; 25 | dstsize--; 26 | i++; 27 | } 28 | while (*src && dstsize > 1) 29 | { 30 | *dst++ = *src++; 31 | dstsize--; 32 | } 33 | if (dstsize) 34 | *dst++ = '\0'; 35 | return (i + len); 36 | } 37 | -------------------------------------------------------------------------------- /libft/src/ft_strlcpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlcpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/02 14:47:01 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:40:32 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | size_t ft_strlcpy(char *dst, const char *src, size_t dstsize) 16 | { 17 | size_t i; 18 | 19 | if (!src) 20 | return (0); 21 | i = -1; 22 | if (dstsize) 23 | { 24 | while (src[++i] && i < dstsize - 1) 25 | dst[i] = src[i]; 26 | dst[i] = '\0'; 27 | } 28 | return (ft_strlen(src)); 29 | } 30 | -------------------------------------------------------------------------------- /libft/src/ft_strlen.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlen.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/20 11:21:14 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:34:53 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | /* 16 | ** Returns the number of characters of 17 | ** nul-terminated string. 18 | */ 19 | 20 | size_t ft_strlen(const char *s) 21 | { 22 | if (!*s) 23 | return (0); 24 | return (ft_strlen(s + 1) + 1); 25 | } 26 | -------------------------------------------------------------------------------- /libft/src/ft_strmapi.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strmapi.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 11:11:42 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:40:00 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strmapi(char const *s, char (*f)(unsigned int, char)) 16 | { 17 | size_t i; 18 | char *map; 19 | 20 | if (!s) 21 | return (NULL); 22 | i = -1; 23 | map = malloc((ft_strlen(s) + 1) * sizeof(*map)); 24 | if (!map) 25 | return (NULL); 26 | while (++i < ft_strlen(s)) 27 | map[i] = f(i, s[i]); 28 | map[i] = '\0'; 29 | return (map); 30 | } 31 | -------------------------------------------------------------------------------- /libft/src/ft_strncmp.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strncmp.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2019/12/03 20:29:51 by aroque #+# #+# */ 9 | /* Updated: 2021/02/03 22:10:47 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_strncmp(const char *s1, const char *s2, size_t n) 16 | { 17 | if (!n) 18 | return (0); 19 | else if ((*s1 != *s2) || !*s1) 20 | return ((unsigned char)*s1 - (unsigned char)*s2); 21 | return (ft_strncmp(++s1, ++s2, --n)); 22 | } 23 | -------------------------------------------------------------------------------- /libft/src/ft_strnstr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strnstr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/20 13:12:52 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:39:40 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strnstr(const char *haystack, const char *needle, size_t len) 16 | { 17 | size_t needle_len; 18 | 19 | needle_len = ft_strlen(needle); 20 | if (!needle_len) 21 | return ((char *)haystack); 22 | while (*haystack && len >= needle_len) 23 | { 24 | if (!ft_strncmp(haystack, needle, needle_len)) 25 | return ((char *)haystack); 26 | haystack++; 27 | len--; 28 | } 29 | return (NULL); 30 | } 31 | -------------------------------------------------------------------------------- /libft/src/ft_strrchr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strrchr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 13:22:43 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:39:24 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strrchr(const char *s, int c) 16 | { 17 | size_t len; 18 | 19 | len = ft_strlen(s) + 1; 20 | while (len--) 21 | { 22 | if (s[len] == c) 23 | return ((char *)(s + len)); 24 | } 25 | return (NULL); 26 | } 27 | -------------------------------------------------------------------------------- /libft/src/ft_strreplace.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strreplace.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/01/31 16:40:32 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:33:08 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | static void replace_s(char **newstr, char *p, const char *r, size_t slen) 16 | { 17 | char *old; 18 | size_t olen; 19 | size_t rlen; 20 | 21 | old = *newstr; 22 | olen = ft_strlen(old); 23 | rlen = ft_strlen(r); 24 | *newstr = malloc((olen - slen + rlen + 1) * sizeof(*newstr)); 25 | if (*newstr == NULL) 26 | { 27 | free(old); 28 | return ; 29 | } 30 | ft_memcpy(*newstr, old, p - old); 31 | ft_memcpy(*newstr + (p - old), r, rlen); 32 | ft_memcpy(*newstr + (p - old) + rlen, p + slen, olen - slen - (p - old)); 33 | ft_memset(*newstr + olen - slen + rlen, 0, 1); 34 | free(old); 35 | } 36 | 37 | char *ft_strreplace(char **s, const char *search, const char *replace) 38 | { 39 | char *p; 40 | char *newstr; 41 | size_t search_len; 42 | size_t replace_len; 43 | 44 | if (!search || !replace) 45 | return (*s); 46 | newstr = ft_strdup(*s); 47 | search_len = ft_strlen(search); 48 | replace_len = ft_strlen(replace); 49 | p = ft_strnstr(newstr, search, ft_strlen(newstr)); 50 | while (p) 51 | { 52 | p = ft_strnstr(newstr, search, ft_strlen(newstr)); 53 | replace_s(&newstr, p, replace, search_len); 54 | } 55 | free(*s); 56 | *s = newstr; 57 | return (*s); 58 | } 59 | -------------------------------------------------------------------------------- /libft/src/ft_strspn.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strspn.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/01/03 23:20:07 by aroque #+# #+# */ 9 | /* Updated: 2021/01/04 08:53:38 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | size_t ft_strspn(const char *s, const char *accept) 16 | { 17 | size_t i; 18 | size_t n; 19 | 20 | i = 0; 21 | n = ft_strlen(accept); 22 | while (ft_memchr(accept, s[i], n)) 23 | i++; 24 | return (i); 25 | } 26 | -------------------------------------------------------------------------------- /libft/src/ft_strtok.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strtok.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/01/04 00:06:48 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:36:18 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strtok(char *str, const char *delim) 16 | { 17 | static char *olds; 18 | 19 | return (ft_strtok_r(str, delim, &olds)); 20 | } 21 | -------------------------------------------------------------------------------- /libft/src/ft_strtok_r.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strtok_r.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/01/04 00:05:28 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:42:13 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strtok_r(char *str, const char *delim, char **save_ptr) 16 | { 17 | char *end; 18 | 19 | if (str == NULL) 20 | str = *save_ptr; 21 | if (*str == '\0') 22 | { 23 | *save_ptr = str; 24 | return (NULL); 25 | } 26 | str += ft_strspn(str, delim); 27 | if (*str == '\0') 28 | { 29 | *save_ptr = str; 30 | return (NULL); 31 | } 32 | end = str + ft_strcspn(str, delim); 33 | if (*end == '\0') 34 | { 35 | *save_ptr = end; 36 | return (str); 37 | } 38 | *end = '\0'; 39 | *save_ptr = end + 1; 40 | return (str); 41 | } 42 | -------------------------------------------------------------------------------- /libft/src/ft_strtrim.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strtrim.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 03:55:14 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:43:21 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | static int ft_charset(char c, char const *set) 16 | { 17 | if (!*set) 18 | return (0); 19 | else if (c == *set) 20 | return (1); 21 | else 22 | return (ft_charset(c, ++set)); 23 | } 24 | 25 | static int ft_left_trim(char const *s1, char const *set) 26 | { 27 | if (!(*s1 && ft_charset(*(char *)s1, set))) 28 | return (0); 29 | else 30 | return (ft_left_trim(++s1, set) + 1); 31 | } 32 | 33 | static int ft_right_trim(char const *s1, char const *set, size_t len) 34 | { 35 | while (s1[len] && ft_charset(s1[len], set)) 36 | len--; 37 | return (len + 1); 38 | } 39 | 40 | char *ft_strtrim(char const *s1, char const *set) 41 | { 42 | char *trim; 43 | int lt; 44 | int rt; 45 | 46 | if (!s1 || !set) 47 | return (NULL); 48 | lt = ft_left_trim(s1, set); 49 | rt = ft_right_trim(s1, set, ft_strlen(s1) - 1); 50 | if (rt < lt) 51 | rt = lt; 52 | trim = malloc((rt - lt + 1) * sizeof(*trim)); 53 | if (!trim) 54 | return (NULL); 55 | ft_strlcpy(trim, &s1[lt], rt - lt + 1); 56 | return (trim); 57 | } 58 | -------------------------------------------------------------------------------- /libft/src/ft_substr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_substr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 02:11:40 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:37:35 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | /* 16 | ** Returns a substring copied from the source 17 | ** string '*s', starting from the 'start' index 18 | ** and copying no more than 'len' bytes. 19 | */ 20 | 21 | char *ft_substr(char const *s, unsigned int start, size_t len) 22 | { 23 | size_t i; 24 | size_t slen; 25 | char *substr; 26 | 27 | if (!s) 28 | return (NULL); 29 | i = 0; 30 | slen = ft_strlen(s); 31 | substr = malloc((len + 1) * sizeof(*substr)); 32 | if (!substr) 33 | return (0); 34 | while ((i < len) && (start + i) < slen) 35 | { 36 | substr[i] = s[start + i]; 37 | i++; 38 | } 39 | substr[i] = '\0'; 40 | return (substr); 41 | } 42 | -------------------------------------------------------------------------------- /libft/src/ft_tolower.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_tolower.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 14:03:19 by aroque #+# #+# */ 9 | /* Updated: 2020/01/22 14:18:49 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_tolower(int c) 14 | { 15 | if (c >= 'A' && c <= 'Z') 16 | return (c + 'a' - 'A'); 17 | return (c); 18 | } 19 | -------------------------------------------------------------------------------- /libft/src/ft_toupper.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_toupper.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/01/22 13:59:00 by aroque #+# #+# */ 9 | /* Updated: 2020/01/22 14:19:10 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | int ft_toupper(int c) 14 | { 15 | if (c >= 'a' && c <= 'z') 16 | return (c - 'a' + 'A'); 17 | return (c); 18 | } 19 | -------------------------------------------------------------------------------- /libft/src/get_next_line.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_next_line.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2020/02/14 11:50:29 by aroque #+# #+# */ 9 | /* Updated: 2021/05/29 18:26:31 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | #include "get_next_line.h" 15 | 16 | static void ft_strdel(char **str) 17 | { 18 | if (str) 19 | { 20 | free(*str); 21 | *str = NULL; 22 | } 23 | } 24 | 25 | static int result(char **line, char **readed_line, int fd, int readed) 26 | { 27 | int len; 28 | char *tmp; 29 | 30 | if (readed < 0) 31 | return (-1); 32 | else if (readed == 0 && readed_line[fd] == NULL && *line) 33 | return (0); 34 | len = 0; 35 | while (readed_line[fd][len] != '\n' && readed_line[fd][len] != '\0') 36 | len++; 37 | if (readed_line[fd][len] == '\n') 38 | { 39 | *line = ft_substr(readed_line[fd], 0, len); 40 | tmp = ft_strdup(&readed_line[fd][len + 1]); 41 | free(readed_line[fd]); 42 | readed_line[fd] = tmp; 43 | if (readed_line[fd][0] == '\0') 44 | ft_strdel(&readed_line[fd]); 45 | return (1); 46 | } 47 | *line = ft_strdup(readed_line[fd]); 48 | ft_strdel(&readed_line[fd]); 49 | return (0); 50 | } 51 | 52 | void paste_line(char **readed_line, char *buff) 53 | { 54 | char *tmp; 55 | 56 | tmp = ft_strjoin(*readed_line, buff); 57 | free(*readed_line); 58 | *readed_line = tmp; 59 | } 60 | 61 | int get_next_line(int fd, char **line) 62 | { 63 | static char *readed_line[OPEN_MAX]; 64 | char *buff; 65 | int readed; 66 | 67 | if (fd < 0 || line == NULL || BUFFER_SIZE < 1) 68 | return (-1); 69 | buff = (char *)malloc((BUFFER_SIZE + 1) * sizeof(char)); 70 | if (!(buff)) 71 | return (-1); 72 | readed = 1; 73 | while (readed > 0) 74 | { 75 | readed = read(fd, buff, BUFFER_SIZE); 76 | buff[readed] = '\0'; 77 | if (!(readed_line[fd])) 78 | readed_line[fd] = ft_strdup(buff); 79 | else 80 | paste_line(&readed_line[fd], buff); 81 | if (ft_strchr(buff, '\n')) 82 | break ; 83 | } 84 | free(buff); 85 | return (result(line, readed_line, fd, readed)); 86 | } 87 | -------------------------------------------------------------------------------- /libstack/include/stack.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* stack.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/03/26 15:30:33 by aroque #+# #+# */ 9 | /* Updated: 2021/05/01 18:19:26 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef STACK_H 14 | # define STACK_H 15 | 16 | # include 17 | # include 18 | 19 | typedef struct s_stack 20 | { 21 | int top; 22 | unsigned int size; 23 | int *array; 24 | } t_stack; 25 | 26 | t_stack *initialize(unsigned int size); 27 | void swap(t_stack *stack); 28 | void push(t_stack *from, t_stack *to); 29 | void rotate(t_stack *stack); 30 | void reverse_rotate(t_stack *stack); 31 | int max(t_stack *stack); 32 | int min(t_stack *stack); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /libstack/src/initialize.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* initialize.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/03/28 14:48:36 by aroque #+# #+# */ 9 | /* Updated: 2021/04/04 22:29:39 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "stack.h" 14 | 15 | t_stack *initialize(unsigned int size) 16 | { 17 | t_stack *stack; 18 | 19 | stack = malloc(sizeof(*stack)); 20 | if (!(stack)) 21 | return (NULL); 22 | stack->array = malloc(size * sizeof(*(stack->array))); 23 | if (!(stack->array)) 24 | return (NULL); 25 | stack->size = size; 26 | stack->top = -1; 27 | return (stack); 28 | } 29 | -------------------------------------------------------------------------------- /libstack/src/max.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* max.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/25 16:29:30 by aroque #+# #+# */ 9 | /* Updated: 2021/04/25 16:31:16 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "stack.h" 14 | 15 | static int _max(int *array, size_t len) 16 | { 17 | int m; 18 | 19 | if (len == 1) 20 | return (array[0]); 21 | m = _max(array, len - 1); 22 | if (array[len - 1] > m) 23 | m = array[len - 1]; 24 | return (m); 25 | } 26 | 27 | int max(t_stack *stack) 28 | { 29 | return (_max(stack->array, stack->top + 1)); 30 | } 31 | -------------------------------------------------------------------------------- /libstack/src/min.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* min.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/05/01 18:15:39 by aroque #+# #+# */ 9 | /* Updated: 2021/05/01 18:16:36 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "stack.h" 14 | 15 | static int _min(int *array, size_t len) 16 | { 17 | int m; 18 | 19 | if (len == 1) 20 | return (array[0]); 21 | m = _min(array, len - 1); 22 | if (array[len - 1] < m) 23 | m = array[len - 1]; 24 | return (m); 25 | } 26 | 27 | int min(t_stack *stack) 28 | { 29 | return (_min(stack->array, stack->top + 1)); 30 | } 31 | -------------------------------------------------------------------------------- /libstack/src/push.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* push.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/03/28 16:25:47 by aroque #+# #+# */ 9 | /* Updated: 2021/03/28 19:01:07 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "stack.h" 14 | 15 | void push(t_stack *from, t_stack *to) 16 | { 17 | if (from->top == -1) 18 | return ; 19 | to->array[++to->top] = from->array[from->top--]; 20 | } 21 | -------------------------------------------------------------------------------- /libstack/src/rotate.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* rotate.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/03/28 18:23:08 by aroque #+# #+# */ 9 | /* Updated: 2021/04/04 22:30:07 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "stack.h" 14 | 15 | void rotate(t_stack *stack) 16 | { 17 | unsigned int i; 18 | int tmp; 19 | 20 | i = stack->top + 1; 21 | tmp = stack->array[stack->top]; 22 | while (--i) 23 | stack->array[i] = stack->array[i - 1]; 24 | stack->array[0] = tmp; 25 | } 26 | 27 | void reverse_rotate(t_stack *stack) 28 | { 29 | int i; 30 | int tmp; 31 | 32 | i = -1; 33 | tmp = stack->array[0]; 34 | while (++i < stack->top) 35 | stack->array[i] = stack->array[i + 1]; 36 | stack->array[stack->top] = tmp; 37 | } 38 | -------------------------------------------------------------------------------- /libstack/src/swap.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* swap.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/03/26 15:23:11 by aroque #+# #+# */ 9 | /* Updated: 2021/03/28 16:20:24 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "stack.h" 14 | 15 | void swap(t_stack *stack) 16 | { 17 | int aux; 18 | 19 | if (stack->top <= 0) 20 | return ; 21 | aux = stack->array[stack->top]; 22 | stack->array[stack->top] = stack->array[stack->top - 1]; 23 | stack->array[stack->top - 1] = aux; 24 | } 25 | -------------------------------------------------------------------------------- /pyviz.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | 4 | from tkinter import * 5 | import sys 6 | import time 7 | import subprocess 8 | import os 9 | from math import sqrt 10 | 11 | 12 | """ 13 | __project__ = "push_swap visualizer" 14 | __author__ = "Emmanuel Ruaud" 15 | __email__ = "eruaud@student.le-101.fr" 16 | This python script was created to visualize your work with the PUSH_SWAP 17 | 42 Project. 18 | You must put this script in the same path or in a sibling path of your program 19 | Of course you need Python3 with the builtin Tkinter. 20 | You can install it with Brew. 21 | --> Brew install python3 22 | Execute the script with : 23 | --> python3 pyviz.py `ruby -e "puts (-200..200).to_a.shuffle.join(' ')"` 24 | You can change the PUSHS_PATH to get to the relative path of your push_swap 25 | You can decrease or increase the speed with the matching buttons. 26 | """ 27 | 28 | 29 | RELATIVE_PATH = r'push_swap' 30 | 31 | 32 | class PsGui: 33 | def __init__(self, master): 34 | ww = 600 35 | wh = 600 36 | self.i = 0 37 | self.speed = 0 38 | dirname = os.path.dirname(os.path.abspath(__file__)) 39 | PUSHS_PATH = os.path.join(dirname, RELATIVE_PATH) 40 | self.pile_a = [int(num) for num in sys.argv[1:]] 41 | self.first_pile = self.pile_a[:] 42 | self.pile_b = [] 43 | self.cmds = subprocess.check_output([PUSHS_PATH] + sys.argv[1:], stderr=subprocess.STDOUT, 44 | timeout=12).splitlines() 45 | self.prespeed = 1 / len(self.pile_a) 46 | self.master = master 47 | master.title("Push_swap viewer") 48 | self.mainframe = Frame(master) 49 | self.mainframe.pack(fill=BOTH) 50 | self.can = Canvas(self.mainframe, width=ww, height=wh, bg="black") 51 | self.can.pack(side=LEFT) 52 | self.toolframe = Frame(self.mainframe) 53 | self.toolframe.pack(side=RIGHT, fill=BOTH) 54 | self.butframe = Frame(self.toolframe) 55 | self.butframe.pack(side=TOP, fill=Y) 56 | self.PrevCtl = Button(self.butframe, text="<<", command=self.speed_down) 57 | self.PrevCtl.pack(side=LEFT) 58 | self.PauseCtl = Button(self.butframe, text=">", command=self.pause) 59 | self.PauseCtl.pack(side=LEFT) 60 | self.NextCtl = Button(self.butframe, text=">>", command=self.speed_up) 61 | self.NextCtl.pack(side=LEFT) 62 | self.ResetCtl = Button(self.butframe, text="R", command=self.reset) 63 | self.ResetCtl.pack(side=LEFT) 64 | self.listbox = Listbox(self.toolframe, bg='black', fg='light cyan', 65 | font=("monospace", 12), relief=FLAT) 66 | self.listbox.pack(fill=BOTH, expand=1) 67 | for cmd in self.cmds: 68 | self.listbox.insert(END, cmd) 69 | self.statusframe = Frame(master) 70 | self.statusframe.pack(side=BOTTOM, fill=X) 71 | self.speedmeter = Label(self.statusframe, 72 | text='frame rate = ' + str(self.speed), 73 | font=("monospace", 10)) 74 | self.speedmeter.pack(side=LEFT) 75 | self.totalcount = Label(self.statusframe, 76 | text='- operations = ' + str(len(self.cmds)), 77 | font=("monospace", 10)) 78 | self.totalcount.pack(side=LEFT) 79 | self.draw_rectangles() 80 | self.launch() 81 | 82 | def reset(self): 83 | self.speed = 0 84 | self.i = 0 85 | del self.pile_a[:] 86 | self.pile_a = self.first_pile[:] 87 | del self.pile_b[:] 88 | self.can.delete("all") 89 | self.draw_rectangles() 90 | self.listbox.see(0) 91 | self.PauseCtl.config(text='>') 92 | self.launch() 93 | 94 | def pause(self): 95 | if self.speed != 0: 96 | self.prespeed = self.speed 97 | self.speed = 0 98 | self.speedmeter.config(text='frame rate = 0') 99 | self.PauseCtl.config(text='>') 100 | else: 101 | self.speed = self.prespeed 102 | self.speedmeter.config(text='frame rate = ' \ 103 | + '{:.2e}'.format(self.speed)) 104 | self.PauseCtl.config(text='||') 105 | 106 | def speed_up(self): 107 | if self.speed == 0: 108 | self.PauseCtl.config(text='||') 109 | self.speed = self.prespeed 110 | self.speed = self.speed ** 2 111 | self.speedmeter.config(text='frame rate = ' \ 112 | + '{:.2e}'.format(self.speed)) 113 | 114 | def speed_down(self): 115 | self.speed = sqrt(self.speed) 116 | self.speedmeter.config(text='frame rate = ' \ 117 | + '{:.2e}'.format(self.speed)) 118 | 119 | def launch_cmds(self, cmd): 120 | if cmd == b'sa' and len(self.pile_a) >= 2: 121 | self.pile_a[0], self.pile_a[1] = self.pile_a[1], self.pile_a[0] 122 | if cmd == b'sb' and len(self.pile_b) >= 2: 123 | self.pile_b[0], self.pile_b[1] = self.pile_b[1], self.pile_b[0] 124 | if cmd == b'ss': 125 | if (len(self.pile_a) >= 2): 126 | self.pile_a[0], self.pile_a[1] = self.pile_a[1], self.pile_a[0] 127 | if (len(self.pile_b) >= 2): 128 | self.pile_b[0], self.pile_b[1] = self.pile_b[1], self.pile_b[0] 129 | if cmd == b'ra' and len(self.pile_a) >= 2: 130 | self.pile_a.append(self.pile_a[0]) 131 | del self.pile_a[0] 132 | if cmd == b'rb' and len(self.pile_b) >= 2: 133 | self.pile_b.append(self.pile_b[0]) 134 | del self.pile_b[0] 135 | if cmd == b'rr': 136 | if (len(self.pile_a) >= 2): 137 | self.pile_a.append(self.pile_a[0]) 138 | del self.pile_a[0] 139 | if (len(self.pile_b) >= 2): 140 | self.pile_b.append(self.pile_b[0]) 141 | del self.pile_b[0] 142 | if cmd == b'rra' and len(self.pile_a) >= 2: 143 | self.pile_a = [self.pile_a[-1]] + self.pile_a 144 | del self.pile_a[-1] 145 | if cmd == b'rrb' and len(self.pile_b) >= 2: 146 | self.pile_b = [self.pile_b[-1]] + self.pile_b 147 | del self.pile_b[-1] 148 | if cmd == b'rrr': 149 | if (len(self.pile_a) >= 2): 150 | self.pile_a = [self.pile_a[-1]] + self.pile_a 151 | del self.pile_a[-1] 152 | if (len(self.pile_b) >= 2): 153 | self.pile_b = [self.pile_b[-1]] + self.pile_b 154 | del self.pile_b[-1] 155 | if cmd == b'pa' and len(self.pile_b) >= 1: 156 | self.pile_a = [self.pile_b[0]] + self.pile_a 157 | del self.pile_b[0] 158 | if cmd == b'pb' and len(self.pile_a) >= 1: 159 | self.pile_b = [self.pile_a[0]] + self.pile_b 160 | del self.pile_a[0] 161 | return self.pile_a, self.pile_b 162 | 163 | def set_color(self, index): 164 | col = '#%02x%02x%02x' % (int(255 * (index - 0.3) * (index > 0.3)), 165 | int(255 * index 166 | - ((510 * (index - 0.6)) * (index > 0.6))), 167 | int((255 - 510 * index) * (index < 0.5))) 168 | return col 169 | 170 | def draw_rectangles(self): 171 | vi = 0 172 | ww = 600 173 | wh = 600 174 | hw = ww / 2 175 | hm = len(self.pile_a) + len(self.pile_b) 176 | mx = max(self.pile_a + self.pile_b) 177 | mn = min(self.pile_a + self.pile_b) 178 | rects = [] 179 | if len(self.pile_a) > 0: 180 | a_val = [(num - mn) / (mx - mn) for num in self.pile_a] 181 | for vala in a_val: 182 | rects.append(self.can.create_rectangle(0, vi, 183 | 10 + vala * (hw - 100), vi + wh / hm, 184 | fill=self.set_color(vala), outline="")) 185 | vi += wh / hm 186 | vi = 0 187 | if len(self.pile_b) > 0: 188 | b_val = [(num - mn) / (mx - mn) for num in self.pile_b] 189 | for valb in b_val: 190 | rects.append(self.can.create_rectangle(hw, vi, 191 | hw + 10 + valb * (hw - 100), vi + wh / hm, 192 | fill=self.set_color(valb), outline="")) 193 | vi += wh / hm 194 | 195 | def launch(self): 196 | while self.i < len(self.cmds): 197 | if self.speed != 0: 198 | while self.i < len(self.cmds): 199 | self.listbox.activate(self.i) 200 | self.can.delete("all") 201 | self.pile_a, self.pile_b = \ 202 | self.launch_cmds(self.cmds[self.i]) 203 | self.draw_rectangles() 204 | time.sleep(2 * self.speed) 205 | self.can.update() 206 | self.listbox.yview_scroll(1, 'units') 207 | self.i += 1 208 | if self.speed == 0: 209 | break 210 | time.sleep(0.25) 211 | self.can.update() 212 | self.PauseCtl.config(text='>') 213 | 214 | 215 | root = Tk() 216 | root.resizable(width=False, height=False) 217 | gui = PsGui(root) 218 | root.mainloop() 219 | -------------------------------------------------------------------------------- /runner.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl 2 | 3 | use strict; 4 | use warnings; 5 | use List::Util 'shuffle'; 6 | use IPC::Run3 qw(run3); # Install libipc-run3-perl 7 | 8 | sub usage { 9 | return "$0 10 | $0 [--count] 11 | $0 [--checker] 12 | "; 13 | } 14 | 15 | # List of arguments 16 | if (@ARGV < 1 || $ARGV[0] !~ /^\d+$/) 17 | { 18 | die usage(); 19 | } 20 | my @numbers = join(' ', shuffle(0..($ARGV[0] - 1))); 21 | 22 | # Push Swap 23 | my ($in); 24 | run3 ['./push_swap', @numbers], undef, \$in, undef; 25 | 26 | if (grep { $_ eq '--checker' } @ARGV) 27 | { 28 | my ($out, $err); 29 | run3 ['./checker', @numbers], \$in, \$out, \$err; 30 | print $out; 31 | } 32 | elsif (grep { $_ eq '--count' } @ARGV) 33 | { 34 | my ($out); 35 | run3 ['wc', '-l'], \$in, \$out; 36 | print $out; 37 | } 38 | else 39 | { 40 | print $in; 41 | } -------------------------------------------------------------------------------- /src/checker/checker.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* checker.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/03/28 19:03:20 by aroque #+# #+# */ 9 | /* Updated: 2021/05/10 10:10:11 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include "libft.h" 15 | #include "general.h" 16 | #include "checker.h" 17 | 18 | int main(int argc, char *argv[]) 19 | { 20 | int status; 21 | t_stack *stack; 22 | char **instructions; 23 | 24 | status = 0; 25 | instructions = NULL; 26 | stack = get_stack(argc - 1, &argv[1]); 27 | status = get_instructions(&instructions); 28 | if (status) 29 | message_and_exit(stack, instructions, status); 30 | execute(instructions, stack); 31 | free_array((void **)instructions); 32 | free_stack(stack); 33 | return (status); 34 | } 35 | -------------------------------------------------------------------------------- /src/checker/execute.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* execute.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/03 14:54:59 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:50:36 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include "stack.h" 15 | #include "libft.h" 16 | #include "general.h" 17 | 18 | static void swap_stacks(char *op, t_stack *a, t_stack *b) 19 | { 20 | if (ft_streq(op, "sa") || ft_streq(op, "ss")) 21 | swap(a); 22 | if (ft_streq(op, "sb") || ft_streq(op, "ss")) 23 | swap(b); 24 | } 25 | 26 | static void push_stacks(char *op, t_stack *a, t_stack *b) 27 | { 28 | if (ft_streq(op, "pa")) 29 | push(b, a); 30 | else if (ft_streq(op, "pb")) 31 | push(a, b); 32 | } 33 | 34 | static void rotate_stacks(char *op, t_stack *a, t_stack *b) 35 | { 36 | if (ft_streq(op, "ra") || ft_streq(op, "rr")) 37 | rotate(a); 38 | if (ft_streq(op, "rb") || ft_streq(op, "rr")) 39 | rotate(b); 40 | if (ft_streq(op, "rra") || ft_streq(op, "rrr")) 41 | reverse_rotate(a); 42 | if (ft_streq(op, "rrb") || ft_streq(op, "rrr")) 43 | reverse_rotate(b); 44 | } 45 | 46 | int execute(char **instructions, t_stack *a) 47 | { 48 | t_stack *b; 49 | 50 | b = initialize(a->size); 51 | while (*instructions) 52 | { 53 | if (*instructions[0] == 's') 54 | swap_stacks(*instructions, a, b); 55 | else if (*instructions[0] == 'p') 56 | push_stacks(*instructions, a, b); 57 | else 58 | rotate_stacks(*instructions, a, b); 59 | instructions++; 60 | } 61 | if (!is_sorted(a) || b->top > -1) 62 | ft_putstr_fd("KO\n", STDOUT_FILENO); 63 | else 64 | ft_putstr_fd("OK\n", STDOUT_FILENO); 65 | free_stack(b); 66 | return (0); 67 | } 68 | -------------------------------------------------------------------------------- /src/checker/get_line.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_line.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/04 12:26:25 by aroque #+# #+# */ 9 | /* Updated: 2021/05/10 09:45:14 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "get_next_line.h" 14 | #include "checker.h" 15 | #include "libft.h" 16 | 17 | static bool invalid_instruction(char *op) 18 | { 19 | if (ft_streq(op, "sa")) 20 | return (false); 21 | else if (ft_streq(op, "sb")) 22 | return (false); 23 | else if (ft_streq(op, "ss")) 24 | return (false); 25 | else if (ft_streq(op, "pa")) 26 | return (false); 27 | else if (ft_streq(op, "pb")) 28 | return (false); 29 | else if (ft_streq(op, "ra")) 30 | return (false); 31 | else if (ft_streq(op, "rb")) 32 | return (false); 33 | else if (ft_streq(op, "rr")) 34 | return (false); 35 | else if (ft_streq(op, "rra")) 36 | return (false); 37 | else if (ft_streq(op, "rrb")) 38 | return (false); 39 | else if (ft_streq(op, "rrr")) 40 | return (false); 41 | return (true); 42 | } 43 | 44 | static int heap_set(char ***instructions, char **buffer, int i) 45 | { 46 | char **tmp; 47 | static size_t in_size; 48 | 49 | tmp = malloc((in_size + i + 1) * sizeof(*tmp)); 50 | if (!tmp) 51 | return (1); 52 | if (in_size) 53 | { 54 | ft_memcpy(tmp, *instructions, in_size * sizeof(*tmp)); 55 | free(*instructions); 56 | } 57 | ft_memcpy(tmp + in_size, buffer, i * sizeof(*tmp)); 58 | tmp[in_size + i] = NULL; 59 | in_size += i; 60 | *instructions = tmp; 61 | return (0); 62 | } 63 | 64 | int get_instructions(char ***instructions) 65 | { 66 | int i; 67 | int status; 68 | char *buffer[INSTRUCTIONS_BUFFER_SIZE]; 69 | char *op; 70 | 71 | i = 0; 72 | status = 0; 73 | while (!status && (get_next_line(STDIN_FILENO, &op) > 0)) 74 | { 75 | if (invalid_instruction(op)) 76 | status = 1; 77 | else 78 | { 79 | buffer[i++] = op; 80 | if (i == INSTRUCTIONS_BUFFER_SIZE) 81 | { 82 | heap_set(instructions, buffer, i); 83 | ft_bzero(buffer, INSTRUCTIONS_BUFFER_SIZE); 84 | i = 0; 85 | } 86 | } 87 | } 88 | heap_set(instructions, buffer, i); 89 | free(op); 90 | return (status); 91 | } 92 | -------------------------------------------------------------------------------- /src/free.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* free.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/06 20:59:32 by aroque #+# #+# */ 9 | /* Updated: 2021/05/02 19:33:50 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include "libft.h" 15 | #include "stack.h" 16 | 17 | void free_array(void **array) 18 | { 19 | size_t i; 20 | 21 | i = 0; 22 | while (array[i]) 23 | free(array[i++]); 24 | free(array); 25 | } 26 | 27 | void free_stack(t_stack *stack) 28 | { 29 | free(stack->array); 30 | free(stack); 31 | } 32 | 33 | void message_and_exit(t_stack *stack, char **ops, int status) 34 | { 35 | if (stack) 36 | free_stack(stack); 37 | if (ops) 38 | free_array((void **)ops); 39 | ft_putstr_fd("Error\n", STDERR_FILENO); 40 | exit(status); 41 | } 42 | -------------------------------------------------------------------------------- /src/get_stack.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* get_stack.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/02 23:27:40 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 16:24:05 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include 15 | #include "stack.h" 16 | #include "libft.h" 17 | #include "checker.h" 18 | #include "general.h" 19 | 20 | bool validate_int(char *elem) 21 | { 22 | bool is_int; 23 | unsigned int i; 24 | unsigned int cm; 25 | 26 | i = 0; 27 | cm = 0; 28 | is_int = true; 29 | while (elem[i] && is_int) 30 | { 31 | if (elem[i] == '-' && cm < 1) 32 | cm++; 33 | else if (!ft_isdigit(elem[i])) 34 | is_int = false; 35 | i++; 36 | } 37 | return (!is_int); 38 | } 39 | 40 | void insert_sorted(int n, int *data, int size) 41 | { 42 | int i; 43 | 44 | i = size; 45 | while (--i >= 0 && data[i] > n) 46 | data[i + 1] = data[i]; 47 | data[i + 1] = n; 48 | } 49 | 50 | bool already_exists(int n, t_stack *stack) 51 | { 52 | int i; 53 | 54 | i = stack->top; 55 | while (i >= 0) 56 | { 57 | if (stack->array[i] == n) 58 | return (true); 59 | i--; 60 | } 61 | return (false); 62 | } 63 | 64 | int fill_element(t_stack *stack, char *arg) 65 | { 66 | unsigned int j; 67 | int n; 68 | int status; 69 | char **array; 70 | 71 | j = 0; 72 | status = 0; 73 | array = ft_split(arg, SPACE); 74 | while (array[j] && !status) 75 | { 76 | if (validate_int(array[j])) 77 | status = 1; 78 | if (atoiv(array[j], &n)) 79 | status = 2; 80 | if (already_exists(n, stack)) 81 | status = 3; 82 | else 83 | stack->array[++stack->top] = n; 84 | j++; 85 | } 86 | free_array((void **)array); 87 | return (status); 88 | } 89 | 90 | t_stack *get_stack(int size, char **args) 91 | { 92 | unsigned int i; 93 | int status; 94 | t_stack *stack; 95 | 96 | if (size < 1) 97 | exit(0); 98 | i = 0; 99 | status = 0; 100 | stack = initialize(STACK_BUFFER); 101 | while (args[i] && !status) 102 | status = fill_element(stack, args[i++]); 103 | if (status) 104 | { 105 | free_stack(stack); 106 | ft_putendl_fd("Error", STDERR_FILENO); 107 | exit(status); 108 | } 109 | reverse_array(stack->array, stack->top + 1); 110 | return (stack); 111 | } 112 | -------------------------------------------------------------------------------- /src/push_swap/index.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* index.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/05/01 11:48:02 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:45:14 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | #include "general.h" 15 | 16 | static int *sorted_array_copy(t_stack *stack) 17 | { 18 | int *copy; 19 | size_t size; 20 | 21 | size = stack->top + 1; 22 | copy = malloc(size * sizeof(*copy)); 23 | ft_memcpy(copy, stack->array, size * sizeof(*copy)); 24 | insertion_sort(copy, size); 25 | return (copy); 26 | } 27 | 28 | void index_stack(t_stack **stack) 29 | { 30 | int *copy; 31 | int i; 32 | size_t pos; 33 | int *array; 34 | 35 | i = 0; 36 | array = ft_calloc((*stack)->top + 1, sizeof(*array)); 37 | copy = sorted_array_copy(*stack); 38 | while (i <= (*stack)->top) 39 | { 40 | pos = 0; 41 | while (copy[pos] != (*stack)->array[i]) 42 | pos++; 43 | array[i++] = pos; 44 | } 45 | ft_memcpy((*stack)->array, array, ((*stack)->top + 1) * sizeof(*array)); 46 | free(copy); 47 | free(array); 48 | } 49 | 50 | int _index(t_stack *stack, int n) 51 | { 52 | int i; 53 | 54 | i = stack->top; 55 | while (stack->array[i] != n && i >= 0) 56 | i--; 57 | return (i); 58 | } 59 | -------------------------------------------------------------------------------- /src/push_swap/move.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* move.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/05/19 15:40:21 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:43:05 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "push_swap.h" 14 | 15 | static int between(int n, int min, int max) 16 | { 17 | return (n >= min && n <= max); 18 | } 19 | 20 | static int find_from_top(t_stack *a, int min, int max) 21 | { 22 | int i; 23 | 24 | i = 0; 25 | while (i <= a->top) 26 | { 27 | if (between(a->array[i], min, max)) 28 | return (i); 29 | i++; 30 | } 31 | return (-1); 32 | } 33 | 34 | static int find_from_bottom(t_stack *a, int min, int max) 35 | { 36 | int i; 37 | 38 | i = a->top; 39 | while (i >= 0) 40 | { 41 | if (between(a->array[i], min, max)) 42 | return (i); 43 | i--; 44 | } 45 | return (-1); 46 | } 47 | 48 | void move_to_top(t_stack *a, int min, int max) 49 | { 50 | int i; 51 | int index[2]; 52 | 53 | index[0] = find_from_top(a, min, max); 54 | index[1] = find_from_bottom(a, min, max); 55 | if (index[0] < a->top - index[1]) 56 | i = index[0]; 57 | else 58 | i = index[1]; 59 | smart_rotate_a(a, a->array[i]); 60 | } 61 | 62 | void move_min_or_max_to_top(t_stack *b) 63 | { 64 | int i; 65 | int index[2]; 66 | 67 | index[0] = _index(b, min(b)); 68 | index[1] = _index(b, max(b)); 69 | if (index[0] < b->top - index[1]) 70 | i = index[0]; 71 | else 72 | i = index[1]; 73 | smart_rotate_b(b, b->array[i]); 74 | } 75 | -------------------------------------------------------------------------------- /src/push_swap/push_swap.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* push_swap.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/05 22:25:18 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:44:48 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "general.h" 14 | #include "push_swap.h" 15 | 16 | int main(int argc, char *argv[]) 17 | { 18 | t_stack *stack; 19 | 20 | stack = get_stack(argc - 1, &argv[1]); 21 | index_stack(&stack); 22 | sort(stack); 23 | free_stack(stack); 24 | return (0); 25 | } 26 | -------------------------------------------------------------------------------- /src/push_swap/run.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* run.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/10 17:29:06 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:44:41 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include "push_swap.h" 15 | #include "libft.h" 16 | 17 | void run(char *op, t_stack *a, t_stack *b) 18 | { 19 | if (ft_streq(op, PA)) 20 | push(b, a); 21 | else if (ft_streq(op, PB)) 22 | push(a, b); 23 | else if (ft_streq(op, SA)) 24 | swap(a); 25 | else if (ft_streq(op, SB)) 26 | swap(b); 27 | else if (ft_streq(op, RA)) 28 | rotate(a); 29 | else if (ft_streq(op, RB)) 30 | rotate(b); 31 | else if (ft_streq(op, RRA)) 32 | reverse_rotate(a); 33 | else if (ft_streq(op, RRB)) 34 | reverse_rotate(b); 35 | ft_putendl_fd(op, STDOUT_FILENO); 36 | } 37 | 38 | void run_n(char *op, t_stack *a, t_stack *b, int n) 39 | { 40 | if (n <= 0) 41 | return ; 42 | run(op, a, b); 43 | run_n(op, a, b, n - 1); 44 | } 45 | -------------------------------------------------------------------------------- /src/push_swap/smart.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* smart.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/05/02 22:40:51 by aroque #+# #+# */ 9 | /* Updated: 2021/05/29 18:26:57 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "push_swap.h" 14 | 15 | /* 16 | ** Find the next number greater than n in the 17 | ** stack. Returns 'n' if there's no such number; 18 | */ 19 | 20 | int closest_above(t_stack *a, int n) 21 | { 22 | int k; 23 | int i; 24 | 25 | if (a->top < 0 || n > max(a)) 26 | return (n); 27 | i = 0; 28 | k = max(a); 29 | while (i <= a->top) 30 | { 31 | if (a->array[i] > n && a->array[i] < k) 32 | k = a->array[i]; 33 | i++; 34 | } 35 | return (k); 36 | } 37 | 38 | int closest_below(t_stack *a, int n) 39 | { 40 | int k; 41 | int i; 42 | 43 | if (a->top < 0 || n < min(a)) 44 | return (n); 45 | i = 0; 46 | k = min(a); 47 | while (i <= a->top) 48 | { 49 | if (a->array[i] < n && a->array[i] > k) 50 | k = a->array[i]; 51 | i++; 52 | } 53 | return (k); 54 | } 55 | 56 | /* 57 | ** Put the number 'n' at the top of the stack, 58 | ** in the least amount of moves possible (RRA 59 | ** or RA). Do nothing if 'n' isn't on stack; 60 | */ 61 | 62 | void smart_rotate_a(t_stack *a, int n) 63 | { 64 | int find; 65 | 66 | find = a->top; 67 | while (find >= 0 && a->array[find] != n) 68 | find--; 69 | if (find < 0) 70 | return ; 71 | else if (find < a->top / 2) 72 | run_n(RRA, a, NULL, find + 1); 73 | else 74 | run_n(RA, a, NULL, a->top - find); 75 | } 76 | 77 | void smart_rotate_b(t_stack *b, int n) 78 | { 79 | int find; 80 | 81 | find = b->top; 82 | while (b->array[find] != n && find >= 0) 83 | find--; 84 | if (find < 0) 85 | return ; 86 | else if (find < b->top / 2) 87 | run_n(RRB, NULL, b, find + 1); 88 | else 89 | run_n(RB, NULL, b, b->top - find); 90 | } 91 | -------------------------------------------------------------------------------- /src/push_swap/sort.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* sort.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/06 21:08:50 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:26:43 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "general.h" 14 | #include "push_swap.h" 15 | 16 | void sort(t_stack *stack) 17 | { 18 | t_stack *new; 19 | 20 | if (is_sorted(stack) || stack->top <= 0) 21 | return ; 22 | new = initialize(stack->size); 23 | if (stack->top < SORT_COMPLEX_LIMIT) 24 | sort_small(stack, new); 25 | else 26 | sort_complex(stack, new); 27 | free_stack(new); 28 | } 29 | -------------------------------------------------------------------------------- /src/push_swap/sort_complex.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* sort_complex.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/05/08 14:50:26 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:44:28 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "push_swap.h" 14 | 15 | void put_in_position(t_stack *a, t_stack *b) 16 | { 17 | int top_b; 18 | int to_move; 19 | 20 | top_b = b->array[b->top]; 21 | to_move = closest_above(a, top_b); 22 | if (to_move == top_b && a->top >= 0) 23 | to_move = min(a); 24 | smart_rotate_a(a, to_move); 25 | run(PA, a, b); 26 | } 27 | 28 | void sort_chunk(t_stack *a, t_stack *b) 29 | { 30 | while (b->top >= 0) 31 | { 32 | move_min_or_max_to_top(b); 33 | put_in_position(a, b); 34 | } 35 | } 36 | 37 | void move_chunk(t_stack *a, t_stack *b, int min, int max) 38 | { 39 | int size; 40 | 41 | size = max - min + 1; 42 | while (size) 43 | { 44 | move_to_top(a, min, max); 45 | run(PB, a, b); 46 | size--; 47 | } 48 | } 49 | 50 | size_t get_chunks(t_stack *a) 51 | { 52 | size_t chunks; 53 | 54 | chunks = (a->top + 1) / CHUNK_CONSTANT + 1; 55 | return (chunks); 56 | } 57 | 58 | void sort_complex(t_stack *a, t_stack *b) 59 | { 60 | int limit_min; 61 | int limit_max; 62 | size_t chunks; 63 | size_t step; 64 | 65 | chunks = get_chunks(a); 66 | limit_max = max(a); 67 | step = (a->top + 1) / chunks; 68 | while (chunks >= 1) 69 | { 70 | if (chunks == 1) 71 | limit_min = min(a); 72 | else 73 | limit_min = limit_max - step + 1; 74 | move_chunk(a, b, limit_min, limit_max); 75 | sort_chunk(a, b); 76 | limit_max = limit_min - 1; 77 | chunks--; 78 | } 79 | smart_rotate_a(a, min(a)); 80 | } 81 | -------------------------------------------------------------------------------- /src/push_swap/sort_small.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* sort_small.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/05/02 16:52:54 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:44:23 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "push_swap.h" 14 | 15 | static void sort_tri(t_stack *a) 16 | { 17 | int *arr; 18 | 19 | arr = a->array; 20 | if (arr[0] > arr[1] && arr[1] < arr[2] && arr[2] < arr[0]) 21 | run(SA, a, NULL); 22 | else if (arr[0] < arr[1] && arr[1] < arr[2] && arr[2] > arr[0]) 23 | { 24 | run(SA, a, NULL); 25 | run(RRA, a, NULL); 26 | } 27 | else if (arr[0] > arr[1] && arr[1] < arr[2] && arr[2] > arr[0]) 28 | run(RA, a, NULL); 29 | else if (arr[0] < arr[1] && arr[1] > arr[2] && arr[2] < arr[0]) 30 | { 31 | run(SA, a, NULL); 32 | run(RA, a, NULL); 33 | } 34 | else if (arr[0] < arr[1] && arr[1] > arr[2] && arr[2] > arr[0]) 35 | run(RRA, a, NULL); 36 | } 37 | 38 | static void put_top_in_position(t_stack *a, t_stack *b) 39 | { 40 | int top_b; 41 | int to_move; 42 | 43 | top_b = b->array[b->top]; 44 | to_move = closest_above(a, top_b); 45 | if (to_move == top_b) 46 | to_move = min(a); 47 | smart_rotate_a(a, to_move); 48 | run(PA, a, b); 49 | } 50 | 51 | static void sort_tri_complex(t_stack *a, t_stack *b) 52 | { 53 | run_n(PB, a, b, a->top - 2); 54 | sort_tri(a); 55 | while (b->top >= 0) 56 | put_top_in_position(a, b); 57 | smart_rotate_a(a, 0); 58 | } 59 | 60 | void sort_small(t_stack *a, t_stack *b) 61 | { 62 | if (a->top == 1) 63 | run(SA, a, NULL); 64 | else if (a->top == 2) 65 | sort_tri(a); 66 | else 67 | sort_tri_complex(a, b); 68 | } 69 | -------------------------------------------------------------------------------- /src/search.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* search.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/03 14:39:45 by aroque #+# #+# */ 9 | /* Updated: 2021/04/04 22:00:47 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | 15 | bool binary_search(int n, int *data, int size) 16 | { 17 | int mid; 18 | int left; 19 | int right; 20 | 21 | left = 0; 22 | right = size - 1; 23 | while (left <= right) 24 | { 25 | mid = left + ((right - left) / 2); 26 | if (data[mid] == n) 27 | return (true); 28 | else if (n < data[mid]) 29 | right = mid - 1; 30 | else 31 | left = mid + 1; 32 | } 33 | return (false); 34 | } 35 | -------------------------------------------------------------------------------- /src/utils.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* utils.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/04/08 09:37:58 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:50:21 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include "libft.h" 15 | #include "stack.h" 16 | 17 | bool atoiv(const char *str, int *n) 18 | { 19 | int signal; 20 | bool overflow; 21 | 22 | *n = 0; 23 | signal = -1; 24 | overflow = false; 25 | while (ft_isspace(*str)) 26 | str++; 27 | if (*str == '+' || *str == '-') 28 | if (*str++ == '-') 29 | signal = 1; 30 | while (*str >= '0' && *str <= '9') 31 | { 32 | *n = *n * 10 - (*str++ - '0'); 33 | if (*n > 0 || (*n == INT_MIN && signal < 0)) 34 | overflow = true; 35 | } 36 | *n *= signal; 37 | return (overflow); 38 | } 39 | 40 | static void _swap(int *a, int *b) 41 | { 42 | int aux; 43 | 44 | aux = *b; 45 | *b = *a; 46 | *a = aux; 47 | } 48 | 49 | void reverse_array(int *array, size_t size) 50 | { 51 | static size_t i; 52 | 53 | if (i < size) 54 | { 55 | _swap(&array[i++], &array[size - 1]); 56 | reverse_array(array, size - 1); 57 | } 58 | i = 0; 59 | } 60 | 61 | int abs(int n) 62 | { 63 | int mask; 64 | 65 | mask = n >> 31; 66 | return ((n ^ mask) - mask); 67 | } 68 | -------------------------------------------------------------------------------- /src/utils_sort.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* utils_sort.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/05/19 15:49:27 by aroque #+# #+# */ 9 | /* Updated: 2021/05/19 15:49:43 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "stack.h" 14 | 15 | bool is_sorted(t_stack *stack) 16 | { 17 | int i; 18 | 19 | i = -1; 20 | while (++i < stack->top) 21 | { 22 | if (stack->array[i + 1] > stack->array[i]) 23 | return (false); 24 | } 25 | return (true); 26 | } 27 | 28 | void insertion_sort(int array[], size_t size) 29 | { 30 | int i; 31 | unsigned int j; 32 | int key; 33 | 34 | j = 1; 35 | while (j < size) 36 | { 37 | i = j - 1; 38 | key = array[j++]; 39 | while (i >= 0 && array[i + 1] < array[i]) 40 | { 41 | array[i + 1] = array[i]; 42 | array[i--] = key; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/include/minunit.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 David Siñuela Pastor, siu.4coders@gmail.com 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining 5 | * a copy of this software and associated documentation files (the 6 | * "Software"), to deal in the Software without restriction, including 7 | * without limitation the rights to use, copy, modify, merge, publish, 8 | * distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so, subject to 10 | * the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | #ifndef MINUNIT_MINUNIT_H 24 | #define MINUNIT_MINUNIT_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | #if defined(_WIN32) 31 | #include 32 | #if defined(_MSC_VER) && _MSC_VER < 1900 33 | #define snprintf _snprintf 34 | #define __func__ __FUNCTION__ 35 | #endif 36 | 37 | #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) 38 | 39 | /* Change POSIX C SOURCE version for pure c99 compilers */ 40 | #if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L 41 | #undef _POSIX_C_SOURCE 42 | #define _POSIX_C_SOURCE 200112L 43 | #endif 44 | 45 | #include /* POSIX flags */ 46 | #include /* clock_gettime(), time() */ 47 | #include /* gethrtime(), gettimeofday() */ 48 | #include 49 | #include 50 | #include 51 | 52 | #if defined(__MACH__) && defined(__APPLE__) 53 | #include 54 | #include 55 | #endif 56 | 57 | #if __GNUC__ >= 5 && !defined(__STDC_VERSION__) 58 | #define __func__ __extension__ __FUNCTION__ 59 | #endif 60 | 61 | #else 62 | #error "Unable to define timers for an unknown OS." 63 | #endif 64 | 65 | #include 66 | #include 67 | 68 | /* Maximum length of last message */ 69 | #define MINUNIT_MESSAGE_LEN 1024 70 | /* Accuracy with which floats are compared */ 71 | #define MINUNIT_EPSILON 1E-12 72 | 73 | /* Misc. counters */ 74 | static int minunit_run = 0; 75 | static int minunit_assert = 0; 76 | static int minunit_fail = 0; 77 | static int minunit_status = 0; 78 | 79 | /* Timers */ 80 | static double minunit_real_timer = 0; 81 | static double minunit_proc_timer = 0; 82 | 83 | /* Last message */ 84 | static char minunit_last_message[MINUNIT_MESSAGE_LEN]; 85 | 86 | /* Test setup and teardown function pointers */ 87 | static void (*minunit_setup)(void) = NULL; 88 | static void (*minunit_teardown)(void) = NULL; 89 | 90 | /* Definitions */ 91 | #define MU_TEST(method_name) static void method_name(void) 92 | #define MU_TEST_SUITE(suite_name) static void suite_name(void) 93 | 94 | #define MU__SAFE_BLOCK(block) do {\ 95 | block\ 96 | } while(0) 97 | 98 | /* Run test suite and unset setup and teardown functions */ 99 | #define MU_RUN_SUITE(suite_name) MU__SAFE_BLOCK(\ 100 | suite_name();\ 101 | minunit_setup = NULL;\ 102 | minunit_teardown = NULL;\ 103 | ) 104 | 105 | /* Configure setup and teardown functions */ 106 | #define MU_SUITE_CONFIGURE(setup_fun, teardown_fun) MU__SAFE_BLOCK(\ 107 | minunit_setup = setup_fun;\ 108 | minunit_teardown = teardown_fun;\ 109 | ) 110 | 111 | /* Test runner */ 112 | #define MU_RUN_TEST(test) MU__SAFE_BLOCK(\ 113 | if (minunit_real_timer==0 && minunit_proc_timer==0) {\ 114 | minunit_real_timer = mu_timer_real();\ 115 | minunit_proc_timer = mu_timer_cpu();\ 116 | }\ 117 | if (minunit_setup) (*minunit_setup)();\ 118 | minunit_status = 0;\ 119 | test();\ 120 | minunit_run++;\ 121 | if (minunit_status) {\ 122 | minunit_fail++;\ 123 | printf("F");\ 124 | printf("\n%s\n", minunit_last_message);\ 125 | }\ 126 | fflush(stdout);\ 127 | if (minunit_teardown) (*minunit_teardown)();\ 128 | ) 129 | 130 | /* Report */ 131 | #define MU_REPORT() MU__SAFE_BLOCK(\ 132 | double minunit_end_real_timer;\ 133 | double minunit_end_proc_timer;\ 134 | printf("\n\n%d tests, %d assertions, %d failures\n", minunit_run, minunit_assert, minunit_fail);\ 135 | minunit_end_real_timer = mu_timer_real();\ 136 | minunit_end_proc_timer = mu_timer_cpu();\ 137 | printf("\nFinished in %.8f seconds (real) %.8f seconds (proc)\n\n",\ 138 | minunit_end_real_timer - minunit_real_timer,\ 139 | minunit_end_proc_timer - minunit_proc_timer);\ 140 | ) 141 | #define MU_EXIT_CODE minunit_fail 142 | 143 | /* Assertions */ 144 | #define mu_check(test) MU__SAFE_BLOCK(\ 145 | minunit_assert++;\ 146 | if (!(test)) {\ 147 | snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, #test);\ 148 | minunit_status = 1;\ 149 | return;\ 150 | } else {\ 151 | printf(".");\ 152 | }\ 153 | ) 154 | 155 | #define mu_fail(message) MU__SAFE_BLOCK(\ 156 | minunit_assert++;\ 157 | snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, message);\ 158 | minunit_status = 1;\ 159 | return;\ 160 | ) 161 | 162 | #define mu_assert(test, message) MU__SAFE_BLOCK(\ 163 | minunit_assert++;\ 164 | if (!(test)) {\ 165 | snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %s", __func__, __FILE__, __LINE__, message);\ 166 | minunit_status = 1;\ 167 | return;\ 168 | } else {\ 169 | printf(".");\ 170 | }\ 171 | ) 172 | 173 | #define mu_assert_int_eq(expected, result) MU__SAFE_BLOCK(\ 174 | int minunit_tmp_e;\ 175 | int minunit_tmp_r;\ 176 | minunit_assert++;\ 177 | minunit_tmp_e = (expected);\ 178 | minunit_tmp_r = (result);\ 179 | if (minunit_tmp_e != minunit_tmp_r) {\ 180 | snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %d expected but was %d", __func__, __FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r);\ 181 | minunit_status = 1;\ 182 | return;\ 183 | } else {\ 184 | printf(".");\ 185 | }\ 186 | ) 187 | 188 | #define mu_assert_double_eq(expected, result) MU__SAFE_BLOCK(\ 189 | double minunit_tmp_e;\ 190 | double minunit_tmp_r;\ 191 | minunit_assert++;\ 192 | minunit_tmp_e = (expected);\ 193 | minunit_tmp_r = (result);\ 194 | if (fabs(minunit_tmp_e-minunit_tmp_r) > MINUNIT_EPSILON) {\ 195 | int minunit_significant_figures = 1 - log10(MINUNIT_EPSILON);\ 196 | snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: %.*g expected but was %.*g", __func__, __FILE__, __LINE__, minunit_significant_figures, minunit_tmp_e, minunit_significant_figures, minunit_tmp_r);\ 197 | minunit_status = 1;\ 198 | return;\ 199 | } else {\ 200 | printf(".");\ 201 | }\ 202 | ) 203 | 204 | #define mu_assert_string_eq(expected, result) MU__SAFE_BLOCK(\ 205 | const char* minunit_tmp_e = expected;\ 206 | const char* minunit_tmp_r = result;\ 207 | minunit_assert++;\ 208 | if (!minunit_tmp_e) {\ 209 | minunit_tmp_e = "";\ 210 | }\ 211 | if (!minunit_tmp_r) {\ 212 | minunit_tmp_r = "";\ 213 | }\ 214 | if(strcmp(minunit_tmp_e, minunit_tmp_r)) {\ 215 | snprintf(minunit_last_message, MINUNIT_MESSAGE_LEN, "%s failed:\n\t%s:%d: '%s' expected but was '%s'", __func__, __FILE__, __LINE__, minunit_tmp_e, minunit_tmp_r);\ 216 | minunit_status = 1;\ 217 | return;\ 218 | } else {\ 219 | printf(".");\ 220 | }\ 221 | ) 222 | 223 | /* 224 | * The following two functions were written by David Robert Nadeau 225 | * from http://NadeauSoftware.com/ and distributed under the 226 | * Creative Commons Attribution 3.0 Unported License 227 | */ 228 | 229 | /** 230 | * Returns the real time, in seconds, or -1.0 if an error occurred. 231 | * 232 | * Time is measured since an arbitrary and OS-dependent start time. 233 | * The returned real time is only useful for computing an elapsed time 234 | * between two calls to this function. 235 | */ 236 | static double mu_timer_real(void) 237 | { 238 | #if defined(_WIN32) 239 | /* Windows 2000 and later. ---------------------------------- */ 240 | LARGE_INTEGER Time; 241 | LARGE_INTEGER Frequency; 242 | 243 | QueryPerformanceFrequency(&Frequency); 244 | QueryPerformanceCounter(&Time); 245 | 246 | Time.QuadPart *= 1000000; 247 | Time.QuadPart /= Frequency.QuadPart; 248 | 249 | return (double)Time.QuadPart / 1000000.0; 250 | 251 | #elif (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__))) 252 | /* HP-UX, Solaris. ------------------------------------------ */ 253 | return (double)gethrtime( ) / 1000000000.0; 254 | 255 | #elif defined(__MACH__) && defined(__APPLE__) 256 | /* OSX. ----------------------------------------------------- */ 257 | static double timeConvert = 0.0; 258 | if ( timeConvert == 0.0 ) 259 | { 260 | mach_timebase_info_data_t timeBase; 261 | (void)mach_timebase_info( &timeBase ); 262 | timeConvert = (double)timeBase.numer / 263 | (double)timeBase.denom / 264 | 1000000000.0; 265 | } 266 | return (double)mach_absolute_time( ) * timeConvert; 267 | 268 | #elif defined(_POSIX_VERSION) 269 | /* POSIX. --------------------------------------------------- */ 270 | struct timeval tm; 271 | #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) 272 | { 273 | struct timespec ts; 274 | #if defined(CLOCK_MONOTONIC_PRECISE) 275 | /* BSD. --------------------------------------------- */ 276 | const clockid_t id = CLOCK_MONOTONIC_PRECISE; 277 | #elif defined(CLOCK_MONOTONIC_RAW) 278 | /* Linux. ------------------------------------------- */ 279 | const clockid_t id = CLOCK_MONOTONIC_RAW; 280 | #elif defined(CLOCK_HIGHRES) 281 | /* Solaris. ----------------------------------------- */ 282 | const clockid_t id = CLOCK_HIGHRES; 283 | #elif defined(CLOCK_MONOTONIC) 284 | /* AIX, BSD, Linux, POSIX, Solaris. ----------------- */ 285 | const clockid_t id = CLOCK_MONOTONIC; 286 | #elif defined(CLOCK_REALTIME) 287 | /* AIX, BSD, HP-UX, Linux, POSIX. ------------------- */ 288 | const clockid_t id = CLOCK_REALTIME; 289 | #else 290 | const clockid_t id = (clockid_t)-1; /* Unknown. */ 291 | #endif /* CLOCK_* */ 292 | if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 ) 293 | return (double)ts.tv_sec + 294 | (double)ts.tv_nsec / 1000000000.0; 295 | /* Fall thru. */ 296 | } 297 | #endif /* _POSIX_TIMERS */ 298 | 299 | /* AIX, BSD, Cygwin, HP-UX, Linux, OSX, POSIX, Solaris. ----- */ 300 | gettimeofday( &tm, NULL ); 301 | return (double)tm.tv_sec + (double)tm.tv_usec / 1000000.0; 302 | #else 303 | return -1.0; /* Failed. */ 304 | #endif 305 | } 306 | 307 | /** 308 | * Returns the amount of CPU time used by the current process, 309 | * in seconds, or -1.0 if an error occurred. 310 | */ 311 | static double mu_timer_cpu(void) 312 | { 313 | #if defined(_WIN32) 314 | /* Windows -------------------------------------------------- */ 315 | FILETIME createTime; 316 | FILETIME exitTime; 317 | FILETIME kernelTime; 318 | FILETIME userTime; 319 | 320 | /* This approach has a resolution of 1/64 second. Unfortunately, Windows' API does not offer better */ 321 | if ( GetProcessTimes( GetCurrentProcess( ), 322 | &createTime, &exitTime, &kernelTime, &userTime ) != 0 ) 323 | { 324 | ULARGE_INTEGER userSystemTime; 325 | memcpy(&userSystemTime, &userTime, sizeof(ULARGE_INTEGER)); 326 | return (double)userSystemTime.QuadPart / 10000000.0; 327 | } 328 | 329 | #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__)) 330 | /* AIX, BSD, Cygwin, HP-UX, Linux, OSX, and Solaris --------- */ 331 | 332 | #if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) 333 | /* Prefer high-res POSIX timers, when available. */ 334 | { 335 | clockid_t id; 336 | struct timespec ts; 337 | #if _POSIX_CPUTIME > 0 338 | /* Clock ids vary by OS. Query the id, if possible. */ 339 | if ( clock_getcpuclockid( 0, &id ) == -1 ) 340 | #endif 341 | #if defined(CLOCK_PROCESS_CPUTIME_ID) 342 | /* Use known clock id for AIX, Linux, or Solaris. */ 343 | id = CLOCK_PROCESS_CPUTIME_ID; 344 | #elif defined(CLOCK_VIRTUAL) 345 | /* Use known clock id for BSD or HP-UX. */ 346 | id = CLOCK_VIRTUAL; 347 | #else 348 | id = (clockid_t)-1; 349 | #endif 350 | if ( id != (clockid_t)-1 && clock_gettime( id, &ts ) != -1 ) 351 | return (double)ts.tv_sec + 352 | (double)ts.tv_nsec / 1000000000.0; 353 | } 354 | #endif 355 | 356 | #if defined(RUSAGE_SELF) 357 | { 358 | struct rusage rusage; 359 | if ( getrusage( RUSAGE_SELF, &rusage ) != -1 ) 360 | return (double)rusage.ru_utime.tv_sec + 361 | (double)rusage.ru_utime.tv_usec / 1000000.0; 362 | } 363 | #endif 364 | 365 | #if defined(_SC_CLK_TCK) 366 | { 367 | const double ticks = (double)sysconf( _SC_CLK_TCK ); 368 | struct tms tms; 369 | if ( times( &tms ) != (clock_t)-1 ) 370 | return (double)tms.tms_utime / ticks; 371 | } 372 | #endif 373 | 374 | #if defined(CLOCKS_PER_SEC) 375 | { 376 | clock_t cl = clock( ); 377 | if ( cl != (clock_t)-1 ) 378 | return (double)cl / (double)CLOCKS_PER_SEC; 379 | } 380 | #endif 381 | 382 | #endif 383 | 384 | return -1; /* Failed. */ 385 | } 386 | 387 | #ifdef __cplusplus 388 | } 389 | #endif 390 | 391 | #endif /* MINUNIT_MINUNIT_H */ 392 | -------------------------------------------------------------------------------- /test/src/test.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* test.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: aroque +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/01/05 20:27:24 by aroque #+# #+# */ 9 | /* Updated: 2021/05/01 18:19:16 by aroque ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include 15 | #include "libft.h" 16 | #include "stack.h" 17 | #include "minunit.h" 18 | #include "general.h" 19 | #include "checker.h" 20 | #include "push_swap.h" 21 | 22 | MU_TEST(test_swap) 23 | { 24 | t_stack *a; 25 | 26 | a = initialize(5); 27 | a->array[0] = 4; 28 | a->array[1] = 1; 29 | a->array[2] = 2; 30 | a->array[3] = 9; 31 | a->top = 3; 32 | mu_assert_int_eq(9, a->array[3]); 33 | mu_assert_int_eq(2, a->array[2]); 34 | swap(a); 35 | mu_assert_int_eq(2, a->array[3]); 36 | mu_assert_int_eq(9, a->array[2]); 37 | } 38 | 39 | MU_TEST(test_swap_null) 40 | { 41 | t_stack *a; 42 | 43 | a = initialize(1); 44 | a->array[0] = 4; 45 | swap(a); 46 | mu_assert_int_eq(4, a->array[0]); 47 | } 48 | 49 | MU_TEST(test_push) 50 | { 51 | t_stack *a; 52 | t_stack *b; 53 | 54 | a = initialize(5); 55 | b = initialize(5); 56 | a->array[0] = 4; 57 | a->array[1] = 1; 58 | a->array[2] = 2; 59 | a->array[3] = 9; 60 | a->top = 3; 61 | b->array[0] = 1; 62 | b->array[1] = 2; 63 | b->array[2] = 0; 64 | b->array[3] = 7; 65 | b->top = 3; 66 | push(a, b); 67 | mu_assert_int_eq(2, a->array[2]); 68 | mu_assert_int_eq(9, b->array[4]); 69 | mu_assert_int_eq(7, b->array[3]); 70 | mu_assert_int_eq(2, a->top); 71 | mu_assert_int_eq(4, b->top); 72 | } 73 | 74 | MU_TEST(test_rotate) 75 | { 76 | t_stack *a; 77 | 78 | a = initialize(5); 79 | a->array[0] = 4; 80 | a->array[1] = 1; 81 | a->array[2] = 2; 82 | a->array[3] = 9; 83 | a->top = 3; 84 | rotate(a); 85 | mu_assert_int_eq(9, a->array[0]); 86 | mu_assert_int_eq(4, a->array[1]); 87 | mu_assert_int_eq(1, a->array[2]); 88 | mu_assert_int_eq(2, a->array[3]); 89 | } 90 | 91 | MU_TEST(test_rotate_null) 92 | { 93 | t_stack *a; 94 | 95 | a = initialize(2); 96 | a->array[0] = 4; 97 | a->top = 0; 98 | rotate(a); 99 | mu_assert_int_eq(4, a->array[0]); 100 | } 101 | 102 | MU_TEST(test_reverse_rotate) 103 | { 104 | t_stack *a; 105 | 106 | a = initialize(5); 107 | a->array[0] = 4; 108 | a->array[1] = 1; 109 | a->array[2] = 2; 110 | a->array[3] = 9; 111 | a->top = 3; 112 | reverse_rotate(a); 113 | mu_assert_int_eq(1, a->array[0]); 114 | mu_assert_int_eq(2, a->array[1]); 115 | mu_assert_int_eq(9, a->array[2]); 116 | mu_assert_int_eq(4, a->array[3]); 117 | } 118 | 119 | MU_TEST(test_reverse_rotate_null) 120 | { 121 | t_stack *a; 122 | 123 | a = initialize(2); 124 | a->array[0] = 4; 125 | a->top = 0; 126 | reverse_rotate(a); 127 | mu_assert_int_eq(4, a->array[0]); 128 | } 129 | 130 | MU_TEST(test_max) 131 | { 132 | t_stack *a; 133 | 134 | a = initialize(5); 135 | a->array[0] = 4; 136 | a->array[1] = 1; 137 | a->array[2] = 2; 138 | a->array[3] = 9; 139 | a->top = 3; 140 | mu_assert_int_eq(9, max(a)); 141 | a->top = 2; 142 | mu_assert_int_eq(4, max(a)); 143 | free_stack(a); 144 | } 145 | 146 | MU_TEST(test_min) 147 | { 148 | t_stack *a; 149 | 150 | a = initialize(5); 151 | a->array[0] = 4; 152 | a->array[1] = 1; 153 | a->array[2] = 2; 154 | a->array[3] = -2; 155 | a->top = 3; 156 | mu_assert_int_eq(-2, min(a)); 157 | a->top = 2; 158 | mu_assert_int_eq(1, min(a)); 159 | free_stack(a); 160 | } 161 | 162 | MU_TEST_SUITE(test_suite_stack) 163 | { 164 | MU_RUN_TEST(test_swap); 165 | MU_RUN_TEST(test_swap_null); 166 | MU_RUN_TEST(test_push); 167 | MU_RUN_TEST(test_rotate); 168 | MU_RUN_TEST(test_rotate_null); 169 | MU_RUN_TEST(test_reverse_rotate); 170 | MU_RUN_TEST(test_reverse_rotate_null); 171 | MU_RUN_TEST(test_max); 172 | MU_RUN_TEST(test_min); 173 | } 174 | 175 | /* 176 | ** --------------------- 177 | ** --- General Tests --- 178 | ** --------------------- 179 | */ 180 | 181 | MU_TEST(test_abs) 182 | { 183 | mu_assert_int_eq(42, abs(42)); 184 | mu_assert_int_eq(42, abs(-42)); 185 | mu_assert_int_eq(2147483647, abs(2147483647)); 186 | mu_assert_int_eq(0, abs(0)); 187 | mu_assert_int_eq(23, abs(-23)); 188 | } 189 | 190 | MU_TEST(test_binary_search) 191 | { 192 | int array[] = { 1, 2, 4, 7, 19, 23 }; 193 | int array_size = 6; 194 | 195 | mu_assert_int_eq(true, binary_search(4, array, array_size)); 196 | mu_assert_int_eq(true, binary_search(1, array, array_size)); 197 | mu_assert_int_eq(false, binary_search(42, array, array_size)); 198 | } 199 | 200 | MU_TEST(test_atoiv) 201 | { 202 | int n; 203 | bool overflow; 204 | 205 | overflow = atoiv("472", &n); 206 | mu_assert_int_eq(472, n); 207 | mu_assert_int_eq(false, overflow); 208 | overflow = atoiv("2147483647", &n); 209 | mu_assert_int_eq(2147483647, n); 210 | mu_assert_int_eq(false, overflow); 211 | overflow = atoiv("-2147483648", &n); 212 | mu_assert_int_eq(-2147483648, n); 213 | mu_assert_int_eq(false, overflow); 214 | overflow = atoiv("2147483648", &n); 215 | mu_assert_int_eq(true, overflow); 216 | overflow = atoiv("10000000000000", &n); 217 | mu_assert_int_eq(true, overflow); 218 | overflow = atoiv("21474836480000000", &n); 219 | mu_assert_int_eq(true, overflow); 220 | overflow = atoiv("-2147483649", &n); 221 | mu_assert_int_eq(true, overflow); 222 | overflow = atoiv("-21474836490000", &n); 223 | mu_assert_int_eq(true, overflow); 224 | } 225 | 226 | MU_TEST(test_reverse_array) 227 | { 228 | int array1[] = { 0, 1, 2, 3, 4 }; 229 | int array2[] = { 0, 1, 2, 3, 4, 5 }; 230 | 231 | reverse_array(array1, 5); 232 | mu_assert_int_eq(4, array1[0]); 233 | mu_assert_int_eq(3, array1[1]); 234 | mu_assert_int_eq(2, array1[2]); 235 | mu_assert_int_eq(1, array1[3]); 236 | mu_assert_int_eq(0, array1[4]); 237 | reverse_array(array2, 6); 238 | mu_assert_int_eq(5, array2[0]); 239 | mu_assert_int_eq(4, array2[1]); 240 | mu_assert_int_eq(3, array2[2]); 241 | mu_assert_int_eq(2, array2[3]); 242 | mu_assert_int_eq(1, array2[4]); 243 | mu_assert_int_eq(0, array2[5]); 244 | } 245 | 246 | MU_TEST_SUITE(test_suite_general) 247 | { 248 | MU_RUN_TEST(test_abs); 249 | MU_RUN_TEST(test_binary_search); 250 | MU_RUN_TEST(test_atoiv); 251 | MU_RUN_TEST(test_reverse_array); 252 | } 253 | 254 | /* 255 | ** ------------------ 256 | ** --- Sort Tests --- 257 | ** ------------------ 258 | */ 259 | 260 | MU_TEST(test_index) 261 | { 262 | int size = 12; 263 | int list[] = { 11, 8, 1, 4, 7, 9, 6, 10, 12, 5, 3, 2 }; 264 | 265 | t_stack *a; 266 | 267 | a = initialize(64); 268 | memcpy(a->array, list, size * sizeof(*list)); 269 | a->top = 11; 270 | index_stack(&a); 271 | mu_assert_int_eq(10, a->array[0]); 272 | mu_assert_int_eq(7, a->array[1]); 273 | mu_assert_int_eq(0, a->array[2]); 274 | mu_assert_int_eq(3, a->array[3]); 275 | mu_assert_int_eq(6, a->array[4]); 276 | mu_assert_int_eq(8, a->array[5]); 277 | mu_assert_int_eq(1, a->array[11]); 278 | free_stack(a); 279 | 280 | size = 7; 281 | int list2[] = { -2147483648, 2100, 220010, -1, 7, 210815, 121 }; 282 | 283 | a = initialize(64); 284 | memcpy(a->array, list2, size * sizeof(*list)); 285 | a->top = 6; 286 | index_stack(&a); 287 | mu_assert_int_eq(0, a->array[0]); 288 | mu_assert_int_eq(4, a->array[1]); 289 | mu_assert_int_eq(6, a->array[2]); 290 | mu_assert_int_eq(1, a->array[3]); 291 | } 292 | 293 | //MU_TEST(test_push_closest) 294 | //{ 295 | // int size = 12; 296 | // int list[] = { 11, 8, 1, 4, 7, 9, 6, 10, 12, 5, 3, 2 }; 297 | // 298 | // t_stack *a; 299 | // t_stack *b; 300 | // 301 | // a = initialize(64); 302 | // b = initialize(64); 303 | // memcpy(a->array, list, size * sizeof(*list)); 304 | // a->top = 11; 305 | // push_closest(7, a, b); 306 | // mu_assert_int_eq(2, b->array[0]); 307 | // push_closest(7, a, b); 308 | // mu_assert_int_eq(3, b->array[1]); 309 | // push_closest(7, a, b); 310 | // mu_assert_int_eq(5, b->array[2]); 311 | // push_closest(7, a, b); 312 | // mu_assert_int_eq(6, b->array[3]); 313 | // push_closest(7, a, b); 314 | // mu_assert_int_eq(6, b->array[0]); 315 | // mu_assert_int_eq(5, b->array[1]); 316 | // mu_assert_int_eq(2, b->array[2]); 317 | // mu_assert_int_eq(3, b->array[3]); 318 | //} 319 | // 320 | // 321 | //MU_TEST(test_push_chunk) 322 | //{ 323 | // int size = 12; 324 | // int list[] = { 11, 8, 1, 4, 7, 9, 6, 10, 12, 5, 3, 2 }; 325 | // 326 | // t_stack *a; 327 | // t_stack *b; 328 | // 329 | // a = initialize(64); 330 | // b = initialize(64); 331 | // memcpy(a->array, list, size * sizeof(*list)); 332 | // a->top = 11; 333 | // push_chunk(a, b); 334 | // mu_assert_int_eq(-1, a->top); 335 | // mu_assert_int_eq(1, b->array[0]); 336 | // mu_assert_int_eq(2, b->array[1]); 337 | // mu_assert_int_eq(3, b->array[2]); 338 | // mu_assert_int_eq(4, b->array[3]); 339 | // mu_assert_int_eq(5, b->array[4]); 340 | // mu_assert_int_eq(6, b->array[5]); 341 | //} 342 | 343 | MU_TEST_SUITE(test_suite_sort) 344 | { 345 | //int fd; 346 | 347 | //fd = dup(STDOUT_FILENO); 348 | //close(STDOUT_FILENO); 349 | MU_RUN_TEST(test_index); 350 | //MU_RUN_TEST(test_push_closest); 351 | //MU_RUN_TEST(test_push_chunk); 352 | //dup2(fd, STDOUT_FILENO); 353 | } 354 | 355 | /* 356 | ** ------------------------- 357 | ** --- Integration Tests --- 358 | ** ------------------------- 359 | */ 360 | 361 | #include 362 | #include 363 | 364 | //MU_TEST(test_already_sorted) 365 | //{ 366 | // int child; 367 | // 368 | // if ((child = fork()) < 0) 369 | // return ; 370 | // else if (child == 0) 371 | // { 372 | // execlp("./push_swap", "") 373 | // 374 | // } 375 | // else 376 | // { 377 | // wait(NULL); 378 | // } 379 | // 380 | // 381 | //} 382 | 383 | 384 | //MU_TEST_SUITE(test_suite_integrated) 385 | //{ 386 | // //int fd; 387 | // 388 | // //fd = dup(STDOUT_FILENO); 389 | // //close(STDOUT_FILENO); 390 | // MU_RUN_TEST(test_already_sorted); 391 | // //dup2(fd, STDOUT_FILENO); 392 | // 393 | //} 394 | 395 | 396 | 397 | int main(void) 398 | { 399 | MU_RUN_SUITE(test_suite_stack); 400 | MU_RUN_SUITE(test_suite_general); 401 | MU_RUN_SUITE(test_suite_sort); 402 | //MU_RUN_SUITE(test_suite_integrated); 403 | MU_REPORT(); 404 | return (MU_EXIT_CODE); 405 | } 406 | --------------------------------------------------------------------------------