From 2776ee1ebcb7d52ccfac8f8174db7de3abdba5d8 Mon Sep 17 00:00:00 2001 From: Maieul BOYER Date: Thu, 11 Jan 2024 21:28:36 +0100 Subject: [PATCH] trying to work --- .clang-format | 9 + .clangd | 16 ++ .gitignore | 57 ++++ .gitmodules | 3 + Makefile | 135 +++++++++ flake.nix | 39 +++ gen.list | 6 + include/app/dup_state.h | 26 ++ include/app/element.h | 25 ++ include/app/lis.h | 22 ++ include/app/moves.h | 37 +++ include/app/state.h | 28 ++ input.toml | 40 +++ mecstd | 1 + push_swap | Bin 0 -> 98944 bytes src.list | 8 + src/app/lis/lis.c | 231 +++++++++++++++ src/app/lis/lower_bound.c | 11 + src/app/main.c | 180 ++++++++++++ src/app/moves.c | 44 +++ src/app/moves/push.c | 37 +++ src/app/moves/rev_rotate.c | 35 +++ src/app/moves/rotate.c | 36 +++ src/app/moves/swap.c | 39 +++ subject.txt | 556 +++++++++++++++++++++++++++++++++++++ 25 files changed, 1621 insertions(+) create mode 100644 .clang-format create mode 100644 .clangd create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 Makefile create mode 100644 flake.nix create mode 100644 gen.list create mode 100644 include/app/dup_state.h create mode 100644 include/app/element.h create mode 100644 include/app/lis.h create mode 100644 include/app/moves.h create mode 100644 include/app/state.h create mode 100644 input.toml create mode 160000 mecstd create mode 100755 push_swap create mode 100644 src.list create mode 100644 src/app/lis/lis.c create mode 100644 src/app/lis/lower_bound.c create mode 100644 src/app/main.c create mode 100644 src/app/moves.c create mode 100644 src/app/moves/push.c create mode 100644 src/app/moves/rev_rotate.c create mode 100644 src/app/moves/rotate.c create mode 100644 src/app/moves/swap.c create mode 100644 subject.txt diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..6b13f20 --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: Microsoft +IndentWidth: 4 +ColumnLimit: 80 +UseTab: Always +SortIncludes: CaseInsensitive +IndentPPDirectives: AfterHash +PPIndentWidth: 1 +AllowShortIfStatementsOnASingleLine: false +AlignConsecutiveDeclarations: true diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..1c222e6 --- /dev/null +++ b/.clangd @@ -0,0 +1,16 @@ +CompileFlags: # Tweak the parse settings + Add: + - "-I/usr/include/" + - "-I/home/maix/school/push_swap/mecstd/include/" + - "-I/home/maix/school/push_swap/mecstd/output/include/" + - "-I/home/maix/school/push_swap/mecstd/generic_sources/header/" + - "-I/home/maix/school/push_swap/include/" + - "-I/home/maix/school/push_swap/output/include/" + - "-I/home/maix/school/push_swap/generic_sources/header/" + - "-I/home/maiboyer/Documents/ring-1/push_swap/mecstd/include/" + - "-I/home/maiboyer/Documents/ring-1/push_swap/mecstd/output/include/" + - "-I/home/maiboyer/Documents/ring-1/push_swap/mecstd/generic_sources/header/" + - "-I/home/maiboyer/Documents/ring-1/push_swap/include/" + - "-I/home/maiboyer/Documents/ring-1/push_swap/output/include/" + - "-I/home/maiboyer/Documents/ring-1/push_swap/generic_sources/header/" + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ce2fd6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +# Prerequisites +*.d + +# Object files +*.o +*.ko +*.obj +*.elf + +# Linker output +*.ilk +*.map +*.exp + +# Precompiled Headers +*.gch +*.pch + +# Libraries +*.lib +*.a +*.la +*.lo + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex + +# Debug files +*.dSYM/ +*.su +*.idb +*.pdb + +# Kernel Module Compile Results +*.mod* +*.cmd +.tmp_versions/ +modules.order +Module.symvers +Mkfile.old +dkms.conf + +./generic +.direnv +test +output/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..92ca1ba --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "mecstd"] + path = mecstd + url = git@github.com:Maix0/mecstd.git diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..780fe88 --- /dev/null +++ b/Makefile @@ -0,0 +1,135 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: maiboyer +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2023/11/03 13:20:01 by maiboyer #+# #+# # +# Updated: 2024/01/11 14:14:03 by maiboyer ### ########.fr # +# # +# **************************************************************************** # + +define_module = $(addprefix $(1)/, $(2)) + +BUILD_DIR = build +SRC_DIR = src +INCLUDE_DIR = include +LIBS_DIR = . +GENERIC_DIR = output/src +GENERIC_INCLUDE = output/include + +ifeq ($(MAKECMDGOALS), bonus) + CFLAGS += -DBONUS + BUILD_DIR := $(BUILD_DIR)/bonus/ +endif + +NAME = push_swap +LIB_NAME ?= +TARGET = $(NAME) +CC = clang +CFLAGS += -Wall -Wextra -Werror -g2 -lme -L$(BUILD_DIR) -Wno-unused-command-line-argument -MMD +BONUS_FILES = +LIBS_NAME = mecstd +SUBJECT_URL = 'https://cdn.intra.42.fr/pdf/pdf/118610/en.subject.pdf' + +GENERIC_FILES = $(shell cat ./gen.list) +SRC_FILES = $(shell cat ./src.list) +BONUS = $(addsuffix .c,$(addprefix $(SRC_DIR)/,$(BONUS_FILES))) +SRC = $(addsuffix .c,$(addprefix $(SRC_DIR)/,$(SRC_FILES))) \ + $(addsuffix .c,$(addprefix $(GENERIC_DIR)/,$(GENERIC_FILES))) +BONUS_OBJ = $(addsuffix .o,$(addprefix $(BUILD_DIR)/,$(BONUS_FILES))) +OBJ = $(addsuffix .o,$(addprefix $(BUILD_DIR)/,$(SRC_FILES))) \ + $(addsuffix .o,$(addprefix $(BUILD_DIR)/,$(GENERIC_FILES))) +DEPS = $(addsuffix .d,$(addprefix $(BUILD_DIR)/,$(SRC_FILES))) \ + $(addsuffix .d,$(addprefix $(BUILD_DIR)/,$(GENERIC_FILES))) +LIBS = $(addprefix $(LIBS_DIR)/,$(LIBS_NAME)) +INCLUDES = $(addprefix -I,$(INCLUDE_DIR) $(GENERIC_INCLUDE) $(LIBS) $(addsuffix /include,$(LIBS))) +COL_GRAY = \\e[90m +COL_WHITE = \\e[37m +COL_GREEN = \\e[32m +COL_BOLD = \\e[1m +COL_RESET = \\e[0m + + +.PHONY: remove_name clean all fclean bonus format re generate_filelist subject get_lib + +all: $(NAME) + +bonus: all + @printf \\n$(COL_GRAY)Building\ Output\ \(with\ bonus\)\ $(COL_WHITE)$(COL_BOLD)%-28s$(COL_RESET)\ \ + $(NAME) + @printf $(COL_RESET)$(COL_GREEN)done$(COL_RESET)\\n + +get_lib: + @printf $(LIB_NAME)/$(NAME) + +$(NAME): $(OBJ) libs_build + @printf \\n$(COL_GRAY)Building\ Output\ $(COL_WHITE)$(COL_BOLD)%-28s$(COL_RESET)\ \ + $(NAME) + @$(CC) $(INCLUDES) $(OBJ) $(CFLAGS) -o $(NAME) + @#ar rcs $(BUILD_DIR)/$(NAME) $(OBJ) + @printf $(COL_GREEN)done$(COL_RESET)\\n + +libs_build: + @- $(foreach LIB,$(LIBS),\ + printf \\n; \ + printf $(COL_GRAY)Building\ library\ $(COL_RESET); \ + printf $(COL_WHITE)$(COL_BOLD)%-25s$(COL_RESET)\\n $(LIB); \ + make LIB_NAME=$(LIB)/ BUILD_DIR=$(realpath $(BUILD_DIR)) -C $(LIB) --no-print-directory all; \ + printf \\n; \ + ) + +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c + @mkdir -p $(dir $@) + @printf $(COL_GRAY)Building\ $(COL_BOLD)$(COL_WHITE)%-50s\ $(LIB_NAME)$< + @$(CC) $(CFLAGS) $(WERROR) $(INCLUDES) -c $< -o $@ + @printf $(COL_RESET)$(COL_GREEN)done$(COL_RESET)\\n + +$(BUILD_DIR)/%.o: $(GENERIC_DIR)/%.c + @mkdir -p $(dir $@) + @printf $(COL_GRAY)Building\ $(COL_BOLD)$(COL_WHITE)%-50s\ $(LIB_NAME)$< + @$(CC) $(CFLAGS) $(WERROR) $(INCLUDES) -c $< -o $@ + @printf $(COL_RESET)$(COL_GREEN)done$(COL_RESET)\\n + +clean: + @- $(foreach LIB,$(LIBS), \ + make clean LIB_NAME=$(LIB)/ BUILD_DIR=$(realpath $(BUILD_DIR)) -C $(LIB) --no-print-directory || true;\ + ) + @- $(if $(LIB_NAME),,\ + printf $(COL_WHITE)Clearing\ Artefacts\ ; \ + printf $(COL_GRAY)\%-25s$(COL_RESET)\ \($(BUILD_DIR)\); \ + rm -rf $(BUILD_DIR); \ + printf $(COL_GREEN)done$(COL_RESET)\\n; \ + ) + @echo >/dev/null + +fclean: clean + @- $(foreach LIB,$(LIBS), \ + make fclean LIB_NAME=$(LIB)/ BUILD_DIR=$(realpath $(BUILD_DIR)) -C $(LIB) --no-print-directory || true;\ + ) + @printf $(COL_WHITE)Clearing\ Output\ $(COL_GRAY)%-28s$(COL_RESET)\ \ + \($(LIB_NAME)$(NAME)\) + @rm -f $(BUILD_DIR)$(NAME) + @printf $(COL_GREEN)done$(COL_RESET)\\n + +re: fclean all + +generate_filelist: + @/usr/bin/env zsh -c "tree -iFf --noreport output | rg '^output/src/(.*)\.c\$$' --replace '\$$1' | sort -u" > ./gen.list + @/usr/bin/env zsh -c "tree -iFf --noreport src | rg '^src/(.*)\.c\$$' --replace '\$$1' | sort -u" > ./src.list + +format: + @zsh -c "c_formatter_42 **/*.c **/*.h" + +subject: subject.txt + @bat --plain subject.txt + +subject.txt: + @curl $(SUBJECT_URL) | pdftotext -layout -nopgbrk - subject.txt + +fuck_raphael: + @echo "Oh que oui~~~\net jte nioc" + +-include $(DEPS) + diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..24419ec --- /dev/null +++ b/flake.nix @@ -0,0 +1,39 @@ +{ + description = "Flake utils demo"; + + inputs = { + flake-utils.url = "github:numtide/flake-utils"; + generic_c.url = "github:maix0/generic_c"; + c_formatter_42.url = "github:maix0/c_formatter_42-flake"; + }; + outputs = { + self, + nixpkgs, + flake-utils, + generic_c, + c_formatter_42, + }: + flake-utils.lib.eachDefaultSystem ( + system: let + pkgs = nixpkgs.legacyPackages.${system}; + in { + devShell = pkgs.mkShell { + packages = [ + pkgs.xorg.libXext + pkgs.xorg.libX11 + pkgs.clang + pkgs.clang-tools + pkgs.norminette + generic_c.packages.${system}.default + c_formatter_42.packages.${system}.default + pkgs.poppler_utils + pkgs.minilibx + pkgs.valgrind + pkgs.libbsd + pkgs.tree + pkgs.fastmod + ]; + }; + } + ); +} diff --git a/gen.list b/gen.list new file mode 100644 index 0000000..7728ddd --- /dev/null +++ b/gen.list @@ -0,0 +1,6 @@ +vec/vec_element +vec/vec_element_functions2 +vec/vec_element_functions3 +vec/vec_i64 +vec/vec_i64_functions2 +vec/vec_i64_functions3 diff --git a/include/app/dup_state.h b/include/app/dup_state.h new file mode 100644 index 0000000..69abfeb --- /dev/null +++ b/include/app/dup_state.h @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* dup_state.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 15:58:29 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 15:59:29 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef DUP_STATE_H +#define DUP_STATE_H + +#include "app/element.h" +#include "me/types.h" + +typedef struct s_dup_state +{ + t_element *lhs; + t_usize index_to_skip; + bool found_dup; +} t_dup_state; + +#endif /* DUP_STATE_H */ diff --git a/include/app/element.h b/include/app/element.h new file mode 100644 index 0000000..74d625f --- /dev/null +++ b/include/app/element.h @@ -0,0 +1,25 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* element.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 14:28:41 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 14:34:27 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ELEMENT_H +#define ELEMENT_H + +#include "me/types.h" + +typedef struct s_element +{ + t_i64 value; +} t_element; + +void free_element(t_element elem); + +#endif /* ELEMENT_H */ diff --git a/include/app/lis.h b/include/app/lis.h new file mode 100644 index 0000000..c1f757b --- /dev/null +++ b/include/app/lis.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lis.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 19:03:30 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 20:50:43 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef LIS_H +#define LIS_H + +#include "me/types.h" +#include "me/vec/vec_element.h" +#include "me/vec/vec_i64.h" + +t_vec_i64 lis(t_vec_element *elements); + +#endif /* LIS_H */ diff --git a/include/app/moves.h b/include/app/moves.h new file mode 100644 index 0000000..677abe7 --- /dev/null +++ b/include/app/moves.h @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* moves.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:13:08 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 16:18:49 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MOVES_H +#define MOVES_H + +#include "app/element.h" +#include "app/state.h" +#include "me/types.h" + +typedef enum e_move +{ + SWAP_A = 1 << 0, + SWAP_B = 1 << 1, + SWAP_BOTH = SWAP_A | SWAP_B, + PUSH_A = 1 << 2, + PUSH_B = 1 << 3, + ROTATE_A = 1 << 4, + ROTATE_B = 1 << 5, + ROTATE_BOTH = ROTATE_A | ROTATE_B, + REVERSE_ROTATE_A = 1 << 6, + REVERSE_ROTATE_B = 1 << 7, + REVERSE_ROTATE_BOTH = REVERSE_ROTATE_A | REVERSE_ROTATE_B, +} t_move; + +void do_move(t_move m, t_state *s); + +#endif /* MOVES_H */ diff --git a/include/app/state.h b/include/app/state.h new file mode 100644 index 0000000..15d0529 --- /dev/null +++ b/include/app/state.h @@ -0,0 +1,28 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* state.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 14:27:25 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 14:36:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef STATE_H +#define STATE_H + +#include "me/types.h" +#include "me/vec/vec_element.h" + +typedef struct s_state +{ + t_vec_element stack_a; + t_vec_element stack_b; +} t_state; + +t_state parses_arguments(t_usize count, t_str nums[]); +void free_state(t_state state); + +#endif /* STATE_H */ diff --git a/input.toml b/input.toml new file mode 100644 index 0000000..9371862 --- /dev/null +++ b/input.toml @@ -0,0 +1,40 @@ +[definition.vec] +headers = ["mecstd/generic_sources/header/vec_C__PREFIX__.h__TEMPLATE__"] +sources = [ + "mecstd/generic_sources/src/vec_C__PREFIX__.c__TEMPLATE__", + "mecstd/generic_sources/src/vec_C__PREFIX___functions2.c__TEMPLATE__", + "mecstd/generic_sources/src/vec_C__PREFIX___functions3.c__TEMPLATE__", +] +replace.C__TYPENAME__ = "type" +replace.C__TYPEHEADER__ = "header_include" +replace.C__PREFIX__ = "prefix" +replace.C__PREFIXUP__ = "prefix" + + +[definition.hashmap] +headers = ["mecstd/generic_sources/header/hashmap_C__PREFIX__.h__TEMPLATE__"] +sources = [ + "mecstd/generic_sources/src/hashmap_C__PREFIX__.c__TEMPLATE__", + "mecstd/generic_sources/src/hashmap_C__PREFIX___utils.c__TEMPLATE__", +] +replace.C__VALTYPE__ = "type" +replace.C__KEYTYPE__ = "type" +replace.C__TYPEHEADER__ = "header_include" +replace.C__PREFIX__ = "prefix" +replace.C__PREFIXUP__ = "prefix" + +[[create.vec]] +sources_output = "src/vec/" +headers_output = "include/me/vec/" +replace.C__TYPENAME__ = "t_element" +replace.C__TYPEHEADER__ = '#include "app/element.h"' +replace.C__PREFIX__ = "element" +replace.C__PREFIXUP__ = "ELEMENT" + +[[create.vec]] +sources_output = "src/vec/" +headers_output = "include/me/vec/" +replace.C__TYPENAME__ = "t_i64" +replace.C__TYPEHEADER__ = '' +replace.C__PREFIX__ = "i64" +replace.C__PREFIXUP__ = "I64" diff --git a/mecstd b/mecstd new file mode 160000 index 0000000..f9c81ca --- /dev/null +++ b/mecstd @@ -0,0 +1 @@ +Subproject commit f9c81caf38361c927fa81f72a1e832bbb619e161 diff --git a/push_swap b/push_swap new file mode 100755 index 0000000000000000000000000000000000000000..865eaa529bcb0321329fe083a7e918e83e7d7755 GIT binary patch literal 98944 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 literal 0 HcmV?d00001 diff --git a/src.list b/src.list new file mode 100644 index 0000000..1fef610 --- /dev/null +++ b/src.list @@ -0,0 +1,8 @@ +app/lis/lis +app/lis/lower_bound +app/main +app/moves +app/moves/push +app/moves/rev_rotate +app/moves/rotate +app/moves/swap diff --git a/src/app/lis/lis.c b/src/app/lis/lis.c new file mode 100644 index 0000000..b8e85b3 --- /dev/null +++ b/src/app/lis/lis.c @@ -0,0 +1,231 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lis.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 18:50:35 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 21:27:36 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/element.h" +#include "me/mem/mem_alloc_array.h" +#include "me/printf/printf.h" +#include "me/vec/vec_element.h" +#include "me/vec/vec_i64.h" +#include + +/* +P = array of length N +M = array of length N + 1 +M[0] = -1 // undefined so can be set to any value + +L = 0 +for i in range 0 to N-1: //N-1 included + // Binary search for the smallest positive l ≤ L + // such that X[M[l]] > X[i] + lo = 1 + hi = L + 1 + while lo < hi: + mid = lo + floor((hi-lo)/2) // lo <= mid < hi + if X[M[mid]] >= X[i] + hi = mid + else: // if X[M[mid]] < X[i] + lo = mid + 1 + + // After searching, lo == hi is 1 greater than the + // length of the longest prefix of X[i] + newL = lo + + // The predecessor of X[i] is the last index of + // the subsequence of length newL-1 + P[i] = M[newL-1] + M[newL] = i + + if newL > L: + // If we found a subsequence longer than any we've + // found yet, update L + L = newL + +// Reconstruct the longest increasing subsequence +// It consists of the values of X at the L indices: +// ..., P[P[M[L]]], P[M[L]], M[L] +S = array of length L +k = M[L] +for j in range L-1 to 0: //0 included + S[j] = X[k] + k = P[k] + +return S +*/ + +// static t_i64 binary_search(t_i64 L, t_i64 i, t_i64 m[], t_vec_element +// *elements) +//{ +// return (low); +//} + +// static t_vec_i64 lis_inner(t_vec_element *elements, t_i64 L, t_i64 m[], +// t_i64 p[]) +//{ +// } + +/* +/// Finds one of the [longest increasing subsequences][1] +/// from the subsequence created by applying `selector` on each item in `items`. +/// The result is a vector of indices within `items` +/// corresponding to one of the longest increasing subsequences. +/// +/// [1]: https://en.wikipedia.org/wiki/Longest_increasing_subsequence +pub fn lis I>(items: &[T], selector: F) -> Vec { + // This algorithm is adapted from + // +http://www.algorithmist.com/index.php?title=Longest_Increasing_Subsequence.cpp&oldid=13595 + + let mut result = Vec::new(); + + // If `items` is empty, then the result is also empty. + if items.is_empty() { + return result; + } + + // This vector stores, for each item, + // the index of the largest item prior to itself that is smaller than +itself. + // We'll use this vector at the end to build the final result. + let mut previous_chain = vec![0; items.len()]; + + // Initially, we assume that the first item is part of the result. + // We will replace this index later if that's not the case. + result.push(0); + + for i in 1..items.len() { + // If the next item is greater than the last item of the current longest +subsequence, + // push its index at the end of the result and continue. + if selector(&items[*result.last().unwrap()]) < selector(&items[i]) { + previous_chain[i] = *result.last().unwrap(); + result.push(i); + continue; + } + + // Perform a binary search to find the index of an item in `result` to +overwrite. + // We want to overwrite an index that refers to the smallest item that +is larger than `items[i]`. + // If there is no such item, then we do nothing. + let comparator = |&result_index| { + use std::cmp::Ordering; + + // We don't return Ordering::Equal when we find an equal value, + // because we want to find the index of the first equal value. + if selector(&items[result_index]) < selector(&items[i]) { + Ordering::Less + } else { + Ordering::Greater + } + }; + + let next_element_index = match result.binary_search_by(comparator) { + Ok(index) | Err(index) => index, + }; + + if selector(&items[i]) < selector(&items[result[next_element_index]]) { + if next_element_index > 0 { + previous_chain[i] = result[next_element_index - 1]; + } + + result[next_element_index] = i; + } + } + + // The last item in `result` is correct, + // but we might have started overwriting earlier items + // with what could have been a longer subsequence. + // Walk back `previous_chain` to restore the proper subsequence. + let mut u = result.len(); + let mut v = *result.last().unwrap(); + while u != 0 { + u -= 1; + result[u] = v; + v = previous_chain[v]; + } + + result +} +*/ + +t_i64 binary_search(t_vec_element *items, t_i64 i) +{ + t_i64 lo; + t_i64 hi; + t_i64 mid; + + lo = 0; + hi = items->len; + while (lo < hi) + { + mid = lo + (hi - lo) / 2; + if (items->buffer[mid].value < items->buffer[i].value) + lo = mid + 1; + else + hi = mid; + } + return (lo); +} + +void lis_inner(t_vec_element *elements, t_vec_i64 *result, + t_vec_i64 *previous_chain) +{ + t_i64 i; + t_i64 next_element_index; + + i = 1; + while (i < (t_i64)elements->len) + { + if (elements->buffer[result->buffer[result->len - 1]].value < + elements->buffer[i].value) + { + previous_chain->buffer[i] = result->buffer[result->len - 1]; + vec_i64_push(result, i++); + continue; + } + next_element_index = binary_search(elements, i); + if (elements->buffer[i].value > + elements->buffer[result->buffer[next_element_index]].value) + { + if (next_element_index > 0) + previous_chain->buffer[i] = + result->buffer[next_element_index - 1]; + result->buffer[next_element_index] = i; + } + i++; + } +} + +t_vec_i64 lis(t_vec_element *elements) +{ + t_vec_i64 result; + t_i64 u; + t_i64 v; + t_vec_i64 previous_chain; + + result = vec_i64_new(elements->len, NULL); + if (elements->len == 0) + return (result); + previous_chain = vec_i64_new(elements->len, NULL); + previous_chain.len = elements->len; + vec_i64_push(&result, 0); + lis_inner(elements, &result, &previous_chain); + u = result.len; + v = result.buffer[result.len - 1]; + while (u != 0) + { + u--; + result.buffer[u] = v; + v = previous_chain.buffer[v]; + } + return (result); +} diff --git a/src/app/lis/lower_bound.c b/src/app/lis/lower_bound.c new file mode 100644 index 0000000..79bceeb --- /dev/null +++ b/src/app/lis/lower_bound.c @@ -0,0 +1,11 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lower_bound.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 18:17:23 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 19:17:19 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ diff --git a/src/app/main.c b/src/app/main.c new file mode 100644 index 0000000..755a321 --- /dev/null +++ b/src/app/main.c @@ -0,0 +1,180 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 14:14:18 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 21:03:29 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/dup_state.h" +#include "app/element.h" +#include "app/lis.h" +#include "app/moves.h" +#include "app/state.h" +#include "me/convert/atoi.h" +#include "me/convert/itoa.h" +#include "me/printf/printf.h" +#include "me/string/str_clone.h" +#include "me/types.h" +#include "me/vec/vec_element.h" +#include +#include +#include +#include +#include + +void free_element(t_element elem) +{ + (void)(elem); +} + +void free_state(t_state state) +{ + vec_element_free(state.stack_a); + vec_element_free(state.stack_b); +} + +t_error parse_element(t_str s, t_element *e) +{ + t_usize i; + t_i64 value; + t_element out; + + if (s == NULL || e == NULL) + return (ERROR); + i = 0; + if (s[i] == '-' || s[i] == '+') + i++; + while (s[i] && s[i] >= '0' && s[i] <= '9') + i++; + if (s[i] != '\0') + return (ERROR); + value = me_atoi_64(s); + if (value > INT_MAX || value < INT_MIN) + return (ERROR); + out.value = value; + *e = out; + return (NO_ERROR); +} +void check_eq(t_usize i, t_element *rhs, t_dup_state *dup_state) +{ + dup_state->found_dup = + dup_state->found_dup || + (i != dup_state->index_to_skip && rhs->value == dup_state->lhs->value); +} + +void check_no_duplicate(t_vec_element *stack, t_vec_element *to_free_in_need) +{ + t_usize i; + t_dup_state s; + + i = 0; + while (i < stack->len) + { + s = (t_dup_state){ + .lhs = &stack->buffer[i], + .index_to_skip = i, + .found_dup = false, + }; + vec_element_iter(stack, (void (*)())check_eq, &s); + if (s.found_dup) + return (me_eprintf("Error:\nDuplicate numbers (%i)\n", + stack->buffer[i]), + vec_element_free(*stack), + vec_element_free(*to_free_in_need), exit(1)); + i++; + } +} + +t_state parses_arguments(t_usize count, t_str nums[]) +{ + t_state out; + t_usize i; + t_element e; + + i = 0; + out.stack_a = vec_element_new(count * 2, free_element); + out.stack_b = vec_element_new(count * 2, free_element); + while (i < count) + { + if (parse_element(nums[i], &e)) + (me_eprintf("Error:\nArgument '%s' isn't a valid number for this " + "program!\n", + nums[i]), + vec_element_free(out.stack_a), vec_element_free(out.stack_b), + exit(1)); + vec_element_push(&out.stack_b, e); + i++; + } + while (!vec_element_pop(&out.stack_b, &e)) + vec_element_push(&out.stack_a, e); + check_no_duplicate(&out.stack_a, &out.stack_b); + return out; +} + +#define LEFT(str, w) \ + ({ \ + int m = w + strlen(str); \ + m % 2 ? (m + 1) / 2 : m / 2; \ + }) + +#define RIGHT(str, w) \ + ({ \ + int m = w - strlen(str); \ + m % 2 ? (m - 1) / 2 : m / 2; \ + }) + +#define STR_CENTER(str, width) LEFT(str, width), str, RIGHT(str, width), "" + +#define STACK_WIDTH 12 +void print_state(t_state *s) +{ + t_usize max_len; + + if (s->stack_a.len > s->stack_b.len) + max_len = s->stack_a.len; + else + max_len = s->stack_b.len; + printf("|%*s%*s|%*s%*s|\n", STR_CENTER("Stack A", STACK_WIDTH), + STR_CENTER("Stack B", STACK_WIDTH)); + for (t_usize i = 0; i < max_len; i++) + { + t_str s_a; + t_str s_b; + + if (i < s->stack_a.len) + s_a = me_itoa(s->stack_a.buffer[s->stack_a.len - i - 1].value); + else + s_a = str_clone(""); + if (i < s->stack_b.len) + s_b = me_itoa(s->stack_b.buffer[s->stack_b.len - i - 1].value); + else + s_b = str_clone(""); + printf("|%*s%*s|%*s%*s|\n", STR_CENTER(s_a, STACK_WIDTH), + STR_CENTER(s_b, STACK_WIDTH)); + free(s_a); + free(s_b); + } + printf("\n"); +} + +int main(t_i32 argc, t_str argv[]) +{ + t_state state; + t_vec_i64 o; + + state = parses_arguments(--argc, ++argv); + print_state(&state); + o = lis(&state.stack_a); + printf("len = %zu", o.len); + for (t_usize i = 0; i < o.len; i++) + printf("%zi\n", (t_isize)o.buffer[i]); + printf("\n"); + free_state(state); + vec_i64_free(o); + return (0); +} diff --git a/src/app/moves.c b/src/app/moves.c new file mode 100644 index 0000000..a24428c --- /dev/null +++ b/src/app/moves.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* moves.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:17:26 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 16:31:56 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/moves.h" +#include "app/element.h" +#include "app/state.h" + +void push_a(t_state *s); +void push_b(t_state *s); +void swap_a(t_state *s); +void swap_b(t_state *s); +void rotate_a(t_state *s); +void rotate_b(t_state *s); +void rev_rotate_a(t_state *s); +void rev_rotate_b(t_state *s); + +void do_move(t_move m, t_state *s) +{ + if (m & PUSH_A) + push_a(s); + if (m & PUSH_B) + push_b(s); + if (m & SWAP_A) + swap_a(s); + if (m & SWAP_B) + swap_b(s); + if (m & ROTATE_A) + rotate_a(s); + if (m & ROTATE_B) + rotate_b(s); + if (m & REVERSE_ROTATE_A) + rev_rotate_a(s); + if (m & REVERSE_ROTATE_B) + rev_rotate_b(s); +} diff --git a/src/app/moves/push.c b/src/app/moves/push.c new file mode 100644 index 0000000..26379bf --- /dev/null +++ b/src/app/moves/push.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* push.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:22:54 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 17:17:45 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/element.h" +#include "app/state.h" +#include "me/vec/vec_element.h" + +static inline void push_inner(t_vec_element *to, t_vec_element *from, + t_const_str tag) +{ + t_element e; + + (void)(tag); + if (from->len == 0) + return; + vec_element_pop(from, &e); + vec_element_push(to, e); +} + +void push_a(t_state *s) +{ + push_inner(&s->stack_a, &s->stack_b, "Push A"); +} + +void push_b(t_state *s) +{ + push_inner(&s->stack_b, &s->stack_a, "Push B"); +} diff --git a/src/app/moves/rev_rotate.c b/src/app/moves/rev_rotate.c new file mode 100644 index 0000000..7344e6c --- /dev/null +++ b/src/app/moves/rev_rotate.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* rev_rotate.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:26:04 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 17:31:44 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/element.h" +#include "app/state.h" + +static inline void rev_rotate_inner(t_vec_element *stack, t_const_str tag) +{ + t_element e; + + (void)(tag); + if (stack->len <= 1) + return; + vec_element_pop(stack, &e); + vec_element_push_front(stack, e); +} + +void rev_rotate_a(t_state *s) +{ + rev_rotate_inner(&s->stack_a, "RevRotate A"); +} + +void rev_rotate_b(t_state *s) +{ + rev_rotate_inner(&s->stack_b, "RevRotate B"); +} diff --git a/src/app/moves/rotate.c b/src/app/moves/rotate.c new file mode 100644 index 0000000..6a78f8f --- /dev/null +++ b/src/app/moves/rotate.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* rotate.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:26:04 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 17:31:20 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/element.h" +#include "app/state.h" + + +static inline void rotate_inner(t_vec_element *stack, t_const_str tag) +{ + t_element e; + + (void)(tag); + if (stack->len <= 1) + return; + vec_element_pop(stack, &e); + vec_element_push_front(stack, e); +} + +void rotate_a(t_state *s) +{ + rotate_inner(&s->stack_a, "Rotate A"); +} + +void rotate_b(t_state *s) +{ + rotate_inner(&s->stack_b, "Rotate B"); +} diff --git a/src/app/moves/swap.c b/src/app/moves/swap.c new file mode 100644 index 0000000..62a316d --- /dev/null +++ b/src/app/moves/swap.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* swap.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:26:04 by maiboyer #+# #+# */ +/* Updated: 2024/01/11 17:56:12 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/element.h" +#include "app/state.h" +#include "me/vec/vec_element.h" + +static inline void swap_inner(t_vec_element *stack, t_const_str tag) +{ + t_element first; + t_element second; + + (void)(tag); + if (stack->len <= 1) + return; + vec_element_pop(stack, &first); + vec_element_pop(stack, &second); + vec_element_push(stack, first); + vec_element_push(stack, second); +} + +void swap_a(t_state *s) +{ + swap_inner(&s->stack_a, "Swap A"); +} + +void swap_b(t_state *s) +{ + swap_inner(&s->stack_b, "Swap B"); +} diff --git a/subject.txt b/subject.txt new file mode 100644 index 0000000..83b2e90 --- /dev/null +++ b/subject.txt @@ -0,0 +1,556 @@ + Push_swap + Because Swap_push isn’t as natural + + + + + Summary: +This project will make you sort data on a stack, with a limited set of instructions, using + the lowest possible number of actions. To succeed you’ll have to manipulate various + types of algorithms and choose the most appropriate solution (out of many) for an + optimized data sorting. + + Version: 7 +Contents +I Foreword 2 + +II Introduction 4 + +III Objectives 5 + +IV Common Instructions 6 + +V Mandatory part 8 + V.1 The rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 + V.2 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 + V.3 The "push_swap" program . . . . . . . . . . . . . . . . . . . . . . . . 10 + +VI Bonus part 12 + VI.1 The "checker" program . . . . . . . . . . . . . . . . . . . . . . . . . . 12 + +VII Submission and peer-evaluation 14 + + + + + 1 +Chapter I + +Foreword + + • C + #include + + int main(void) + { + printf("hello, world\n"); + return 0; + } + + + + • ASM + cseg segment + assume cs:cseg, ds:cseg + org 100h + main proc + jmp debut + mess db 'Hello world!$' + debut: + mov dx, offset mess + mov ah, 9 + int 21h + ret + main endp + cseg ends + end main + + + + • LOLCODE + HAI + CAN HAS STDIO? + VISIBLE "HELLO WORLD!" + KTHXBYE + + + + • PHP + + + + + • BrainFuck + ++++++++++[>+++++++>++++++++++>+++>+<<<<-] + >++.>+.+++++++..+++.>++. + <<+++++++++++++++.>.+++.------.--------.>+.>. + + + + + 2 +Push_swap Because Swap_push isn’t as natural + + + • C# + using System; + + public class HelloWorld { + public static void Main () { + Console.WriteLine("Hello world!"); + } + } + + + + • HTML5 + + + + + Hello world ! + + +

