trying to work
This commit is contained in:
parent
3d3d7a35ab
commit
2776ee1ebc
25 changed files with 1621 additions and 0 deletions
9
.clang-format
Normal file
9
.clang-format
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
BasedOnStyle: Microsoft
|
||||
IndentWidth: 4
|
||||
ColumnLimit: 80
|
||||
UseTab: Always
|
||||
SortIncludes: CaseInsensitive
|
||||
IndentPPDirectives: AfterHash
|
||||
PPIndentWidth: 1
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AlignConsecutiveDeclarations: true
|
||||
16
.clangd
Normal file
16
.clangd
Normal file
|
|
@ -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/"
|
||||
|
||||
57
.gitignore
vendored
Normal file
57
.gitignore
vendored
Normal file
|
|
@ -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/
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "mecstd"]
|
||||
path = mecstd
|
||||
url = git@github.com:Maix0/mecstd.git
|
||||
135
Makefile
Normal file
135
Makefile
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
# **************************************************************************** #
|
||||
# #
|
||||
# ::: :::::::: #
|
||||
# Makefile :+: :+: :+: #
|
||||
# +:+ +:+ +:+ #
|
||||
# By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ #
|
||||
# +#+#+#+#+#+ +#+ #
|
||||
# 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)
|
||||
|
||||
39
flake.nix
Normal file
39
flake.nix
Normal file
|
|
@ -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
|
||||
];
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
6
gen.list
Normal file
6
gen.list
Normal file
|
|
@ -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
|
||||
26
include/app/dup_state.h
Normal file
26
include/app/dup_state.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* dup_state.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 */
|
||||
25
include/app/element.h
Normal file
25
include/app/element.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* element.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 */
|
||||
22
include/app/lis.h
Normal file
22
include/app/lis.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lis.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 */
|
||||
37
include/app/moves.h
Normal file
37
include/app/moves.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* moves.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 */
|
||||
28
include/app/state.h
Normal file
28
include/app/state.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* state.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 */
|
||||
40
input.toml
Normal file
40
input.toml
Normal file
|
|
@ -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"
|
||||
1
mecstd
Submodule
1
mecstd
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit f9c81caf38361c927fa81f72a1e832bbb619e161
|
||||
BIN
push_swap
Executable file
BIN
push_swap
Executable file
Binary file not shown.
8
src.list
Normal file
8
src.list
Normal file
|
|
@ -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
|
||||
231
src/app/lis/lis.c
Normal file
231
src/app/lis/lis.c
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lis.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 <stdlib.h>
|
||||
|
||||
/*
|
||||
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<T, I: Ord, F: Fn(&T) -> I>(items: &[T], selector: F) -> Vec<usize> {
|
||||
// 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);
|
||||
}
|
||||
11
src/app/lis/lower_bound.c
Normal file
11
src/app/lis/lower_bound.c
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lower_bound.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/01/11 18:17:23 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/01/11 19:17:19 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
180
src/app/main.c
Normal file
180
src/app/main.c
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* main.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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 <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
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);
|
||||
}
|
||||
44
src/app/moves.c
Normal file
44
src/app/moves.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* moves.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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);
|
||||
}
|
||||
37
src/app/moves/push.c
Normal file
37
src/app/moves/push.c
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* push.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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");
|
||||
}
|
||||
35
src/app/moves/rev_rotate.c
Normal file
35
src/app/moves/rev_rotate.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* rev_rotate.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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");
|
||||
}
|
||||
36
src/app/moves/rotate.c
Normal file
36
src/app/moves/rotate.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* rotate.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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");
|
||||
}
|
||||
39
src/app/moves/swap.c
Normal file
39
src/app/moves/swap.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* swap.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* 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");
|
||||
}
|
||||
556
subject.txt
Normal file
556
subject.txt
Normal file
|
|
@ -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 <stdio.h>
|
||||
|
||||
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
|
||||
<?php
|
||||
echo "Hello world!";
|
||||
?>
|
||||
|
||||
|
||||
|
||||
• 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
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Hello world !</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Hello World !</p>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
• 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue