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/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6ccc634 --- /dev/null +++ b/.gitignore @@ -0,0 +1,61 @@ +# 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/ +push_swap +push_swap_visualizer +Push-Swap-Tester +checker 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..bf3d702 --- /dev/null +++ b/Makefile @@ -0,0 +1,139 @@ +# **************************************************************************** # +# # +# ::: :::::::: # +# Makefile :+: :+: :+: # +# +:+ +:+ +:+ # +# By: maiboyer +#+ +:+ +#+ # +# +#+#+#+#+#+ +#+ # +# Created: 2023/11/03 13:20:01 by maiboyer #+# #+# # +# Updated: 2024/02/09 15:27:44 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 + +NAME = push_swap + +ifeq ($(MAKECMDGOALS), bonus) + CFLAGS += -DBONUS=1 + BUILD_DIR := $(BUILD_DIR)/bonus/ + NAME = checker +endif + +LIB_NAME ?= +TARGET = $(NAME) +CC ?= clang +CFLAGS += -Wall -Werror -Wextra -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) + @rm -f push_swap + @rm -f checker + @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/check.sh b/check.sh new file mode 100755 index 0000000..ded0e01 --- /dev/null +++ b/check.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +ARGS="133 193 -16 -234 239 85 -223 -100 178 212 -202 -102 -199 -233 227 86 -166 224 160 -21 -56 102 -62 62 -127 89 127 -246 1 140 38 157 179 220 154 -1 125 240 -238 78 -175 222 -145 -60 115 67 -220 80 -136 -134 -159 35 136 192 47 117 -51 -140 37 6 -26 -188 213 -204 -210 14 -70 112 201 -191 -22 219 15 -143 -131 -41 -152 -187 24 215 235 -147 170 -168 12 107 105 130 -91 230 -174 -176 -224 -35 5 -110 -180 60 -59 -24 94 -196 -39 21 131 -18 165 -2 -219 -198 -19 -11 244 -151 -80 43 -17 -244 -65 124 9 -153 118 -6 -235 81 225 121 217 -43 30 218 -111 163 -9 23 214 166 207 238 -217 -161 -165 116 -170 26 -44 -106 245 -155 48 -177 75 -66 -89 109 22 56 58 -53 203 -79 39 184 -94 -231 45 246 93 13 -128 -179 -236 -139 114 63 -32 196 -205 57 249 -243 233 247 -46 -90 -47 -201 -144 221 -172 66 -38 -101 -232 175 164 -215 -195 -126 209 -108 -64 126 134 -77 -69 113 146 -211 2 88 -28 -132 -250 77 -181 191 198 183 -239 -52 -118 187 -109 4 -208 73 -96 -81 87 188 122 -120 -29 83 18 92 -83 100 -68 -221 -186 189 41 68 -150 129 -49 -137 -99 -123 -42 150 -192 -82 -158 104 -61 145 16 96 -115 -27 -119 97 -203 -240 -173 -185 -227 -98 72 -237 -7 -105 -76 149 -218 -182 54 76 61 211 173 7 185 -10 19 -15 -84 -48 36 53 -67 -63 155 -169 -138 -141 -78 33 -85 234 138 -146 223 158 135 91 108 55 32 90 226 -230 -40 177 -34 -112 -190 144 -104 -241 71 237 -226 95 208 -31 180 59 52 151 153 -135 46 -50 -154 204 132 119 70 110 199 -225 169 194 -148 148 241 -37 27 -23 176 232 -156 206 200 -167 -14 3 -209 159 -75 -248 111 -73 34 -113 -184 25 -86 -122 106 11 162 -133 -88 -245 147 -178 -197 190 -117 84 210 -54 -247 98 -157 64 -95 -129 10 -207 -72 182 -71 181 51 79 -87 242 20 123 82 99 -130 49 101 216 -216 -93 -97 172 -125 -163 -200 -8 -206 197 -242 -194 -212 168 161 -45 103 -160 195 -249 -25 69 137 167 152 -20 -142 243 -55 -171 -36 156 -12 -149 29 28 -183 50 120 -222 17 174 -4 -74 143 236 -189 44 -228 -162 40 229 228 -124 248 231 -5 -193 65 -13 139 128 -92 31 -103 142 -3 -33 205 -164 186 -121 -57 0 -229 42 -114 -213 202 -58 141 -107 -30 -116 171 -214 74 8" + +echo -n "Mine: " +./push_swap $ARGS | valgrind --track-origins=yes ./checker $ARGS +echo -n "Their: " +./push_swap $ARGS | ./Push-Swap-Tester/checker_linux $ARGS diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..d2e09c7 --- /dev/null +++ b/flake.lock @@ -0,0 +1,351 @@ +{ + "nodes": { + "c_formatter_42": { + "inputs": { + "c_formatter_42_src": "c_formatter_42_src", + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1700259489, + "narHash": "sha256-Ye2zwphDUY/eDjyFCPFt0r9RyqMr4ZQprCE4bydNdpw=", + "owner": "maix0", + "repo": "c_formatter_42-flake", + "rev": "3d4f6a40bd1edf9fdb4959051edc172473d9544d", + "type": "github" + }, + "original": { + "owner": "maix0", + "repo": "c_formatter_42-flake", + "type": "github" + } + }, + "c_formatter_42_src": { + "flake": false, + "locked": { + "lastModified": 1696506114, + "narHash": "sha256-jUScF2lAHhjTWOWZsIAocE6FN8+HG+kLdpbYsEA1SZs=", + "owner": "dawnbeen", + "repo": "c_formatter_42", + "rev": "ef91ff383966885374695c327fa6015f9cfbc364", + "type": "github" + }, + "original": { + "owner": "dawnbeen", + "repo": "c_formatter_42", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_3": { + "inputs": { + "systems": "systems_3" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_4": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_5": { + "locked": { + "lastModified": 1659877975, + "narHash": "sha256-zllb8aq3YO3h8B/U0/J1WBgAL8EX5yWf5pMj3G0NAmc=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "c0e246b9b83f637f4681389ecabcb2681b4f3af0", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "generic_c": { + "inputs": { + "flake-utils": "flake-utils_3", + "naersk": "naersk", + "nixpkgs": "nixpkgs_3", + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1706829609, + "narHash": "sha256-A0imQ9AIJafdL1/+j/1b3G7bm2j+N+VhzTsvKikKjz4=", + "owner": "maix0", + "repo": "generic_c", + "rev": "a470c2c5a8c8aadc852a7a50d72853f2a3873595", + "type": "github" + }, + "original": { + "owner": "maix0", + "repo": "generic_c", + "type": "github" + } + }, + "naersk": { + "inputs": { + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1698420672, + "narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=", + "owner": "nix-community", + "repo": "naersk", + "rev": "aeb58d5e8faead8980a807c840232697982d47b9", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "naersk", + "type": "github" + } + }, + "nixGL": { + "inputs": { + "flake-utils": "flake-utils_5", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1685908677, + "narHash": "sha256-E4zUPEUFyVWjVm45zICaHRpfGepfkE9Z2OECV9HXfA4=", + "owner": "guibou", + "repo": "nixGL", + "rev": "489d6b095ab9d289fe11af0219a9ff00fe87c7c5", + "type": "github" + }, + "original": { + "owner": "guibou", + "repo": "nixGL", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1700108881, + "narHash": "sha256-+Lqybl8kj0+nD/IlAWPPG/RDTa47gff9nbei0u7BntE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "7414e9ee0b3e9903c24d3379f577a417f0aae5f1", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1706683685, + "narHash": "sha256-FtPPshEpxH/ewBOsdKBNhlsL2MLEFv1hEnQ19f/bFsQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5ad9903c16126a7d949101687af0aa589b1d7d3d", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1706683685, + "narHash": "sha256-FtPPshEpxH/ewBOsdKBNhlsL2MLEFv1hEnQ19f/bFsQ=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "5ad9903c16126a7d949101687af0aa589b1d7d3d", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_4": { + "locked": { + "lastModified": 1706487304, + "narHash": "sha256-LE8lVX28MV2jWJsidW13D2qrHU/RUUONendL2Q/WlJg=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "90f456026d284c22b3e3497be980b2e47d0b28ac", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_5": { + "locked": { + "lastModified": 1706925685, + "narHash": "sha256-hVInjWMmgH4yZgA4ZtbgJM1qEAel72SYhP5nOWX4UIM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "79a13f1437e149dc7be2d1290c74d378dad60814", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "type": "indirect" + } + }, + "root": { + "inputs": { + "c_formatter_42": "c_formatter_42", + "flake-utils": "flake-utils_2", + "generic_c": "generic_c", + "nixGL": "nixGL", + "nixpkgs": "nixpkgs_5" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": "flake-utils_4", + "nixpkgs": "nixpkgs_4" + }, + "locked": { + "lastModified": 1706753617, + "narHash": "sha256-ZKqTFzhFwSWFEpQTJ0uXnfJBs5Y/po9/8TK4bzssdbs=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "58be43ae223034217ea1bd58c73210644031b687", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..3a31d1f --- /dev/null +++ b/flake.nix @@ -0,0 +1,46 @@ +{ + 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"; + nixGL.url = "github:guibou/nixGL"; + nixGL.inputs.nixpkgs.follows = "nixpkgs"; + }; + outputs = { + self, + nixpkgs, + flake-utils, + generic_c, + c_formatter_42, + nixGL, + }: + flake-utils.lib.eachDefaultSystem ( + system: let + pkgs = import nixpkgs { + inherit system; + overlays = [nixGL.overlay]; + }; + in { + devShell = pkgs.mkShell { + packages = [ + pkgs.xorg.libXext + pkgs.xorg.libX11 + pkgs.clang + pkgs.clang-tools + pkgs.norminette + pkgs.poppler_utils + pkgs.minilibx + pkgs.valgrind + pkgs.libbsd + pkgs.tree + pkgs.fastmod + generic_c.packages.${system}.default + c_formatter_42.packages.${system}.default + pkgs.nixgl.nixGLIntel + ]; + }; + } + ); +} diff --git a/gen.list b/gen.list new file mode 100644 index 0000000..a1c896e --- /dev/null +++ b/gen.list @@ -0,0 +1,24 @@ +convert/str_to_i16 +convert/str_to_i16_utils +convert/str_to_i32 +convert/str_to_i32_utils +convert/str_to_i64 +convert/str_to_i64_utils +convert/str_to_i8 +convert/str_to_i8_utils +convert/str_to_u16 +convert/str_to_u16_utils +convert/str_to_u32 +convert/str_to_u32_utils +convert/str_to_u64 +convert/str_to_u64_utils +convert/str_to_u8 +convert/str_to_u8_utils +vec/vec_i64 +vec/vec_i64_bool +vec/vec_i64_bool_functions2 +vec/vec_i64_bool_functions3 +vec/vec_i64_bool_sort +vec/vec_i64_functions2 +vec/vec_i64_functions3 +vec/vec_i64_sort diff --git a/include/app/best_index_to_move.h b/include/app/best_index_to_move.h new file mode 100644 index 0000000..53e5ed7 --- /dev/null +++ b/include/app/best_index_to_move.h @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* best_index_to_move.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/08 14:18:43 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 14:20:01 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BEST_INDEX_TO_MOVE_H +# define BEST_INDEX_TO_MOVE_H + +# include "app/best_move.h" +# include "app/state.h" +# include "me/types.h" +# include "me/vec/vec_i64.h" + +struct s_best_index_to_move +{ + t_state *state; + t_vec_i64 *from; + t_vec_i64 *to; + t_iter_pos_func f; + t_usize i; +}; + +#endif /* BEST_INDEX_TO_MOVE_H */ diff --git a/include/app/best_move.h b/include/app/best_move.h new file mode 100644 index 0000000..f78fb2b --- /dev/null +++ b/include/app/best_move.h @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* best_move.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 20:10:21 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 13:30:30 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BEST_MOVE_H +# define BEST_MOVE_H + +# include "app/state.h" +# include "me/vec/vec_i64.h" + +struct s_functions +{ + void (*forward)(void *); + void (*reverse)(void *); +}; + +typedef t_usize (*t_iter_pos_func)(t_vec_i64 *); + +typedef struct s_best_move_args +{ + t_iter_pos_func iter_func; + t_usize index; + t_vec_i64 *from; + t_vec_i64 *to; + void *args; + struct s_functions main; + struct s_functions other; + struct s_functions both; + bool print_stuff; +} t_best_move_args; + +void run_func_with_best_rotate_for_item(t_state *state, + t_best_move_args data); + +#endif /* BEST_MOVE_H */ diff --git a/include/app/best_move_inner.h b/include/app/best_move_inner.h new file mode 100644 index 0000000..902c125 --- /dev/null +++ b/include/app/best_move_inner.h @@ -0,0 +1,58 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* best_move_inner.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 21:31:42 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 14:22:49 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef BEST_MOVE_INNER_H +# define BEST_MOVE_INNER_H + +# include "app/best_move.h" +# include "app/rotate.h" +# include "app/state.h" +# include "me/types.h" +# include "me/vec/vec_i64.h" + +typedef void (*t_banana_func)(void *); + +static inline t_banana_func choose_func(struct s_functions *funcs, + t_rotation rotate) +{ + if (rotate.direction == FORWARD) + return (funcs->forward); + else if (rotate.direction == REVERSE) + return (funcs->reverse); + return (NULL); +} + +static inline t_isize abs_diff(t_isize lhs, t_isize rhs) +{ + if (lhs > rhs) + return (lhs - rhs); + else + return (rhs - lhs); +} + +static inline t_isize min(t_isize lhs, t_isize rhs) +{ + if (lhs > rhs) + return (rhs); + else + return (lhs); +} + +static inline t_isize max(t_isize lhs, t_isize rhs) +{ + if (lhs < rhs) + return (rhs); + else + return (lhs); +} + +#endif /* BEST_MOVE_INNER_H */ diff --git a/include/app/find_iter.h b/include/app/find_iter.h new file mode 100644 index 0000000..ff9b460 --- /dev/null +++ b/include/app/find_iter.h @@ -0,0 +1,22 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* find_iter.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/31 14:24:10 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:24:47 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FIND_ITER_H +# define FIND_ITER_H + +# include "me/types.h" +# include "me/vec/vec_i64.h" + +t_usize min_iter_zero_pos(t_vec_i64 *vec); +t_usize max_iter_zero_pos(t_vec_i64 *vec); + +#endif /* FIND_ITER_H */ diff --git a/include/app/find_place.h b/include/app/find_place.h new file mode 100644 index 0000000..234e7b1 --- /dev/null +++ b/include/app/find_place.h @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* find_place.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 22:00:27 by maiboyer #+# #+# */ +/* Updated: 2024/01/29 22:15:08 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef FIND_PLACE_H +# define FIND_PLACE_H + +# include "app/state.h" +# include "me/types.h" + +typedef struct s_find_place_iter_state +{ + t_usize current_index; + t_usize found_index; + t_i64 to_find_elem; + +} t_find_place_iter_state; + +t_usize find_place(t_i64 elem, t_state *state); + +#endif /* FIND_PLACE_H */ diff --git a/include/app/iter_state.h b/include/app/iter_state.h new file mode 100644 index 0000000..acc14be --- /dev/null +++ b/include/app/iter_state.h @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* iter_state.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/31 14:19:06 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:19:50 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ITER_STATE_H +# define ITER_STATE_H + +# include "me/types.h" + +typedef struct s_iter_state +{ + t_usize pos; + t_i64 elem; +} t_iter_state; + +#endif /* ITER_STATE_H */ diff --git a/include/app/moves.h b/include/app/moves.h new file mode 100644 index 0000000..db9b4f7 --- /dev/null +++ b/include/app/moves.h @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* moves.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:13:08 by maiboyer #+# #+# */ +/* Updated: 2024/01/29 19:07:15 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef MOVES_H +# define MOVES_H + +# include "app/state.h" +# include "app/types/type_move.h" +# include "me/types.h" + +void do_move(t_move m, t_state *s); +t_const_str get_str_for_move(t_move m); + +#endif /* MOVES_H */ diff --git a/include/app/rotate.h b/include/app/rotate.h new file mode 100644 index 0000000..f393485 --- /dev/null +++ b/include/app/rotate.h @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* rotate.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 19:00:18 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 13:33:09 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef ROTATE_H +# define ROTATE_H + +# include "me/types.h" + +enum e_rotation_direction +{ + FORWARD, + REVERSE, +}; +typedef struct s_rotation +{ + t_isize value; + t_isize ring_size; + enum e_rotation_direction direction; +} t_rotation; + +static inline t_rotation forward(t_isize by, t_isize ring_size) +{ + return ((t_rotation){.value = by, .ring_size = ring_size, + .direction = FORWARD}); +} + +static inline t_rotation reverse(t_isize by, t_isize ring_size) +{ + return ((t_rotation){.value = by, .ring_size = ring_size, + .direction = REVERSE}); +} + +static inline t_rotation flip(t_rotation rot) +{ + enum e_rotation_direction flipped; + + if (rot.direction == FORWARD) + flipped = REVERSE; + else if (rot.direction == REVERSE) + flipped = FORWARD; + else + return (rot); + return ((t_rotation){.value = rot.ring_size - rot.value, + .ring_size = rot.ring_size, .direction = flipped}); +} + +#endif /* ROTATE_H */ diff --git a/include/app/state.h b/include/app/state.h new file mode 100644 index 0000000..2261e43 --- /dev/null +++ b/include/app/state.h @@ -0,0 +1,73 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* state.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 14:27:25 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 19:05:37 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef STATE_H +# define STATE_H + +# include "me/types.h" +# include "me/vec/vec_i64.h" +# include "me/vec/vec_i64_bool.h" + +# ifndef BONUS +# define BONUS 0 +# endif + +typedef struct s_state +{ + t_vec_i64_bool sorted; + t_vec_i64 stack_a; + t_vec_i64 stack_b; +} t_state; + +t_state parses_arguments(t_usize count, t_str nums[]); +void free_state(t_state state); + +static inline void make_sorted_true_for_elem(t_state *s, t_i64 elem) +{ + t_usize i; + + i = 0; + while (i < s->sorted.len) + { + if (s->sorted.buffer[i].value == elem) + { + s->sorted.buffer[i].active = true; + return ; + } + i++; + } +} + +static inline void make_sorted_true_from_stack(t_state *s, t_vec_i64 *stack) +{ + t_usize i; + + i = 0; + while (i < stack->len) + { + make_sorted_true_for_elem(s, stack->buffer[i++]); + } +} + +static inline void make_sorted_all_false(t_state *s) +{ + t_usize i; + + i = 0; + while (i < s->sorted.len) + { + s->sorted.buffer[i].active = false; + i++; + } +} + +#endif /* STATE_H */ diff --git a/include/app/target.h b/include/app/target.h new file mode 100644 index 0000000..204044e --- /dev/null +++ b/include/app/target.h @@ -0,0 +1,21 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* target.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 20:30:43 by maiboyer #+# #+# */ +/* Updated: 2024/01/29 20:31:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef TARGET_H +# define TARGET_H + +# include "app/rotate.h" +# include "me/types.h" + +t_rotation target(t_usize from, t_usize to, t_usize ring_size); + +#endif /* TARGET_H */ diff --git a/include/app/types/type_i64_bool.h b/include/app/types/type_i64_bool.h new file mode 100644 index 0000000..48af825 --- /dev/null +++ b/include/app/types/type_i64_bool.h @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* type_i64_bool.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 19:14:52 by maiboyer #+# #+# */ +/* Updated: 2024/01/29 19:15:56 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef TYPE_I64_BOOL_H +# define TYPE_I64_BOOL_H + +# include "me/types.h" + +typedef struct s_i64_bool +{ + t_i64 value; + bool active; +} t_i64_bool; + +#endif /* TYPE_I64_BOOL_H */ diff --git a/include/app/types/type_move.h b/include/app/types/type_move.h new file mode 100644 index 0000000..761a82a --- /dev/null +++ b/include/app/types/type_move.h @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* type_move.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/12 21:26:56 by maiboyer #+# #+# */ +/* Updated: 2024/01/12 21:27:08 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef TYPE_MOVE_H +# define TYPE_MOVE_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; + +#endif /* TYPE_MOVE_H */ diff --git a/include/me/convert/str_to_numbers.h b/include/me/convert/str_to_numbers.h new file mode 100644 index 0000000..9f90ddf --- /dev/null +++ b/include/me/convert/str_to_numbers.h @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_numbers.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:08:13 by maiboyer #+# #+# */ +/* Updated: 2024/02/02 00:22:50 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef STR_TO_NUMBERS_H +# define STR_TO_NUMBERS_H + +# include "me/types.h" + +t_error str_to_isize(t_const_str str, t_u32 radix, t_isize *out); +t_error str_to_i64(t_const_str str, t_u32 radix, t_i64 *out); +t_error str_to_i32(t_const_str str, t_u32 radix, t_i32 *out); +t_error str_to_i16(t_const_str str, t_u32 radix, t_i16 *out); +t_error str_to_i8(t_const_str str, t_u32 radix, t_i8 *out); + +t_error str_to_usize(t_const_str str, t_u32 radix, t_usize *out); +t_error str_to_u64(t_const_str str, t_u32 radix, t_u64 *out); +t_error str_to_u32(t_const_str str, t_u32 radix, t_u32 *out); +t_error str_to_u16(t_const_str str, t_u32 radix, t_u16 *out); +t_error str_to_u8(t_const_str str, t_u32 radix, t_u8 *out); + +#endif /* STR_TO_NUMBERS_H */ diff --git a/input.toml b/input.toml new file mode 100644 index 0000000..8125265 --- /dev/null +++ b/input.toml @@ -0,0 +1,144 @@ +[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__", + "mecstd/generic_sources/src/vec_C__PREFIX___sort.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" + +[definition.str_to_num] +headers = [] +sources = [ + "mecstd/generic_sources/src/str_to_C__PREFIX__.c__TEMPLATE__", + "mecstd/generic_sources/src/str_to_C__PREFIX___utils.c__TEMPLATE__", +] +replace.C__TYPE__ = "type" +replace.C__UNSIGNED_TYPE__ = "type" +replace.C__PREFIX__ = "prefix" +replace.C__MAX__ = "value" +replace.C__MIN__ = "value" +replace.C__ZERO__ = "value" +replace.C__SIGNED_TYPE__ = "bool" + +[[create.str_to_num]] +sources_output = "src/convert/" +headers_output = "" +replace.C__TYPE__ = "t_i64" +replace.C__UNSIGNED_TYPE__ = "t_u64" +replace.C__PREFIX__ = "i64" +replace.C__MAX__ = "9223372036854775807ll" +replace.C__MIN__ = "-(~9223372036854775807ll + 1)" +replace.C__ZERO__ = "0ll" +replace.C__SIGNED_TYPE__ = "true" + +[[create.str_to_num]] +sources_output = "src/convert/" +headers_output = "" +replace.C__TYPE__ = "t_i32" +replace.C__UNSIGNED_TYPE__ = "t_u32" +replace.C__PREFIX__ = "i32" +replace.C__MAX__ = "2147483647" +replace.C__MIN__ = "-2147483648" +replace.C__ZERO__ = "0" +replace.C__SIGNED_TYPE__ = "true" + +[[create.str_to_num]] +sources_output = "src/convert/" +headers_output = "" +replace.C__TYPE__ = "t_i16" +replace.C__UNSIGNED_TYPE__ = "t_u16" +replace.C__PREFIX__ = "i16" +replace.C__MAX__ = "32767" +replace.C__MIN__ = "-32768" +replace.C__ZERO__ = "0" +replace.C__SIGNED_TYPE__ = "true" + +[[create.str_to_num]] +sources_output = "src/convert/" +headers_output = "" +replace.C__TYPE__ = "t_i8" +replace.C__UNSIGNED_TYPE__ = "t_u8" +replace.C__PREFIX__ = "i8" +replace.C__MAX__ = "127" +replace.C__MIN__ = "-128" +replace.C__ZERO__ = "0" +replace.C__SIGNED_TYPE__ = "true" + +[[create.str_to_num]] +sources_output = "src/convert/" +headers_output = "" +replace.C__TYPE__ = "t_u64" +replace.C__UNSIGNED_TYPE__ = "t_u64" +replace.C__PREFIX__ = "u64" +replace.C__MAX__ = "18446744073709551615llu" +replace.C__MIN__ = "0llu" +replace.C__ZERO__ = "0llu" +replace.C__SIGNED_TYPE__ = "false" + +[[create.str_to_num]] +sources_output = "src/convert/" +headers_output = "" +replace.C__TYPE__ = "t_u32" +replace.C__UNSIGNED_TYPE__ = "t_u32" +replace.C__PREFIX__ = "u32" +replace.C__MAX__ = "4294967295u" +replace.C__MIN__ = "0u" +replace.C__ZERO__ = "0u" +replace.C__SIGNED_TYPE__ = "false" + +[[create.str_to_num]] +sources_output = "src/convert/" +headers_output = "" +replace.C__TYPE__ = "t_u16" +replace.C__UNSIGNED_TYPE__ = "t_u16" +replace.C__PREFIX__ = "u16" +replace.C__MAX__ = "65535u" +replace.C__MIN__ = "0u" +replace.C__ZERO__ = "0u" +replace.C__SIGNED_TYPE__ = "false" + + +[[create.str_to_num]] +sources_output = "src/convert/" +headers_output = "" +replace.C__TYPE__ = "t_u8" +replace.C__UNSIGNED_TYPE__ = "t_u8" +replace.C__PREFIX__ = "u8" +replace.C__MAX__ = "128u" +replace.C__MIN__ = "0u" +replace.C__ZERO__ = "0u" +replace.C__SIGNED_TYPE__ = "false" + +[[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" + +[[create.vec]] +sources_output = "src/vec/" +headers_output = "include/me/vec/" +replace.C__TYPENAME__ = "t_i64_bool" +replace.C__TYPEHEADER__ = '#include "app/types/type_i64_bool.h"' +replace.C__PREFIX__ = "i64_bool" +replace.C__PREFIXUP__ = "I64_BOOL" diff --git a/mecstd b/mecstd new file mode 160000 index 0000000..07ea967 --- /dev/null +++ b/mecstd @@ -0,0 +1 @@ +Subproject commit 07ea9679e2413366502a73ea9391d89847d6b3c2 diff --git a/output/include/me/vec/vec_i64.h b/output/include/me/vec/vec_i64.h new file mode 100644 index 0000000..8a8f200 --- /dev/null +++ b/output/include/me/vec/vec_i64.h @@ -0,0 +1,51 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/04 18:46:53 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:53:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef VEC_I64_H +# define VEC_I64_H + +# include "me/types.h" + +typedef bool (*t_vec_i64_sort_fn)(t_i64 *, t_i64 *); +typedef void (*t_free_i64_item)(t_i64); + +typedef struct s_vec_i64 +{ + t_free_i64_item free_func; + t_usize len; + t_usize capacity; + t_i64 *buffer; +} t_vec_i64; + +t_vec_i64 vec_i64_new(t_usize capacity, + t_free_i64_item free_function); +t_error vec_i64_push(t_vec_i64 *vec, t_i64 element); +t_error vec_i64_push_front(t_vec_i64 *vec, t_i64 element); +t_error vec_i64_pop(t_vec_i64 *vec, t_i64 *value); +t_error vec_i64_pop_front(t_vec_i64 *vec, t_i64 *value); +void vec_i64_free(t_vec_i64 vec); +t_error vec_i64_reserve(t_vec_i64 *vec, t_usize wanted_capacity); +t_error vec_i64_find(t_vec_i64 *vec, bool (*fn)(const t_i64 *), + t_usize *index); +t_error vec_i64_find_starting(t_vec_i64 *vec, + bool (*fn)(const t_i64 *), t_usize starting_index, + t_usize *index); +t_error vec_i64_all(t_vec_i64 *vec, bool (*fn)(const t_i64 *), + bool *result); +t_error vec_i64_any(t_vec_i64 *vec, bool (*fn)(const t_i64 *), + bool *result); +void vec_i64_iter(t_vec_i64 *vec, void (*fn)(t_usize index, + t_i64 *value, void *state), void *state); +void vec_i64_reverse(t_vec_i64 *vec); +void vec_i64_sort(t_vec_i64 *vec, t_vec_i64_sort_fn is_sorted); + +#endif diff --git a/output/include/me/vec/vec_i64_bool.h b/output/include/me/vec/vec_i64_bool.h new file mode 100644 index 0000000..42f456a --- /dev/null +++ b/output/include/me/vec/vec_i64_bool.h @@ -0,0 +1,60 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64_bool.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/04 18:46:53 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:53:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef VEC_I64_BOOL_H +# define VEC_I64_BOOL_H + +# include "app/types/type_i64_bool.h" +# include "me/types.h" + +typedef bool (*t_vec_i64_bool_sort_fn)(t_i64_bool *, + t_i64_bool *); +typedef void (*t_free_i64_bool_item)(t_i64_bool); + +typedef struct s_vec_i64_bool +{ + t_free_i64_bool_item free_func; + t_usize len; + t_usize capacity; + t_i64_bool *buffer; +} t_vec_i64_bool; + +t_vec_i64_bool vec_i64_bool_new(t_usize capacity, + t_free_i64_bool_item free_function); +t_error vec_i64_bool_push(t_vec_i64_bool *vec, + t_i64_bool element); +t_error vec_i64_bool_push_front(t_vec_i64_bool *vec, + t_i64_bool element); +t_error vec_i64_bool_pop(t_vec_i64_bool *vec, + t_i64_bool *value); +t_error vec_i64_bool_pop_front(t_vec_i64_bool *vec, + t_i64_bool *value); +void vec_i64_bool_free(t_vec_i64_bool vec); +t_error vec_i64_bool_reserve(t_vec_i64_bool *vec, + t_usize wanted_capacity); +t_error vec_i64_bool_find(t_vec_i64_bool *vec, + bool (*fn)(const t_i64_bool *), t_usize *index); +t_error vec_i64_bool_find_starting(t_vec_i64_bool *vec, + bool (*fn)(const t_i64_bool *), + t_usize starting_index, t_usize *index); +t_error vec_i64_bool_all(t_vec_i64_bool *vec, + bool (*fn)(const t_i64_bool *), bool *result); +t_error vec_i64_bool_any(t_vec_i64_bool *vec, + bool (*fn)(const t_i64_bool *), bool *result); +void vec_i64_bool_iter(t_vec_i64_bool *vec, + void (*fn)(t_usize index, t_i64_bool *value, + void *state), void *state); +void vec_i64_bool_reverse(t_vec_i64_bool *vec); +void vec_i64_bool_sort(t_vec_i64_bool *vec, + t_vec_i64_bool_sort_fn is_sorted); + +#endif diff --git a/output/src/convert/str_to_i16.c b/output/src/convert/str_to_i16.c new file mode 100644 index 0000000..b1d2bc8 --- /dev/null +++ b/output/src/convert/str_to_i16.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_i16(t_i16 lhs, t_i16 rhs, t_i16 *out); +t_error checked_sub_i16(t_i16 lhs, t_i16 rhs, t_i16 *out); +t_error checked_mul_i16(t_i16 lhs, t_i16 rhs, t_i16 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_i16) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_i16 digit, t_u8 op, t_i16 *result) +{ + t_i16 rhs; + t_i16 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_i16(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_i16(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_i16(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_i16 *out) +{ + t_u32 digit; + t_i16 result; + + result = 0; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_i16(t_const_str s, t_u32 radix, t_i16 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && true) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, true, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_i16_utils.c b/output/src/convert/str_to_i16_utils.c new file mode 100644 index 0000000..4ecbbe2 --- /dev/null +++ b/output/src/convert/str_to_i16_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i16_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 18:55:47 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_i16(t_i16 lhs, t_i16 rhs, t_i16 *out) +{ + if (rhs > 0 && (lhs > 32767 - rhs)) + return (ERROR); + *out = (t_i16)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_i16(t_i16 lhs, t_i16 rhs, t_i16 *out) +{ + if ((((rhs & (1 << (sizeof(t_i16) - 1)) || rhs == 0) || !true) && (lhs < \ + -32768 + rhs))) + return (ERROR); + *out = (t_i16)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_i16(t_i16 lhs, t_i16 rhs, t_i16 *out) +{ + t_i16 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_i32.c b/output/src/convert/str_to_i32.c new file mode 100644 index 0000000..4956029 --- /dev/null +++ b/output/src/convert/str_to_i32.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_i32(t_i32 lhs, t_i32 rhs, t_i32 *out); +t_error checked_sub_i32(t_i32 lhs, t_i32 rhs, t_i32 *out); +t_error checked_mul_i32(t_i32 lhs, t_i32 rhs, t_i32 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_i32) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_i32 digit, t_u8 op, t_i32 *result) +{ + t_i32 rhs; + t_i32 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_i32(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_i32(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_i32(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_i32 *out) +{ + t_u32 digit; + t_i32 result; + + result = 0; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_i32(t_const_str s, t_u32 radix, t_i32 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && true) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, true, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_i32_utils.c b/output/src/convert/str_to_i32_utils.c new file mode 100644 index 0000000..5b6f5fd --- /dev/null +++ b/output/src/convert/str_to_i32_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i32_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 18:56:06 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_i32(t_i32 lhs, t_i32 rhs, t_i32 *out) +{ + if (rhs > 0 && (lhs > 2147483647 - rhs)) + return (ERROR); + *out = (t_i32)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_i32(t_i32 lhs, t_i32 rhs, t_i32 *out) +{ + if ((((rhs & (1 << (sizeof(t_i32) - 1)) || rhs == 0) || !true) && (lhs < \ + -2147483648 + rhs))) + return (ERROR); + *out = (t_i32)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_i32(t_i32 lhs, t_i32 rhs, t_i32 *out) +{ + t_i32 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_i64.c b/output/src/convert/str_to_i64.c new file mode 100644 index 0000000..56a48cc --- /dev/null +++ b/output/src/convert/str_to_i64.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_i64(t_i64 lhs, t_i64 rhs, t_i64 *out); +t_error checked_sub_i64(t_i64 lhs, t_i64 rhs, t_i64 *out); +t_error checked_mul_i64(t_i64 lhs, t_i64 rhs, t_i64 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_i64) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_i64 digit, t_u8 op, t_i64 *result) +{ + t_i64 rhs; + t_i64 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_i64(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_i64(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_i64(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_i64 *out) +{ + t_u32 digit; + t_i64 result; + + result = 0ll; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_i64(t_const_str s, t_u32 radix, t_i64 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && true) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, true, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_i64_utils.c b/output/src/convert/str_to_i64_utils.c new file mode 100644 index 0000000..1dd268d --- /dev/null +++ b/output/src/convert/str_to_i64_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 18:55:37 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_i64(t_i64 lhs, t_i64 rhs, t_i64 *out) +{ + if (rhs > 0 && (lhs > 9223372036854775807ll - rhs)) + return (ERROR); + *out = (t_i64)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_i64(t_i64 lhs, t_i64 rhs, t_i64 *out) +{ + if ((((rhs & (1 << (sizeof(t_i64) - 1)) || rhs == 0) || !true) && (lhs < \ + -(~9223372036854775807ll + 1) + rhs))) + return (ERROR); + *out = (t_i64)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_i64(t_i64 lhs, t_i64 rhs, t_i64 *out) +{ + t_i64 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_i8.c b/output/src/convert/str_to_i8.c new file mode 100644 index 0000000..80f91a0 --- /dev/null +++ b/output/src/convert/str_to_i8.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_i8(t_i8 lhs, t_i8 rhs, t_i8 *out); +t_error checked_sub_i8(t_i8 lhs, t_i8 rhs, t_i8 *out); +t_error checked_mul_i8(t_i8 lhs, t_i8 rhs, t_i8 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_i8) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_i8 digit, t_u8 op, t_i8 *result) +{ + t_i8 rhs; + t_i8 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_i8(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_i8(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_i8(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_i8 *out) +{ + t_u32 digit; + t_i8 result; + + result = 0; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_i8(t_const_str s, t_u32 radix, t_i8 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && true) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, true, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_i8_utils.c b/output/src/convert/str_to_i8_utils.c new file mode 100644 index 0000000..2073dd6 --- /dev/null +++ b/output/src/convert/str_to_i8_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_i8(t_i8 lhs, t_i8 rhs, t_i8 *out) +{ + if (rhs > 0 && (lhs > 127 - rhs)) + return (ERROR); + *out = (t_i8)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_i8(t_i8 lhs, t_i8 rhs, t_i8 *out) +{ + if ((((rhs & (1 << (sizeof(t_i8) - 1)) || rhs == 0) || !true) && (lhs < -128 + + rhs))) + return (ERROR); + *out = (t_i8)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_i8(t_i8 lhs, t_i8 rhs, t_i8 *out) +{ + t_i8 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_u16.c b/output/src/convert/str_to_u16.c new file mode 100644 index 0000000..7c5bbaa --- /dev/null +++ b/output/src/convert/str_to_u16.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_u16(t_u16 lhs, t_u16 rhs, t_u16 *out); +t_error checked_sub_u16(t_u16 lhs, t_u16 rhs, t_u16 *out); +t_error checked_mul_u16(t_u16 lhs, t_u16 rhs, t_u16 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_u16) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_u16 digit, t_u8 op, t_u16 *result) +{ + t_u16 rhs; + t_u16 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_u16(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_u16(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_u16(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_u16 *out) +{ + t_u32 digit; + t_u16 result; + + result = 0u; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_u16(t_const_str s, t_u32 radix, t_u16 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && false) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, false, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_u16_utils.c b/output/src/convert/str_to_u16_utils.c new file mode 100644 index 0000000..85fd7b2 --- /dev/null +++ b/output/src/convert/str_to_u16_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_u16(t_u16 lhs, t_u16 rhs, t_u16 *out) +{ + if (rhs > 0 && (lhs > 65535u - rhs)) + return (ERROR); + *out = (t_u16)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_u16(t_u16 lhs, t_u16 rhs, t_u16 *out) +{ + if ((((rhs & (1 << (sizeof(t_u16) - 1)) || rhs == 0) || !false) && (lhs < 0u + + rhs))) + return (ERROR); + *out = (t_u16)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_u16(t_u16 lhs, t_u16 rhs, t_u16 *out) +{ + t_u16 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_u32.c b/output/src/convert/str_to_u32.c new file mode 100644 index 0000000..1b625d1 --- /dev/null +++ b/output/src/convert/str_to_u32.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_u32(t_u32 lhs, t_u32 rhs, t_u32 *out); +t_error checked_sub_u32(t_u32 lhs, t_u32 rhs, t_u32 *out); +t_error checked_mul_u32(t_u32 lhs, t_u32 rhs, t_u32 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_u32) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_u32 digit, t_u8 op, t_u32 *result) +{ + t_u32 rhs; + t_u32 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_u32(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_u32(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_u32(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_u32 *out) +{ + t_u32 digit; + t_u32 result; + + result = 0u; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_u32(t_const_str s, t_u32 radix, t_u32 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && false) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, false, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_u32_utils.c b/output/src/convert/str_to_u32_utils.c new file mode 100644 index 0000000..3a929d5 --- /dev/null +++ b/output/src/convert/str_to_u32_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_u32(t_u32 lhs, t_u32 rhs, t_u32 *out) +{ + if (rhs > 0 && (lhs > 4294967295u - rhs)) + return (ERROR); + *out = (t_u32)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_u32(t_u32 lhs, t_u32 rhs, t_u32 *out) +{ + if ((((rhs & (1 << (sizeof(t_u32) - 1)) || rhs == 0) || !false) && (lhs < 0u + + rhs))) + return (ERROR); + *out = (t_u32)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_u32(t_u32 lhs, t_u32 rhs, t_u32 *out) +{ + t_u32 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_u64.c b/output/src/convert/str_to_u64.c new file mode 100644 index 0000000..b744be8 --- /dev/null +++ b/output/src/convert/str_to_u64.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_u64(t_u64 lhs, t_u64 rhs, t_u64 *out); +t_error checked_sub_u64(t_u64 lhs, t_u64 rhs, t_u64 *out); +t_error checked_mul_u64(t_u64 lhs, t_u64 rhs, t_u64 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_u64) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_u64 digit, t_u8 op, t_u64 *result) +{ + t_u64 rhs; + t_u64 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_u64(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_u64(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_u64(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_u64 *out) +{ + t_u32 digit; + t_u64 result; + + result = 0llu; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_u64(t_const_str s, t_u32 radix, t_u64 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && false) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, false, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_u64_utils.c b/output/src/convert/str_to_u64_utils.c new file mode 100644 index 0000000..f2bb77f --- /dev/null +++ b/output/src/convert/str_to_u64_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_u64(t_u64 lhs, t_u64 rhs, t_u64 *out) +{ + if (rhs > 0 && (lhs > 18446744073709551615llu - rhs)) + return (ERROR); + *out = (t_u64)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_u64(t_u64 lhs, t_u64 rhs, t_u64 *out) +{ + if ((((rhs & (1 << (sizeof(t_u64) - 1)) || rhs == 0) || !false) + && (lhs < 0llu + rhs))) + return (ERROR); + *out = (t_u64)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_u64(t_u64 lhs, t_u64 rhs, t_u64 *out) +{ + t_u64 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/convert/str_to_u8.c b/output/src/convert/str_to_u8.c new file mode 100644 index 0000000..8fac9fa --- /dev/null +++ b/output/src/convert/str_to_u8.c @@ -0,0 +1,129 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/string/str_len.h" +#include "me/types.h" + +#define OP_ADD 0b0001 +#define OP_SUB 0b0010 +#define OP_MUL 0b0100 +#define OP_CHK 0b1000 + +t_error checked_add_u8(t_u8 lhs, t_u8 rhs, t_u8 *out); +t_error checked_sub_u8(t_u8 lhs, t_u8 rhs, t_u8 *out); +t_error checked_mul_u8(t_u8 lhs, t_u8 rhs, t_u8 *out); + +static inline bool can_not_overflow(t_u32 radix, bool is_signed_type, + t_usize digits_len) +{ + return (radix <= 16 && digits_len <= sizeof(t_u8) * 2 + - (t_usize)is_signed_type); +} + +static inline t_error to_digit(t_u8 ascii, t_u32 radix, t_u32 *out) +{ + t_u32 digit; + + if (radix < 2 || radix > 36) + return (ERROR); + digit = ascii - '0'; + if (radix > 10 && digit >= 10) + { + if (!me_isalpha(ascii)) + return (ERROR); + digit = ((ascii | 0b100000) - 'a') + 10; + } + if (digit >= radix) + return (ERROR); + *out = digit; + return (NO_ERROR); +} + +static inline t_error do_operation(t_u8 digit, t_u8 op, t_u8 *result) +{ + t_u8 rhs; + t_u8 res; + + rhs = *result; + res = *result; + if (op & OP_CHK) + { + if (op & OP_MUL && checked_mul_u8(rhs, digit, &res)) + return (ERROR); + else if (op & OP_ADD && checked_add_u8(rhs, digit, &res)) + return (ERROR); + else if (op & OP_SUB && checked_sub_u8(rhs, digit, &res)) + return (ERROR); + } + else + { + if (op & OP_MUL) + res = rhs * digit; + else if (op & OP_ADD) + res = rhs + digit; + else if (op & OP_SUB) + res = rhs - digit; + } + *result = res; + return (NO_ERROR); +} + +static inline t_error loop_inner(t_const_str s, t_u32 radix, t_u8 op, + t_u8 *out) +{ + t_u32 digit; + t_u8 result; + + result = 0u; + while (*s) + { + if (do_operation(radix, (op & OP_CHK) | OP_MUL, &result)) + return (ERROR); + if (to_digit(*s, radix, &digit)) + return (ERROR); + if (do_operation(digit, op, &result)) + return (ERROR); + s++; + } + if (out) + *out = result; + return (NO_ERROR); +} + +t_error str_to_u8(t_const_str s, t_u32 radix, t_u8 *out) +{ + t_usize digits_len; + bool is_positive; + t_u8 op; + + if (radix < 2 || radix > 36) + return (ERROR); + digits_len = str_len(s); + is_positive = true; + if (digits_len == 0) + return (ERROR); + if ((s[0] == '-' || s[0] == '+') && s[1] == '\0') + return (ERROR); + else if (s[0] == '+') + is_positive = (s++, digits_len--, true); + else if (s[0] == '-' && false) + is_positive = (s++, digits_len--, false); + if (is_positive) + op = OP_ADD; + else + op = OP_SUB; + if (!can_not_overflow(radix, false, digits_len)) + op |= OP_CHK; + return (loop_inner(s, radix, op, out)); +} diff --git a/output/src/convert/str_to_u8_utils.c b/output/src/convert/str_to_u8_utils.c new file mode 100644 index 0000000..14a4a04 --- /dev/null +++ b/output/src/convert/str_to_u8_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* str_to_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:15:19 by maiboyer #+# #+# */ +/* Updated: 2024/02/01 23:18:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/char/isalpha.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_len.h" +#include "me/types.h" + +t_error checked_add_u8(t_u8 lhs, t_u8 rhs, t_u8 *out) +{ + if (rhs > 0 && (lhs > 128u - rhs)) + return (ERROR); + *out = (t_u8)(lhs + rhs); + return (NO_ERROR); +} + +t_error checked_sub_u8(t_u8 lhs, t_u8 rhs, t_u8 *out) +{ + if ((((rhs & (1 << (sizeof(t_u8) - 1)) || rhs == 0) || !false) && (lhs < 0u + + rhs))) + return (ERROR); + *out = (t_u8)(lhs - rhs); + return (NO_ERROR); +} + +t_error checked_mul_u8(t_u8 lhs, t_u8 rhs, t_u8 *out) +{ + t_u8 mul; + + mul = lhs * rhs; + if (lhs != 0 && mul / lhs != rhs) + return (ERROR); + *out = mul; + return (NO_ERROR); +} diff --git a/output/src/vec/vec_i64.c b/output/src/vec/vec_i64.c new file mode 100644 index 0000000..1a24dec --- /dev/null +++ b/output/src/vec/vec_i64.c @@ -0,0 +1,114 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/05 18:46:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:54:11 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include + +t_vec_i64 vec_i64_new(t_usize capacity, t_free_i64_item free_function) +{ + t_vec_i64 out; + + out = (t_vec_i64){0}; + out.free_func = free_function; + out.buffer = mem_alloc_array(capacity, sizeof(t_i64)); + if (out.buffer) + out.capacity = capacity; + return (out); +} + +/// Return true in case of an error +t_error vec_i64_push(t_vec_i64 *vec, t_i64 element) +{ + t_i64 *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (vec->len + 1 > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (vec->len + 1 > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_i64)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_i64)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + vec->buffer[vec->len] = element; + vec->len += 1; + return (NO_ERROR); +} + +/// Return true in case of an error +t_error vec_i64_reserve(t_vec_i64 *vec, t_usize wanted_capacity) +{ + t_i64 *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (wanted_capacity > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (wanted_capacity > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_i64)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_i64)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + return (NO_ERROR); +} + +/// Return true if the vector is empty +/// This function is safe to call with value being NULL +t_error vec_i64_pop(t_vec_i64 *vec, t_i64 *value) +{ + t_i64 temp_value; + t_i64 *ptr; + + if (vec == NULL) + return (ERROR); + ptr = value; + if (vec->len == 0) + return (ERROR); + if (value == NULL) + ptr = &temp_value; + vec->len--; + *ptr = vec->buffer[vec->len]; + mem_set_zero(&vec->buffer[vec->len], sizeof(t_i64)); + return (NO_ERROR); +} + +/// This function is safe to call with `free_elem` being NULL +void vec_i64_free(t_vec_i64 vec) +{ + if (vec.free_func) + { + while (vec.len) + { + vec.free_func(vec.buffer[vec.len - 1]); + vec.len--; + } + } + free(vec.buffer); +} diff --git a/output/src/vec/vec_i64_bool.c b/output/src/vec/vec_i64_bool.c new file mode 100644 index 0000000..af10724 --- /dev/null +++ b/output/src/vec/vec_i64_bool.c @@ -0,0 +1,115 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64_bool.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/05 18:46:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/09 17:54:11 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64_bool.h" +#include + +t_vec_i64_bool vec_i64_bool_new(t_usize capacity, + t_free_i64_bool_item free_function) +{ + t_vec_i64_bool out; + + out = (t_vec_i64_bool){0}; + out.free_func = free_function; + out.buffer = mem_alloc_array(capacity, sizeof(t_i64_bool)); + if (out.buffer) + out.capacity = capacity; + return (out); +} + +/// Return true in case of an error +t_error vec_i64_bool_push(t_vec_i64_bool *vec, t_i64_bool element) +{ + t_i64_bool *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (vec->len + 1 > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (vec->len + 1 > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_i64_bool)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_i64_bool)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + vec->buffer[vec->len] = element; + vec->len += 1; + return (NO_ERROR); +} + +/// Return true in case of an error +t_error vec_i64_bool_reserve(t_vec_i64_bool *vec, t_usize wanted_capacity) +{ + t_i64_bool *temp_buffer; + size_t new_capacity; + + if (vec == NULL) + return (ERROR); + if (wanted_capacity > vec->capacity) + { + new_capacity = (vec->capacity * 3) / 2 + 1; + while (wanted_capacity > new_capacity) + new_capacity = (new_capacity * 3) / 2 + 1; + temp_buffer = mem_alloc_array(new_capacity, sizeof(t_i64_bool)); + if (temp_buffer == NULL) + return (ERROR); + mem_copy(temp_buffer, vec->buffer, vec->len * sizeof(t_i64_bool)); + free(vec->buffer); + vec->buffer = temp_buffer; + vec->capacity = new_capacity; + } + return (NO_ERROR); +} + +/// Return true if the vector is empty +/// This function is safe to call with value being NULL +t_error vec_i64_bool_pop(t_vec_i64_bool *vec, t_i64_bool *value) +{ + t_i64_bool temp_value; + t_i64_bool *ptr; + + if (vec == NULL) + return (ERROR); + ptr = value; + if (vec->len == 0) + return (ERROR); + if (value == NULL) + ptr = &temp_value; + vec->len--; + *ptr = vec->buffer[vec->len]; + mem_set_zero(&vec->buffer[vec->len], sizeof(t_i64_bool)); + return (NO_ERROR); +} + +/// This function is safe to call with `free_elem` being NULL +void vec_i64_bool_free(t_vec_i64_bool vec) +{ + if (vec.free_func) + { + while (vec.len) + { + vec.free_func(vec.buffer[vec.len - 1]); + vec.len--; + } + } + free(vec.buffer); +} diff --git a/output/src/vec/vec_i64_bool_functions2.c b/output/src/vec/vec_i64_bool_functions2.c new file mode 100644 index 0000000..01927c2 --- /dev/null +++ b/output/src/vec/vec_i64_bool_functions2.c @@ -0,0 +1,109 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64_bool.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64_bool.h" +#include + +t_error vec_i64_bool_find(t_vec_i64_bool *vec, bool (*fn)(const t_i64_bool *), + t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = 0; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_i64_bool_find_starting(t_vec_i64_bool *vec, + bool (*fn)(const t_i64_bool *), t_usize starting_index, t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = starting_index; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_i64_bool_all(t_vec_i64_bool *vec, bool (*fn)(const t_i64_bool *), + bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = true; + while (*result && idx < vec->len) + { + if (!fn(&vec->buffer[idx])) + *result = false; + idx++; + } + return (ERROR); +} + +t_error vec_i64_bool_any(t_vec_i64_bool *vec, bool (*fn)(const t_i64_bool *), + bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = false; + while (*result && idx < vec->len) + { + if (fn(&vec->buffer[idx])) + *result = true; + idx++; + } + return (ERROR); +} + +void vec_i64_bool_iter(t_vec_i64_bool *vec, void (*fn)(t_usize index, + t_i64_bool *value, void *state), void *state) +{ + t_usize idx; + + if (vec == NULL || fn == NULL) + return ; + idx = 0; + while (idx < vec->len) + { + fn(idx, &vec->buffer[idx], state); + idx++; + } +} diff --git a/output/src/vec/vec_i64_bool_functions3.c b/output/src/vec/vec_i64_bool_functions3.c new file mode 100644 index 0000000..ee82947 --- /dev/null +++ b/output/src/vec/vec_i64_bool_functions3.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64_bool.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64_bool.h" +#include + +t_error vec_i64_bool_push_front(t_vec_i64_bool *vec, t_i64_bool element) +{ + t_usize i; + + if (vec->len == 0) + return (vec_i64_bool_push(vec, element)); + i = vec->len - 1; + if (vec->capacity < vec->len + 1 && vec_i64_bool_reserve(vec, 3 * vec->len + / 2 + 1)) + return (ERROR); + while (i > 0) + { + vec->buffer[i + 1] = vec->buffer[i]; + i--; + } + vec->buffer[1] = vec->buffer[0]; + vec->buffer[0] = element; + vec->len++; + return (NO_ERROR); +} + +t_error vec_i64_bool_pop_front(t_vec_i64_bool *vec, t_i64_bool *value) +{ + t_usize i; + + if (vec->len <= 1) + return (vec_i64_bool_pop(vec, value)); + i = 0; + *value = vec->buffer[0]; + vec->len--; + while (i < vec->len) + { + vec->buffer[i] = vec->buffer[i + 1]; + i++; + } + mem_set_zero(&vec->buffer[i], sizeof(*vec->buffer)); + return (NO_ERROR); +} + +void vec_i64_bool_reverse(t_vec_i64_bool *vec) +{ + t_i64_bool temporary; + t_usize i; + + i = 0; + while (i < vec->len / 2) + { + temporary = vec->buffer[vec->len - 1 - i]; + vec->buffer[vec->len - 1 - i] = vec->buffer[i]; + vec->buffer[i] = temporary; + i++; + } +} diff --git a/output/src/vec/vec_i64_bool_sort.c b/output/src/vec/vec_i64_bool_sort.c new file mode 100644 index 0000000..edbdfc1 --- /dev/null +++ b/output/src/vec/vec_i64_bool_sort.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* best_move.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 20:04:33 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:25:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/types.h" +#include "me/vec/vec_i64_bool.h" + +void vec_i64_bool_sort(t_vec_i64_bool *v, + t_vec_i64_bool_sort_fn is_sorted_fn) +{ + t_usize sorted_part; + t_usize i; + t_i64_bool tmp; + + if (v == NULL) + return ; + sorted_part = v->len; + while (sorted_part > 0) + { + i = 0; + while (i < sorted_part - 1) + { + if (!is_sorted_fn(&v->buffer[i], &v->buffer[i + 1])) + { + tmp = v->buffer[i]; + v->buffer[i] = v->buffer[i + 1]; + v->buffer[i + 1] = tmp; + } + i++; + } + sorted_part--; + } +} diff --git a/output/src/vec/vec_i64_functions2.c b/output/src/vec/vec_i64_functions2.c new file mode 100644 index 0000000..d7180bc --- /dev/null +++ b/output/src/vec/vec_i64_functions2.c @@ -0,0 +1,106 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include + +t_error vec_i64_find(t_vec_i64 *vec, bool (*fn)(const t_i64 *), t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = 0; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_i64_find_starting(t_vec_i64 *vec, bool (*fn)(const t_i64 *), + t_usize starting_index, t_usize *index) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || index == NULL) + return (ERROR); + idx = starting_index; + while (idx < vec->len) + { + if (fn(&vec->buffer[idx])) + { + *index = idx; + return (NO_ERROR); + } + idx++; + } + return (ERROR); +} + +t_error vec_i64_all(t_vec_i64 *vec, bool (*fn)(const t_i64 *), bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = true; + while (*result && idx < vec->len) + { + if (!fn(&vec->buffer[idx])) + *result = false; + idx++; + } + return (ERROR); +} + +t_error vec_i64_any(t_vec_i64 *vec, bool (*fn)(const t_i64 *), bool *result) +{ + t_usize idx; + + if (vec == NULL || fn == NULL || result == NULL) + return (ERROR); + idx = 0; + *result = false; + while (*result && idx < vec->len) + { + if (fn(&vec->buffer[idx])) + *result = true; + idx++; + } + return (ERROR); +} + +void vec_i64_iter(t_vec_i64 *vec, void (*fn)(t_usize index, t_i64 *value, + void *state), void *state) +{ + t_usize idx; + + if (vec == NULL || fn == NULL) + return ; + idx = 0; + while (idx < vec->len) + { + fn(idx, &vec->buffer[idx], state); + idx++; + } +} diff --git a/output/src/vec/vec_i64_functions3.c b/output/src/vec/vec_i64_functions3.c new file mode 100644 index 0000000..653eee8 --- /dev/null +++ b/output/src/vec/vec_i64_functions3.c @@ -0,0 +1,72 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* vec_i64.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2023/12/30 17:59:28 by maiboyer #+# #+# */ +/* Updated: 2023/12/30 17:59:28 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem_alloc_array.h" +#include "me/mem/mem_copy.h" +#include "me/mem/mem_set_zero.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include + +t_error vec_i64_push_front(t_vec_i64 *vec, t_i64 element) +{ + t_usize i; + + if (vec->len == 0) + return (vec_i64_push(vec, element)); + i = vec->len - 1; + if (vec->capacity < vec->len + 1 && vec_i64_reserve(vec, 3 * vec->len / 2 + + 1)) + return (ERROR); + while (i > 0) + { + vec->buffer[i + 1] = vec->buffer[i]; + i--; + } + vec->buffer[1] = vec->buffer[0]; + vec->buffer[0] = element; + vec->len++; + return (NO_ERROR); +} + +t_error vec_i64_pop_front(t_vec_i64 *vec, t_i64 *value) +{ + t_usize i; + + if (vec->len <= 1) + return (vec_i64_pop(vec, value)); + i = 0; + *value = vec->buffer[0]; + vec->len--; + while (i < vec->len) + { + vec->buffer[i] = vec->buffer[i + 1]; + i++; + } + mem_set_zero(&vec->buffer[i], sizeof(*vec->buffer)); + return (NO_ERROR); +} + +void vec_i64_reverse(t_vec_i64 *vec) +{ + t_i64 temporary; + t_usize i; + + i = 0; + while (i < vec->len / 2) + { + temporary = vec->buffer[vec->len - 1 - i]; + vec->buffer[vec->len - 1 - i] = vec->buffer[i]; + vec->buffer[i] = temporary; + i++; + } +} diff --git a/output/src/vec/vec_i64_sort.c b/output/src/vec/vec_i64_sort.c new file mode 100644 index 0000000..d32b66b --- /dev/null +++ b/output/src/vec/vec_i64_sort.c @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* best_move.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 20:04:33 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:25:00 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/types.h" +#include "me/vec/vec_i64.h" + +void vec_i64_sort(t_vec_i64 *v, t_vec_i64_sort_fn is_sorted_fn) +{ + t_usize sorted_part; + t_usize i; + t_i64 tmp; + + if (v == NULL) + return ; + sorted_part = v->len; + while (sorted_part > 0) + { + i = 0; + while (i < sorted_part - 1) + { + if (!is_sorted_fn(&v->buffer[i], &v->buffer[i + 1])) + { + tmp = v->buffer[i]; + v->buffer[i] = v->buffer[i + 1]; + v->buffer[i + 1] = tmp; + } + i++; + } + sorted_part--; + } +} diff --git a/src.list b/src.list new file mode 100644 index 0000000..e78502d --- /dev/null +++ b/src.list @@ -0,0 +1,21 @@ +app/actual_main +app/best_index_to_move +app/best_move +app/do_move +app/find_place +app/iter_find +app/main +app/main_bonus +app/moves +app/moves/push +app/moves/rev_rotate +app/moves/rotate +app/moves/swap +app/rotate +app/run_with_items +app/sort2 +app/sort3 +app/sort5 +app/state +app/target +bonus/move1 diff --git a/src/app/actual_main.c b/src/app/actual_main.c new file mode 100644 index 0000000..6804f8b --- /dev/null +++ b/src/app/actual_main.c @@ -0,0 +1,26 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* actual_main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/09 15:10:39 by maiboyer #+# #+# */ +/* Updated: 2024/02/09 15:26:33 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/state.h" +#include "me/printf/printf.h" +#include "me/string/str_n_compare.h" +#include "me/types.h" + +int main_normal(t_i32 argc, t_str argv[]); +int main_checker(t_i32 argc, t_str argv[]); + +int main(t_i32 argc, t_str argv[]) +{ + if (BONUS) + return (main_checker(argc, argv)); + return (main_normal(argc, argv)); +} diff --git a/src/app/best_index_to_move.c b/src/app/best_index_to_move.c new file mode 100644 index 0000000..1b37701 --- /dev/null +++ b/src/app/best_index_to_move.c @@ -0,0 +1,77 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* best_index_to_move.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/08 14:14:54 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 14:21:51 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/best_index_to_move.h" +#include "app/best_move.h" +#include "app/find_iter.h" +#include "app/rotate.h" +#include "app/state.h" +#include "app/target.h" +#include "me/printf/printf.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include "me/vec/vec_i64_bool.h" +#include + +static void inc(void *s) +{ + t_usize *p; + + p = (t_usize *)s; + *p += 1; +} + +static inline t_usize count_move_for_index(struct s_best_index_to_move d) +{ + t_usize tmp; + + tmp = 0; + run_func_with_best_rotate_for_item(d.state, + (t_best_move_args){ + .index = d.i, + .args = &tmp, + .iter_func = d.f, + .from = d.from, + .to = d.to, + .other = {inc, inc}, + .main = {inc, inc}, + .both = {inc, inc}, + }); + return (tmp); +} + +t_usize best_index_to_move(t_state *state, t_vec_i64 *from, t_vec_i64 *to, + t_iter_pos_func f) +{ + t_usize min_val; + t_usize min_pos; + t_usize i; + t_usize tmp; + + if (from->len == 0) + return (0); + i = 0; + min_val = ~0; + min_pos = 0; + while (i < from->len) + { + tmp = count_move_for_index((struct s_best_index_to_move){state, from, + to, f, i}); + if (tmp < min_val) + { + min_val = tmp; + min_pos = i; + } + i++; + } + return (min_pos); +} diff --git a/src/app/best_move.c b/src/app/best_move.c new file mode 100644 index 0000000..2bbbfdf --- /dev/null +++ b/src/app/best_move.c @@ -0,0 +1,99 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* best_move.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 20:04:33 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 14:22:55 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/best_move.h" +#include "app/best_move_inner.h" +#include "app/find_iter.h" +#include "app/find_place.h" +#include "app/rotate.h" +#include "app/state.h" +#include "app/target.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include + +static inline t_isize move_count(t_rotation lhs, t_rotation rhs) +{ + if (lhs.direction == rhs.direction) + return (max(lhs.value, rhs.value)); + else + return (abs_diff(lhs.value, rhs.value)); +} + +void find_least_move(t_rotation *main, t_rotation *other) +{ + t_isize main_fliped; + t_isize other_fliped; + t_isize none_fliped; + t_rotation tmp; + t_isize minimum; + + none_fliped = move_count(*main, *other); + main_fliped = move_count(flip(*main), *other); + other_fliped = move_count(*main, flip(*other)); + minimum = min(none_fliped, min(main_fliped, other_fliped)); + if (minimum == none_fliped) + return ; + else if (minimum == main_fliped) + { + tmp = flip(*main); + *main = tmp; + } + else if (minimum == other_fliped) + { + tmp = flip(*other); + *other = tmp; + } +} + +static inline void func(t_best_move_args *data, t_rotation *main, + t_rotation *other) +{ + t_isize i; + + i = 0; + while (i++ < min(main->value, other->value)) + choose_func(&data->both, *main)(data->args); + i = 0; + if (main->value > other->value) + while (i++ < main->value - other->value) + choose_func(&data->main, *main)(data->args); + else + while (i++ < other->value - main->value) + choose_func(&data->other, *other)(data->args); +} + +void run_func_with_best_rotate_for_item(t_state *state, + t_best_move_args data) +{ + t_isize target_index; + t_rotation main; + t_rotation other; + t_isize i; + + target_index = (find_place(data.from->buffer[data.index], state) + + (data.to->len - data.iter_func(data.to))) % max(data.to->len, 1); + main = target(0, data.index, data.from->len); + other = target(target_index, 0, data.to->len); + find_least_move(&main, &other); + if (main.direction == other.direction) + func(&data, &main, &other); + else + { + i = 0; + while (i++ < main.value) + choose_func(&data.main, main)(data.args); + i = 0; + while (i++ < other.value) + choose_func(&data.other, other)(data.args); + } +} diff --git a/src/app/do_move.c b/src/app/do_move.c new file mode 100644 index 0000000..96b06b1 --- /dev/null +++ b/src/app/do_move.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* do_move.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/31 14:25:57 by maiboyer #+# #+# */ +/* Updated: 2024/02/02 22:54:12 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/best_move.h" +#include "app/moves.h" +#include "app/state.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" + +void push_a(void *s); +void push_b(void *s); +void swap_a(void *s); +void swap_b(void *s); +void swap_both(void *s); +void rotate_a(void *s); +void rotate_b(void *s); +void rotate_both(void *s); +void rev_rotate_a(void *s); +void rev_rotate_b(void *s); +void rev_rotate_both(void *s); diff --git a/src/app/find_place.c b/src/app/find_place.c new file mode 100644 index 0000000..1a3efd6 --- /dev/null +++ b/src/app/find_place.c @@ -0,0 +1,52 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* find_place.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 22:01:12 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 14:06:05 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/find_place.h" +#include "app/types/type_i64_bool.h" +#include "me/vec/vec_i64_bool.h" + +static void find_place_iter(t_usize index, t_i64_bool *elem, + t_find_place_iter_state *state) +{ + (void)(index); + if (!(elem->active || elem->value == state->to_find_elem)) + return ; + if (elem->value == state->to_find_elem) + state->found_index = state->current_index; + state->current_index++; +} + +t_usize find_place(t_i64 elem, t_state *state) +{ + t_find_place_iter_state iter_state; + + iter_state.current_index = 0; + iter_state.found_index = 0; + iter_state.to_find_elem = elem; + vec_i64_bool_iter(&state->sorted, (void (*)())find_place_iter, &iter_state); + return (iter_state.found_index); +} + +/* +state + .sorted + .iter() + .copied() + .filter(|&(e, active)| active || elem == e) + .enumerate() + .find(|(_, (e, _))| *e == elem) + .map(|(i, _)| i) + .unwrap_or_else(|| { + println!("why..."); + 0 + }) +*/ diff --git a/src/app/iter_find.c b/src/app/iter_find.c new file mode 100644 index 0000000..bd6d1cf --- /dev/null +++ b/src/app/iter_find.c @@ -0,0 +1,57 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* iter_find.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/31 14:17:53 by maiboyer #+# #+# */ +/* Updated: 2024/01/31 14:23:26 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/iter_state.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" + +static void iter_min(t_usize index, t_i64 *elem, t_iter_state *state) +{ + if (*elem < state->elem) + { + state->elem = *elem; + state->pos = index; + } +} + +static void iter_max(t_usize index, t_i64 *elem, t_iter_state *state) +{ + if (*elem > state->elem) + { + state->elem = *elem; + state->pos = index; + } +} + +t_usize min_iter_zero_pos(t_vec_i64 *vec) +{ + t_iter_state state; + + if (vec->len == 0) + return (0); + state.pos = 0; + state.elem = vec->buffer[0]; + vec_i64_iter(vec, (void (*)())iter_min, &state); + return (state.pos); +} + +t_usize max_iter_zero_pos(t_vec_i64 *vec) +{ + t_iter_state state; + + if (vec->len == 0) + return (0); + state.pos = 0; + state.elem = vec->buffer[0]; + vec_i64_iter(vec, (void (*)())iter_max, &state); + return (state.pos); +} diff --git a/src/app/main.c b/src/app/main.c new file mode 100644 index 0000000..e234e3e --- /dev/null +++ b/src/app/main.c @@ -0,0 +1,64 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:00:12 by maiboyer #+# #+# */ +/* Updated: 2024/02/15 17:42:03 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/state.h" +#include "app/types/type_i64_bool.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_n_compare.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include "me/vec/vec_i64_bool.h" +#include +#include + +#if BONUS == 1 + +# define ERR_INVALID_NUM "Error\n" +# define ERR_DUPLICATE "Error\n" + +#else + +//# define ERR_INVALID_NUM "Error:\nInvalid Number\n" +//# define ERR_DUPLICATE "Error:\nDuplicate Number\n" +# define ERR_INVALID_NUM "Error\n" +# define ERR_DUPLICATE "Error\n" + +#endif + +void sort_3(t_state *state); +void sort_2(t_state *state); +void sort_5(t_state *state); +bool is_sorted(t_vec_i64 *v); +void run_with_items(t_state *state); + +int main_normal(t_i32 argc, t_str argv[]) +{ + t_state state; + + (void)(argc--, argv++); + state = parses_arguments(argc, argv); + if (is_sorted(&state.stack_a)) + return (free_state(state), 0); + if (state.stack_a.len == 0) + (free_state(state), exit(0)); + else if (state.stack_a.len == 2) + sort_2(&state); + else if (state.stack_a.len == 3) + sort_3(&state); + else if (state.stack_a.len == 5) + sort_5(&state); + else + run_with_items(&state); + free_state(state); + return (0); +} diff --git a/src/app/main_bonus.c b/src/app/main_bonus.c new file mode 100644 index 0000000..4de3a02 --- /dev/null +++ b/src/app/main_bonus.c @@ -0,0 +1,105 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* main_bonus.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/08 18:59:33 by maiboyer #+# #+# */ +/* Updated: 2024/02/15 17:47:33 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/state.h" +#include "me/buffered_str/buf_str.h" +#include "me/gnl/gnl.h" +#include "me/printf/printf.h" +#include "me/string/str_n_compare.h" +#include "me/vec/vec_i64.h" + +#if BONUS + +void push_inner(t_vec_i64 *to, t_vec_i64 *from, t_const_str tag, + t_const_str print); +void swap_inner(t_vec_i64 *vec, t_const_str tag, t_const_str print); +void rotate_inner(t_vec_i64 *vec, t_const_str tag, t_const_str print); +void rev_rotate_inner(t_vec_i64 *vec, t_const_str tag, t_const_str print); +bool is_sorted(t_vec_i64 *v); + +bool does_match_strings(t_const_str in, t_const_str s1, t_const_str s2) +{ + bool res; + + res = (str_n_compare(in, s1, 4) == 0); + if (s2 != NULL) + res = (res || (str_n_compare(in, s2, 4) == 0)); + return (res); +} + +t_error handle_operation(t_buffer_str s, t_state *state) +{ + t_usize op; + + op = 0; + if (s.buf == NULL) + return (ERROR); + if (does_match_strings(s.buf, "pa", NULL)) + push_inner(&state->stack_a, &state->stack_b, NULL, (op++, NULL)); + if (does_match_strings(s.buf, "pb", NULL)) + push_inner(&state->stack_b, &state->stack_a, NULL, (op++, NULL)); + if (does_match_strings(s.buf, "sa", "ss")) + swap_inner(&state->stack_a, NULL, (op++, NULL)); + if (does_match_strings(s.buf, "sb", "ss")) + swap_inner(&state->stack_b, NULL, (op++, NULL)); + if (does_match_strings(s.buf, "ra", "rr")) + rotate_inner(&state->stack_a, NULL, (op++, NULL)); + if (does_match_strings(s.buf, "rb", "rr")) + rotate_inner(&state->stack_b, NULL, (op++, NULL)); + if (does_match_strings(s.buf, "rra", "rrr")) + rev_rotate_inner(&state->stack_a, NULL, (op++, NULL)); + if (does_match_strings(s.buf, "rrb", "rrr")) + rev_rotate_inner(&state->stack_b, NULL, (op++, NULL)); + if (op == 0) + return (ERROR); + return (NO_ERROR); +} + +void handle_end(t_state state, t_buffer_str s) +{ + str_free(s); + if (is_sorted(&state.stack_a) && state.stack_b.len == 0) + me_printf("OK\n"); + else + me_printf("KO\n"); + free_state(state); +} + +int main_checker(t_i32 argc, t_str argv[]) +{ + t_state state; + t_buffer_str s; + bool err; + + (void)(argc--, argv++); + s.buf = ""; + err = false; + state = parses_arguments(argc, argv); + while (!err) + { + s = get_next_line(0, &err); + if (err) + break ; + if (s.len != 0 && s.buf[s.len - 1] == '\n') + str_pop(&s); + if (s.buf[0] == '\0') + continue ; + if (handle_operation(s, &state)) + return (me_printf("KO\n"), str_free(s), free_state(state), 1); + if (s.buf != NULL) + str_free(s); + } + handle_end(state, s); + return (0); +} + +#endif diff --git a/src/app/moves.c b/src/app/moves.c new file mode 100644 index 0000000..1eef164 --- /dev/null +++ b/src/app/moves.c @@ -0,0 +1,71 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* moves.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:17:26 by maiboyer #+# #+# */ +/* Updated: 2024/01/29 18:58:48 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/moves.h" +#include "app/state.h" +#include "app/types/type_move.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); +} + +t_const_str get_str_for_move(t_move m) +{ + if (m & PUSH_A) + return ("pa"); + if (m & PUSH_B) + return ("pb"); + if (m & SWAP_A && m & SWAP_B) + return ("ss"); + if (m & SWAP_A) + return ("sa"); + if (m & SWAP_B) + return ("sb"); + if (m & ROTATE_A && m & ROTATE_B) + return ("rr"); + if (m & ROTATE_A) + return ("ra"); + if (m & ROTATE_B) + return ("rb"); + if (m & REVERSE_ROTATE_A && m & REVERSE_ROTATE_B) + return ("rrr"); + if (m & REVERSE_ROTATE_A) + return ("rra"); + if (m & REVERSE_ROTATE_B) + return ("rrb"); + return (""); +} diff --git a/src/app/moves/push.c b/src/app/moves/push.c new file mode 100644 index 0000000..dc53491 --- /dev/null +++ b/src/app/moves/push.c @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* push.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:22:54 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 19:15:58 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/state.h" +#include "me/printf/printf.h" +#include "me/vec/vec_i64.h" + +void push_inner(t_vec_i64 *to, t_vec_i64 *from, t_const_str tag, + t_const_str print) +{ + t_i64 e; + + (void)(tag); + if (from->len == 0) + return ; + vec_i64_pop_front(from, &e); + vec_i64_push_front(to, e); + if (print) + me_printf("%s\n", print); +} + +void push_a(t_state *s) +{ + push_inner(&s->stack_a, &s->stack_b, "Push A", "pa"); +} + +void push_b(t_state *s) +{ + push_inner(&s->stack_b, &s->stack_a, "Push B", "pb"); +} diff --git a/src/app/moves/rev_rotate.c b/src/app/moves/rev_rotate.c new file mode 100644 index 0000000..f630ea0 --- /dev/null +++ b/src/app/moves/rev_rotate.c @@ -0,0 +1,44 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* rev_rotate.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:26:04 by maiboyer #+# #+# */ +/* Updated: 2024/02/10 18:39:03 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/state.h" +#include "me/printf/printf.h" + +void rev_rotate_inner(t_vec_i64 *stack, t_const_str tag, + t_const_str print) +{ + t_i64 e; + + (void)(tag); + if (stack->len < 2) + return ; + vec_i64_pop(stack, &e); + vec_i64_push_front(stack, e); + if (print) + me_printf("%s\n", print); +} + +void rev_rotate_a(t_state *s) +{ + rev_rotate_inner(&s->stack_a, "RevRotate A", "rra"); +} + +void rev_rotate_b(t_state *s) +{ + rev_rotate_inner(&s->stack_b, "RevRotate B", "rrb"); +} + +void rev_rotate_both(t_state *s) +{ + rev_rotate_inner(&s->stack_a, "RevRotate Both", NULL); + rev_rotate_inner(&s->stack_b, "RevRotate Both", "rrr"); +} diff --git a/src/app/moves/rotate.c b/src/app/moves/rotate.c new file mode 100644 index 0000000..86cd2aa --- /dev/null +++ b/src/app/moves/rotate.c @@ -0,0 +1,43 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* rotate.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:26:04 by maiboyer #+# #+# */ +/* Updated: 2024/02/10 18:38:52 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/state.h" +#include "me/printf/printf.h" + +void rotate_inner(t_vec_i64 *stack, t_const_str tag, t_const_str print) +{ + t_i64 e; + + (void)(tag); + if (stack->len < 2) + return ; + vec_i64_pop_front(stack, &e); + vec_i64_push(stack, e); + if (print) + me_printf("%s\n", print); +} + +void rotate_a(t_state *s) +{ + rotate_inner(&s->stack_a, "Rotate A", "ra"); +} + +void rotate_b(t_state *s) +{ + rotate_inner(&s->stack_b, "Rotate B", "rb"); +} + +void rotate_both(t_state *s) +{ + rotate_inner(&s->stack_a, "Rotate Both", NULL); + rotate_inner(&s->stack_b, "Rotate Both", "rr"); +} diff --git a/src/app/moves/swap.c b/src/app/moves/swap.c new file mode 100644 index 0000000..934cedd --- /dev/null +++ b/src/app/moves/swap.c @@ -0,0 +1,47 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* swap.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/11 16:26:04 by maiboyer #+# #+# */ +/* Updated: 2024/02/09 15:40:37 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/state.h" +#include "me/printf/printf.h" +#include "me/vec/vec_i64.h" + +void swap_inner(t_vec_i64 *stack, t_const_str tag, t_const_str print) +{ + t_i64 first; + t_i64 second; + + (void)(tag); + if (stack->len < 2) + return ; + vec_i64_pop_front(stack, &first); + vec_i64_pop_front(stack, &second); + vec_i64_push_front(stack, first); + vec_i64_push_front(stack, second); + if (print) + me_printf("%s\n", print); +} + +void swap_a(t_state *s) +{ + swap_inner(&s->stack_a, "Swap A", "sa"); +} + +void swap_b(t_state *s) +{ + swap_inner(&s->stack_b, "Swap B", "sb"); +} + +void swap_both(t_state *s) +{ + swap_inner(&s->stack_a, "Swap Both", NULL); + swap_inner(&s->stack_b, "Swap Both", "ss"); +} diff --git a/src/app/rotate.c b/src/app/rotate.c new file mode 100644 index 0000000..33c6652 --- /dev/null +++ b/src/app/rotate.c @@ -0,0 +1,14 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* rotate.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 18:59:56 by maiboyer #+# #+# */ +/* Updated: 2024/01/29 20:04:18 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/rotate.h" +#include "me/types.h" diff --git a/src/app/run_with_items.c b/src/app/run_with_items.c new file mode 100644 index 0000000..45ed8df --- /dev/null +++ b/src/app/run_with_items.c @@ -0,0 +1,114 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* run_with_items.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/31 15:12:47 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 14:22:15 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/best_move.h" +#include "app/find_iter.h" +#include "app/rotate.h" +#include "app/state.h" +#include "app/target.h" +#include "me/printf/printf.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include "me/vec/vec_i64_bool.h" +#include + +void push_a(void *s); +void push_b(void *s); +void swap_a(void *s); +void swap_b(void *s); +void swap_both(void *s); +void rotate_a(void *s); +void rotate_b(void *s); +void rotate_both(void *s); +void rev_rotate_a(void *s); +void rev_rotate_b(void *s); +void rev_rotate_both(void *s); + +t_usize best_index_to_move(t_state *state, t_vec_i64 *from, t_vec_i64 *to, + t_iter_pos_func f); + +static inline struct s_functions funcs( void (*f)(void *), void (*r)(void *)) +{ + return ((struct s_functions){.forward = f, .reverse = r}); +} + +static inline void banana_first(t_state *state) +{ + t_usize idx; + + idx = best_index_to_move(state, &state->stack_a, &state->stack_b, + &max_iter_zero_pos); + run_func_with_best_rotate_for_item(state, + (t_best_move_args){ + .index = idx, .iter_func = &max_iter_zero_pos, .from = \ +&state->stack_a, .to = &state->stack_b, .args = state, .both = \ +funcs(rotate_both, rev_rotate_both), .main = funcs(rotate_a, rev_rotate_a), \ +.other = funcs(rotate_b, rev_rotate_b), }); + push_b(state); + make_sorted_true_from_stack(state, &state->stack_b); +} + +bool is_sorted(t_vec_i64 *v) +{ + t_usize i; + + i = 1; + while (i < v->len) + { + if (v->buffer[i - 1] > v->buffer[i]) + return (false); + i++; + } + return (true); +} + +static inline void banana_second(t_state *state) +{ + t_usize idx; + + idx = best_index_to_move(state, &state->stack_b, &state->stack_a, + &min_iter_zero_pos); + run_func_with_best_rotate_for_item(state, (t_best_move_args){ + .index = idx, .from = &state->stack_b, \ +.to = &state->stack_a, .iter_func = &min_iter_zero_pos, .args = state, \ +.both = funcs(rotate_both, rev_rotate_both), .main = funcs(rotate_b, \ +rev_rotate_b), .other = funcs(rotate_a, rev_rotate_a), }); + push_a(state); + make_sorted_true_from_stack(state, &state->stack_a); +} + +void run_with_items(t_state *state) +{ + t_rotation rot; + + if (is_sorted(&state->stack_a)) + return ; + while (state->stack_a.len > state->stack_b.len) + banana_first(state); + while (state->stack_a.len != 0) + push_b(state); + vec_i64_bool_reverse(&state->sorted); + make_sorted_all_false(state); + while (state->stack_b.len != 0) + banana_second(state); + rot = target(0, min_iter_zero_pos(&state->stack_a), state->stack_a.len); + if (rot.value > flip(rot).value) + rot = flip(rot); + while (rot.value > 0) + { + if (rot.direction == FORWARD) + rotate_a(state); + else + rev_rotate_a(state); + rot.value--; + } +} diff --git a/src/app/sort2.c b/src/app/sort2.c new file mode 100644 index 0000000..a82f46c --- /dev/null +++ b/src/app/sort2.c @@ -0,0 +1,33 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sort2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/08 15:50:10 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 16:20:35 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/state.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" + +void push_a(void *s); +void push_b(void *s); +void swap_a(void *s); +void swap_b(void *s); +void swap_both(void *s); +void rotate_a(void *s); +void rotate_b(void *s); +void rotate_both(void *s); +void rev_rotate_a(void *s); +void rev_rotate_b(void *s); +void rev_rotate_both(void *s); + +void sort_2(t_state *state) +{ + if (state->stack_a.buffer[0] > state->stack_a.buffer[1]) + swap_a(state); +} diff --git a/src/app/sort3.c b/src/app/sort3.c new file mode 100644 index 0000000..080bfe4 --- /dev/null +++ b/src/app/sort3.c @@ -0,0 +1,138 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sort3.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/08 15:50:10 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 17:53:02 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/state.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" + +void push_a(void *s); +void push_b(void *s); +void swap_a(void *s); +void swap_b(void *s); +void swap_both(void *s); +void rotate_a(void *s); +void rotate_b(void *s); +void rotate_both(void *s); +void rev_rotate_a(void *s); +void rev_rotate_b(void *s); +void rev_rotate_both(void *s); + +/* +fn sort_three(state: &mut State, selector: StackSelector, min_first: bool) { + macro_rules! stack { + () => { + match selector { + StackSelector::B => &mut state.b, + StackSelector::A => &mut state.a, + } + }; + } + let [swap, rotate, rev_rotate] = match selector { + StackSelector::A => [sa, ra, rra], + StackSelector::B => [sb, rb, rrb], + }; + match stack!().len() { + 2 => { + let func = match min_first { + true => PartialOrd::gt, + false => PartialOrd::lt, + }; + + if func(&stack!()[0].clone(), &stack!()[1]) { + swap(state); + } + return ; + } + 3 => {} + 0 | 1 | 4.. => return, + } + let mut c = stack!().clone(); + macro_rules! comb { + ($i1:literal, $i2:literal, $i3:literal) => { + &[c[$i1 - 1], c[$i2 - 1], c[$i3 - 1]] + }; + } + c.make_contiguous().sort_unstable(); + if min_first { + c.make_contiguous().reverse(); + } + stack!().make_contiguous(); + + if (stack!() == comb![1, 2, 3] / * abc * /) +{ + swap(state); + rev_rotate(state); +} +else if (stack!() == comb ![ 1, 3, 2 ] / * acb * /) +{ + rotate(state); +} +else if (stack !() == comb ![ 2, 3, 1 ] / * bca * /) +{ + swap(state); +} +else if (stack !() == comb ![ 2, 1, 3 ] / * bac * /) +{ + rotate(state); +} +else if (stack !() == comb ![ 3, 2, 1 ] / * cba * /) +{ +} +else if (stack !() == comb ![ 3, 1, 2 ] / * cab * /) +{ + rotate(state); + swap(state); + rev_rotate(state); +} +} +*/ +// 2 3 1 +bool sort_i64(t_i64 *lhs, t_i64 *rhs) +{ + return (*lhs <= *rhs); +} + +void sort_3_inner(t_state *state, t_i64 data[3], t_i64 sorted[3]) +{ + if ((data[0] == sorted[0]) && (data[1] == sorted[1]) + && (data[2] == sorted[2])) + (swap_a(state), rev_rotate_a(state)); + else if ((data[0] == sorted[0]) && (data[1] == sorted[2]) + && (data[2] == sorted[1])) + rotate_a(state); + else if ((data[0] == sorted[1]) && (data[1] == sorted[2]) + && (data[2] == sorted[0])) + swap_a(state); + else if ((data[0] == sorted[1]) && (data[1] == sorted[0]) + && (data[2] == sorted[2])) + rev_rotate_a(state); + else if ((data[0] == sorted[2]) && (data[1] == sorted[0]) + && (data[2] == sorted[1])) + (rotate_a(state), swap_a(state), rev_rotate_a(state)); +} + +void sort_3(t_state *state) +{ + t_i64 array[3]; + t_vec_i64 why_do_i_do_this; + + why_do_i_do_this.free_func = NULL; + why_do_i_do_this.len = 3; + why_do_i_do_this.capacity = 3; + why_do_i_do_this.buffer = array; + array[0] = state->stack_a.buffer[0]; + array[1] = state->stack_a.buffer[1]; + array[2] = state->stack_a.buffer[2]; + vec_i64_sort(&why_do_i_do_this, sort_i64); + vec_i64_reverse(&why_do_i_do_this); + sort_3_inner(state, state->stack_a.buffer, array); +} diff --git a/src/app/sort5.c b/src/app/sort5.c new file mode 100644 index 0000000..8c23853 --- /dev/null +++ b/src/app/sort5.c @@ -0,0 +1,139 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* sort5.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/08 15:50:10 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 18:50:53 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/find_place.h" +#include "app/state.h" +#include "me/printf/printf.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include "me/vec/vec_i64_bool.h" +#include "me/mem/mem_compare.h" +#include "me/mem/mem_copy.h" + +void push_a(void *s); +void push_b(void *s); +void swap_a(void *s); +void swap_b(void *s); +void swap_both(void *s); +void rotate_a(void *s); +void rotate_b(void *s); +void rotate_both(void *s); +void rev_rotate_a(void *s); +void rev_rotate_b(void *s); +void rev_rotate_both(void *s); +void sort_2(t_state *state); + +bool sort_i64(t_i64 *lhs, t_i64 *rhs); + +bool sort_i64_other_way(t_i64 *lhs, t_i64 *rhs) +{ + return (*lhs >= *rhs); +} + +void sort_5_inner(t_state *state, t_i64 data[3], t_i64 sorted[3]) +{ + if ((data[0] == sorted[0]) && (data[1] == sorted[1]) + && (data[2] == sorted[2])) + (swap_a(state), rev_rotate_a(state)); + else if ((data[0] == sorted[0]) && (data[1] == sorted[2]) + && (data[2] == sorted[1])) + rotate_a(state); + else if ((data[0] == sorted[1]) && (data[1] == sorted[2]) + && (data[2] == sorted[0])) + swap_a(state); + else if ((data[0] == sorted[1]) && (data[1] == sorted[0]) + && (data[2] == sorted[2])) + rev_rotate_a(state); + else if ((data[0] == sorted[2]) && (data[1] == sorted[0]) + && (data[2] == sorted[1])) + (rotate_a(state), swap_a(state), rev_rotate_a(state)); +} + +void sort_5_inner2(t_state *state) +{ + t_usize index; + + make_sorted_true_from_stack(state, &state->stack_a); + index = find_place(state->stack_b.buffer[0], state); + if (index == 0) + push_a(state); + else if (index == 1) + (push_a(state), swap_a(state)); + else if (index == 2) + (rotate_a(state), push_a(state), swap_a(state), rev_rotate_a(state)); + else if (index == 3) + (push_a(state), rotate_a(state)); + make_sorted_true_from_stack(state, &state->stack_a); + index = find_place(state->stack_b.buffer[0], state); + if (index == 0) + push_a(state); + else if (index == 1) + (push_a(state), swap_a(state)); + else if (index == 2) + (rotate_a(state), push_a(state), swap_a(state), rev_rotate_a(state)); + else if (index == 3) + (rev_rotate_a(state), push_a(state), rotate_a(state), rotate_a(state)); + else if (index == 4) + (push_a(state), rotate_a(state)); + make_sorted_true_from_stack(state, &state->stack_a); +} + +bool sort_5_specialized(t_state *state, t_i64 cur[5]) +{ + t_i64 target[5]; + t_vec_i64 why_do_i_do_this; + + why_do_i_do_this.free_func = NULL; + why_do_i_do_this.len = 5; + why_do_i_do_this.capacity = 5; + why_do_i_do_this.buffer = target; + mem_copy(target, state->stack_a.buffer, sizeof(t_i64) * 5); + vec_i64_sort(&why_do_i_do_this, sort_i64); + if (cur[0] == target[3 - 1] && cur[1] == target[4 - 1] && cur[2] == \ + target[1 - 1] && cur[3] == target[5 - 1] && cur[4] == target[2 - 1]) + return (me_printf("pb\npb\nra\nsa\npa\nsa\npa\nsa\nrra\n"), true); + if (cur[0] == target[3 - 1] && cur[1] == target[4 - 1] && cur[2] == \ + target[5 - 1] && cur[3] == target[2 - 1] && cur[4] == target[1 - 1]) + return (me_printf("pb\npb\nsb\nsa\npa\nsa\nrra\nrra\npa\nra\nra\n"), + true); + if (cur[0] == target[4 - 1] && cur[1] == target[3 - 1] && cur[2] == \ + target[1 - 1] && cur[3] == target[5 - 1] && cur[4] == target[2 - 1]) + return (me_printf("pb\npb\nra\nsa\npa\nsa\nrra\nrra\npa\nra\nra\n"), + true); + if (cur[0] == target[4 - 1] && cur[1] == target[3 - 1] && cur[2] == \ + target[5 - 1] && cur[3] == target[2 - 1] && cur[4] == target[1 - 1]) + return (me_printf("pb\npb\nsb\nsa\npa\nsa\npa\nsa\nrra\n"), true); + return (false); +} + +void sort_5(t_state *state) +{ + t_i64 array[3]; + t_vec_i64 why_do_i_do_this; + + if (sort_5_specialized(state, state->stack_a.buffer)) + return ; + push_b(state); + push_b(state); + if (state->stack_b.buffer[0] >= state->stack_a.buffer[1]) + swap_b(state); + why_do_i_do_this.free_func = NULL; + why_do_i_do_this.len = 3; + why_do_i_do_this.capacity = 3; + why_do_i_do_this.buffer = array; + array[0] = state->stack_a.buffer[0]; + array[1] = state->stack_a.buffer[1]; + array[2] = state->stack_a.buffer[2]; + vec_i64_sort(&why_do_i_do_this, sort_i64_other_way); + sort_5_inner(state, state->stack_a.buffer, array); + sort_5_inner2(state); +} diff --git a/src/app/state.c b/src/app/state.c new file mode 100644 index 0000000..7d5e2dc --- /dev/null +++ b/src/app/state.c @@ -0,0 +1,91 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* state.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/01 21:00:12 by maiboyer #+# #+# */ +/* Updated: 2024/02/15 17:42:13 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/state.h" +#include "app/types/type_i64_bool.h" +#include "me/convert/str_to_numbers.h" +#include "me/printf/printf.h" +#include "me/string/str_n_compare.h" +#include "me/types.h" +#include "me/vec/vec_i64.h" +#include "me/vec/vec_i64_bool.h" +#include +#include + +#if BONUS == 1 + +# define ERR_INVALID_NUM "Error\n" +# define ERR_DUPLICATE "Error\n" + +#else + +//# define ERR_INVALID_NUM "Error:\nInvalid Number\n" +//# define ERR_DUPLICATE "Error:\nDuplicate Number\n" +# define ERR_INVALID_NUM "Error\n" +# define ERR_DUPLICATE "Error\n" + +#endif + +bool sort_i64_bool(t_i64_bool *lhs, t_i64_bool *rhs) +{ + return (lhs->value <= rhs->value); +} + +void free_state(t_state state) +{ + vec_i64_free(state.stack_a); + vec_i64_free(state.stack_b); + vec_i64_bool_free(state.sorted); +} + +bool duplicate_check(t_state *state) +{ + t_i64 last; + t_usize index; + + if (state->sorted.len == 0) + return (false); + index = 1; + last = state->sorted.buffer[0].value; + while (index < state->sorted.len) + { + if (last == state->sorted.buffer[index].value) + return (true); + last = state->sorted.buffer[index++].value; + } + return (false); +} + +t_state parses_arguments(t_usize count, t_str nums[]) +{ + t_state state; + t_i32 atoi; + t_usize i; + + state.stack_a = vec_i64_new(count, NULL); + state.stack_b = vec_i64_new(count, NULL); + state.sorted = vec_i64_bool_new(count, NULL); + i = 0; + while (i < count) + { + if (str_to_i32(nums[i], 10, &atoi)) + (free_state(state), me_eprintf(ERR_INVALID_NUM), exit(1)); + vec_i64_push(&state.stack_a, atoi); + vec_i64_bool_push(&state.sorted, (t_i64_bool){.value = atoi, + .active = false}); + i++; + } + vec_i64_bool_sort(&state.sorted, sort_i64_bool); + if (duplicate_check(&state)) + (free_state(state), me_eprintf(ERR_DUPLICATE), exit(1)); + return (state); +} diff --git a/src/app/target.c b/src/app/target.c new file mode 100644 index 0000000..1444454 --- /dev/null +++ b/src/app/target.c @@ -0,0 +1,24 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* target.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/01/29 20:30:27 by maiboyer #+# #+# */ +/* Updated: 2024/02/02 22:40:55 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "app/rotate.h" +#include "app/target.h" + +t_rotation target(t_usize from, t_usize to, t_usize ring_size) +{ + if (ring_size == 0) + ring_size++; + if (from > to) + return (reverse(from - to, ring_size)); + else + return (forward(to - from, ring_size)); +} diff --git a/src/bonus/move1.c b/src/bonus/move1.c new file mode 100644 index 0000000..6ca0754 --- /dev/null +++ b/src/bonus/move1.c @@ -0,0 +1,11 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* move1.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/08 19:15:21 by maiboyer #+# #+# */ +/* Updated: 2024/02/08 19:15:21 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ 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