Hello World !

+ + + + + + • YASL + "Hello world!" + print + + + + • OCaml + let main () = + print_endline "Hello world !" + + let _ = main () + + + + + 3 +Chapter II + +Introduction + +The Push swap project is a very simple and a highly straightforward algorithm project: +data must be sorted. + + You have at your disposal a set of integer values, 2 stacks, and a set of instructions +to manipulate both stacks. + + Your goal? Write a program in C called push_swap which calculates and displays +on the standard output the smallest program, made of Push swap language instructions, +that sorts the integers received as arguments. + + Easy? + + We’ll see... + + + + + 4 +Chapter III + +Objectives + +Writing a sorting algorithm is always a very important step in a developer’s journey. It +is often the first encounter with the concept of complexity. + + Sorting algorithms and their complexity are part of the classic questions discussed +during job interviews. It’s probably a good time to look at these concepts since you’ll +have to face them at some point. + + The learning objectives of this project are rigor, use of C, and use of basic algorithms. +Especially focusing on their complexity. + + Sorting values is simple. To sort them the fastest way possible is less simple. Especially +because from one integers configuration to another, the most efficient sorting solution can +differ. + + + + + 5 +Chapter IV + +Common Instructions + + • Your project must be written in C. + + • Your project must be written in accordance with the Norm. If you have bonus + files/functions, they are included in the norm check and you will receive a 0 if there + is a norm error inside. + + • Your functions should not quit unexpectedly (segmentation fault, bus error, double + free, etc) apart from undefined behaviors. If this happens, your project will be + considered non functional and will receive a 0 during the evaluation. + + • All heap allocated memory space must be properly freed when necessary. No leaks + will be tolerated. + + • If the subject requires it, you must submit a Makefile which will compile your + source files to the required output with the flags -Wall, -Wextra and -Werror, use + cc, and your Makefile must not relink. + + • Your Makefile must at least contain the rules $(NAME), all, clean, fclean and + re. + + • To turn in bonuses to your project, you must include a rule bonus to your Makefile, + which will add all the various headers, librairies or functions that are forbidden on + the main part of the project. Bonuses must be in a different file _bonus.{c/h} if + the subject does not specify anything else. Mandatory and bonus part evaluation + is done separately. + + • If your project allows you to use your libft, you must copy its sources and its + associated Makefile in a libft folder with its associated Makefile. Your project’s + Makefile must compile the library by using its Makefile, then compile the project. + + • We encourage you to create test programs for your project even though this work + won’t have to be submitted and won’t be graded. It will give you a chance + to easily test your work and your peers’ work. You will find those tests especially + useful during your defence. Indeed, during defence, you are free to use your tests + and/or the tests of the peer you are evaluating. + + • Submit your work to your assigned git repository. Only the work in the git reposi- + tory will be graded. If Deepthought is assigned to grade your work, it will be done + + + 6 +Push_swap Because Swap_push isn’t as natural + + + after your peer-evaluations. If an error happens in any section of your work during + Deepthought’s grading, the evaluation will stop. + + + + + 7 +Chapter V + +Mandatory part + +V.1 The rules + • You have 2 stacks named a and b. + • At the beginning: + + ◦ The stack a contains a random amount of negative and/or positive numbers + which cannot be duplicated. + ◦ The stack b is empty. + + • The goal is to sort in ascending order numbers into stack a. To do so you have the + following operations at your disposal: + + sa (swap a): Swap the first 2 elements at the top of stack a. + Do nothing if there is only one or no elements. + sb (swap b): Swap the first 2 elements at the top of stack b. + Do nothing if there is only one or no elements. + ss : sa and sb at the same time. + 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. + 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. + ra (rotate a): Shift up all elements of stack a by 1. + The first element becomes the last one. + rb (rotate b): Shift up all elements of stack b by 1. + The first element becomes the last one. + rr : ra and rb at the same time. + rra (reverse rotate a): Shift down all elements of stack a by 1. + The last element becomes the first one. + rrb (reverse rotate b): Shift down all elements of stack b by 1. + The last element becomes the first one. + rrr : rra and rrb at the same time. + + + 8 +Push_swap Because Swap_push isn’t as natural + + +V.2 Example +To illustrate the effect of some of these instructions, let’s sort a random list of integers. +In this example, we’ll consider that both stacks grow from the right. + +---------------------------------------------------------------------------------------------------------- +Init a and b: +2 +1 +3 +6 +5 +8 +_ _ +a b +---------------------------------------------------------------------------------------------------------- +Exec sa: +1 +2 +3 +6 +5 +8 +_ _ +a b +---------------------------------------------------------------------------------------------------------- +Exec pb pb pb: +6 3 +5 2 +8 1 +_ _ +a b +---------------------------------------------------------------------------------------------------------- +Exec ra rb (equiv. to rr): +5 2 +8 1 +6 3 +_ _ +a b +---------------------------------------------------------------------------------------------------------- +Exec rra rrb (equiv. to rrr): +6 3 +5 2 +8 1 +_ _ +a b +---------------------------------------------------------------------------------------------------------- +Exec sa: +5 3 +6 2 +8 1 +_ _ +a b +---------------------------------------------------------------------------------------------------------- +Exec pa pa pa: +1 +2 +3 +5 +6 +8 +_ _ +a b +---------------------------------------------------------------------------------------------------------- + + Integers from a get sorted in 12 instructions. Can you do better? + + + + + 9 +Push_swap Because Swap_push isn’t as natural + + +V.3 The "push_swap" program + + Program name push_swap + Turn in files Makefile, *.h, *.c + Makefile NAME, all, clean, fclean, re + Arguments stack a: A list of integers + External functs. + + • read, write, malloc, free, + exit + • ft_printf and any equivalent + YOU coded + + Libft authorized Yes + Description Sort stacks + + + + Your project must comply with the following rules: + + • You have to turn in a Makefile which will compile your source files. It must not + relink. + + • Global variables are forbidden. + + • You have to write a program named push_swap that takes as an argument the stack + a formatted as a list of integers. The first argument should be at the top of the + stack (be careful about the order). + + • The program must display the smallest list of instructions possible to sort the stack + a, the smallest number being at the top. + + • Instructions must be separated by a ’\n’ and nothing else. + + • The goal is to sort the stack with the lowest possible number of operations. During + the evaluation process, the number of instructions found by your program will be + compared against a limit: the maximum number of operations tolerated. If your + program either displays a longer list or if the numbers aren’t sorted properly, your + grade will be 0. + + • If no parameters are specified, the program must not display anything and give the + prompt back. + + • In case of error, it must display "Error" followed by a ’\n’ on the standard error. + Errors include for example: some arguments aren’t integers, some arguments are + bigger than an integer and/or there are duplicates. + + + + + 10 +Push_swap Because Swap_push isn’t as natural + + +$>./push_swap 2 1 3 6 5 8 +sa +pb +pb +pb +sa +pa +pa +pa +$>./push_swap 0 one 2 3 +Error +$> + + + + During the evaluation process, a binary will be provided in order to properly check +your program. + + It will work as follows: + +$>ARG="4 67 3 87 23"; ./push_swap $ARG | wc -l + 6 +$>ARG="4 67 3 87 23"; ./push_swap $ARG | ./checker_OS $ARG +OK +$> + + + + If the program checker_OS displays "KO", it means that your push_swap came up +with a list of instructions that doesn’t sort the numbers. + + + The checker_OS program is available in the resources of the project + in the intranet. + You can find a description of how it works in the Bonus Part of this + document. + + + + + 11 +Chapter VI + +Bonus part + +This project leaves little room for adding extra features due to its simplicity. However, +how about creating your own checker? + + + Thanks to the checker program, you will be able to check whether + the list of instructions generated by the push_swap program actually + sorts the stack properly. + + + + +VI.1 The "checker" program + + Program name checker + Turn in files *.h, *.c + Makefile bonus + Arguments stack a: A list of integers + External functs. + + • read, write, malloc, free, + exit + • ft_printf and any equivalent + YOU coded + + Libft authorized Yes + Description Execute the sorting instructions + + • Write a program named checker that takes as an argument the stack a formatted + as a list of integers. The first argument should be at the top of the stack (be careful + about the order). If no argument is given, it stops and displays nothing. + • It will then wait and read instructions on the standard input, each instruction will + be followed by ’\n’. Once all the instructions have been read, the program has to + execute them on the stack received as an argument. + + 12 +Push_swap Because Swap_push isn’t as natural + + + • If after executing those instructions, the stack a is actually sorted and the stack b + is empty, then the program must display "OK" followed by a ’\n’ on the standard + output. + + • In every other case, it must display "KO" followed by a ’\n’ on the standard output. + + • In case of error, you must display "Error" followed by a ’\n’ on the standard er- + ror. Errors include for example: some arguments are not integers, some arguments + are bigger than an integer, there are duplicates, an instruction doesn’t exist and/or + is incorrectly formatted. + + +$>./checker 3 2 1 0 +rra +pb +sa +rra +pa +OK +$>./checker 3 2 1 0 +sa +rra +pb +KO +$>./checker 3 2 one 0 +Error +$>./checker "" 1 +Error +$> + + + + + You DO NOT have to reproduce the exact same behavior as the provided + binary. It is mandatory to manage errors but it is up to you to + decide how you want to parse the arguments. + + + + + The bonus part will only be assessed if the mandatory part is + PERFECT. Perfect means the mandatory part has been integrally done + and works without malfunctioning. If you have not passed ALL the + mandatory requirements, your bonus part will not be evaluated at all. + + + + + 13 +Chapter VII + +Submission and peer-evaluation + +Turn in your assignment in your Git repository as usual. Only the work inside your repos- +itory will be evaluated during the defense. Don’t hesitate to double check the names of +your files to ensure they are correct. + + As these assignments are not verified by a program, feel free to organize your files as +you wish, as long as you turn in the mandatory files and comply with the requirements. + + + + + file.bfe:VABB7yO9xm7xWXROeASsmsgnY0o0sDMJev7zFHhwQS8mvM8V5xQQp + Lc6cDCFXDWTiFzZ2H9skYkiJ/DpQtnM/uZ0 + + + + + 14