feat(09): finishing the exercice 01
This commit is contained in:
parent
bf81e18e76
commit
429896d153
3 changed files with 163 additions and 19 deletions
|
|
@ -6,7 +6,7 @@
|
||||||
# By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ #
|
# By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ #
|
||||||
# +#+#+#+#+#+ +#+ #
|
# +#+#+#+#+#+ +#+ #
|
||||||
# Created: 2023/11/12 11:05:05 by rparodi #+# #+# #
|
# Created: 2023/11/12 11:05:05 by rparodi #+# #+# #
|
||||||
# Updated: 2025/04/27 13:01:07 by rparodi ### ########.fr #
|
# Updated: 2025/04/27 18:52:30 by rparodi ### ########.fr #
|
||||||
# #
|
# #
|
||||||
# **************************************************************************** #
|
# **************************************************************************** #
|
||||||
|
|
||||||
|
|
@ -83,6 +83,38 @@ $(OBJDIRNAME)/%.o: %.cpp
|
||||||
@printf '$(GREY) Compiling $(END)$(GREEN)$<$(END)\n'
|
@printf '$(GREY) Compiling $(END)$(GREEN)$<$(END)\n'
|
||||||
@$(CXX) $(CXXFLAGS) -o $@ -c $<
|
@$(CXX) $(CXXFLAGS) -o $@ -c $<
|
||||||
|
|
||||||
|
test:
|
||||||
|
@printf '$(GREY) Testing with $(END)$(GOLD)./RPN ""$(END)\n'
|
||||||
|
@./$(NAME) ""
|
||||||
|
@printf '\n'
|
||||||
|
@printf '$(GREY) MemCheck with $(END)$(GOLD)./RPN ""$(END)\n'
|
||||||
|
@valgrind ./$(NAME) "" 2> /tmp/RPN_test
|
||||||
|
@cat /tmp/RPN_test | rg --color=always "ERROR SUMMARY" -A 10
|
||||||
|
@printf '$(GREY) Testing with $(END)$(GOLD)./RPN "8 9 * 9 - 9 - 9 - 4 - 1 +"$(END)\n'
|
||||||
|
@./$(NAME) "8 9 * 9 - 9 - 9 - 4 - 1 +"
|
||||||
|
@printf '\n'
|
||||||
|
@printf '$(GREY) MemCheck with $(END)$(GOLD)./RPN "8 9 * 9 - 9 - 9 - 4 - 1 +"$(END)\n'
|
||||||
|
@valgrind ./$(NAME) "8 9 * 9 - 9 - 9 - 4 - 1 +" 2> /tmp/RPN_test
|
||||||
|
@cat /tmp/RPN_test | rg --color=always "ERROR SUMMARY" -A 10
|
||||||
|
@printf '$(GREY) Testing with $(END)$(GOLD)./RPN "7 7 * 7 -"$(END)\n'
|
||||||
|
@./$(NAME) "7 7 * 7 -"
|
||||||
|
@printf '\n'
|
||||||
|
@printf '$(GREY) MemCheck with $(END)$(GOLD)./RPN "7 7 * 7 -"$(END)\n'
|
||||||
|
@valgrind ./$(NAME) "7 7 * 7 -" 2> /tmp/RPN_test
|
||||||
|
@cat /tmp/RPN_test | rg --color=always "ERROR SUMMARY" -A 10
|
||||||
|
@printf '$(GREY) Testing with $(END)$(GOLD)./RPN "1 2 * 2 / 2 * 2 4 - +"$(END)\n'
|
||||||
|
@./$(NAME) "1 2 * 2 / 2 * 2 4 - +"
|
||||||
|
@printf '\n'
|
||||||
|
@printf '$(GREY) MemCheck with $(END)$(GOLD)./RPN "1 2 * 2 / 2 * 2 4 - +"$(END)\n'
|
||||||
|
@valgrind ./$(NAME) "1 2 * 2 / 2 * 2 4 - +" 2> /tmp/RPN_test
|
||||||
|
@cat /tmp/RPN_test | rg --color=always "ERROR SUMMARY" -A 10
|
||||||
|
@printf '$(GREY) Testing with $(END)$(GOLD)./RPN "(1 + 1)"$(END)\n'
|
||||||
|
@./$(NAME) "(1 + 1)"
|
||||||
|
@printf '\n'
|
||||||
|
@printf '$(GREY) MemCheck with $(END)$(GOLD)./RPN "(1 + 1)"$(END)\n'
|
||||||
|
@valgrind ./$(NAME) "(1 + 1)" 2> /tmp/RPN_test
|
||||||
|
@cat /tmp/RPN_test | rg --color=always "ERROR SUMMARY" -A 10
|
||||||
|
|
||||||
# Header
|
# Header
|
||||||
header:
|
header:
|
||||||
@clear
|
@clear
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2025/04/27 13:03:08 by rparodi #+# #+# */
|
/* Created: 2025/04/27 13:03:08 by rparodi #+# #+# */
|
||||||
/* Updated: 2025/04/27 15:39:50 by rparodi ### ########.fr */
|
/* Updated: 2025/04/27 17:13:10 by rparodi ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -24,3 +24,18 @@
|
||||||
#define CLR_WHITE "\033[0;37m"
|
#define CLR_WHITE "\033[0;37m"
|
||||||
#define CLR_GOLD "\033[38;5;220m"
|
#define CLR_GOLD "\033[38;5;220m"
|
||||||
#define CLR_GREY "\033[38;5;240m"
|
#define CLR_GREY "\033[38;5;240m"
|
||||||
|
|
||||||
|
enum e_op
|
||||||
|
{
|
||||||
|
NUM = 0,
|
||||||
|
ADD,
|
||||||
|
SUB,
|
||||||
|
MUL,
|
||||||
|
DIV
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct s_tok
|
||||||
|
{
|
||||||
|
e_op type;
|
||||||
|
int value;
|
||||||
|
} tok;
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,16 @@
|
||||||
/* ************************************************************************** */
|
|
||||||
/* */
|
|
||||||
/* ::: :::::::: */
|
|
||||||
/* main.cpp :+: :+: :+: */
|
|
||||||
/* +:+ +:+ +:+ */
|
|
||||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
|
||||||
/* +#+#+#+#+#+ +#+ */
|
|
||||||
/* Created: 2025/04/27 12:58:08 by rparodi #+# #+# */
|
|
||||||
/* Updated: 2025/04/27 15:50:20 by rparodi ### ########.fr */
|
|
||||||
/* */
|
|
||||||
/* ************************************************************************** */
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <stack>
|
|
||||||
#include "RPN.hpp"
|
#include "RPN.hpp"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <sstream>
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief check if the input have only numbers and operators
|
* @brief Check if the input string is valid
|
||||||
*
|
*
|
||||||
* @param str the input of the user
|
* @param str input of the user
|
||||||
* @return true if the input is valid, false otherwise
|
* @return true if the input is valid
|
||||||
*/
|
*/
|
||||||
bool check_input(std::string str) {
|
bool check_input(std::string str) {
|
||||||
std::string allowed = "0123456789 +-*/";
|
std::string allowed = "0123456789 +-*/";
|
||||||
|
|
@ -29,12 +21,117 @@ bool check_input(std::string str) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief split the input string into a list of tokens
|
||||||
|
*
|
||||||
|
* @param input input of the user (already checked)
|
||||||
|
* @return std::list<tok> list of tokens
|
||||||
|
*/
|
||||||
|
std::list<tok> split_to_list(const std::string& input) {
|
||||||
|
std::istringstream iss(input);
|
||||||
|
std::string token;
|
||||||
|
std::list<tok> tokens;
|
||||||
|
e_op op;
|
||||||
|
int tmp;
|
||||||
|
|
||||||
|
while (iss >> token) {
|
||||||
|
op = NUM;
|
||||||
|
tmp = 0;
|
||||||
|
if (token == "*") {
|
||||||
|
op = MUL;
|
||||||
|
}
|
||||||
|
else if (token == "/") {
|
||||||
|
op = DIV;
|
||||||
|
}
|
||||||
|
else if (token == "+") {
|
||||||
|
op = ADD;
|
||||||
|
}
|
||||||
|
else if (token == "-") {
|
||||||
|
op = SUB;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
op = NUM;
|
||||||
|
tmp = std::strtol(token.c_str(), 0, 10);
|
||||||
|
}
|
||||||
|
tok to_push = {op, tmp};
|
||||||
|
tokens.push_back(to_push);
|
||||||
|
}
|
||||||
|
return tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Execute the RPN algorithm
|
||||||
|
*
|
||||||
|
* @param tokens list of tokens
|
||||||
|
* @return true if the execution was successful
|
||||||
|
*/
|
||||||
|
bool exec_rpn(std::list<tok> tokens) {
|
||||||
|
if (tokens.size() < 3) {
|
||||||
|
std::cerr << CLR_RED << "Error:\tNot enough operands" << CLR_RESET << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<int> numbers;
|
||||||
|
|
||||||
|
while (!tokens.empty()) {
|
||||||
|
tok current = tokens.front();
|
||||||
|
tokens.pop_front();
|
||||||
|
|
||||||
|
if (current.type == NUM) {
|
||||||
|
numbers.push_back(current.value);
|
||||||
|
}
|
||||||
|
else if (current.type == ADD || current.type == SUB || current.type == MUL || current.type == DIV) {
|
||||||
|
if (numbers.size() < 2) {
|
||||||
|
std::cerr << CLR_RED << "Error:\tNot enough operands for operator" << CLR_RESET << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int b = numbers.back();
|
||||||
|
numbers.pop_back();
|
||||||
|
int a = numbers.back();
|
||||||
|
numbers.pop_back();
|
||||||
|
|
||||||
|
if (current.type == ADD)
|
||||||
|
numbers.push_back(a + b);
|
||||||
|
else if (current.type == SUB)
|
||||||
|
numbers.push_back(a - b);
|
||||||
|
else if (current.type == MUL)
|
||||||
|
numbers.push_back(a * b);
|
||||||
|
else if (current.type == DIV) {
|
||||||
|
if (b == 0) {
|
||||||
|
std::cerr << CLR_RED << "Error:\tDivision by zero" << CLR_RESET << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
numbers.push_back(a / b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
std::cerr << CLR_RED << "Error:\tInvalid token" << CLR_RESET << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numbers.size() != 1) {
|
||||||
|
std::cerr << CLR_RED << "Error:\tInvalid final stack state" << CLR_RESET << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << CLR_GREEN << "Result:\t" << numbers.back() << CLR_RESET << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
if (argc != 2) {
|
if (argc != 2) {
|
||||||
std::cerr << CLR_RED << "Usage:\t" << argv[0] << " <string>" << CLR_RESET << std::endl;
|
std::cerr << CLR_RED << "Usage:\t" << argv[0] << " <string>" << CLR_RESET << std::endl;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
std::string input = argv[1];
|
std::string input = argv[1];
|
||||||
if (!check_input(input)) {
|
if (!check_input(input)) {
|
||||||
std::cerr << CLR_RED << "Error:\tYour input can only have digits, spaces and the operators '+' '-' '*' '/'" << CLR_RESET << std::endl;
|
std::cerr << CLR_RED << "Error:\tYour input can only have digits, spaces and the operators '+' '-' '*' '/'" << CLR_RESET << std::endl;
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
std::list<tok> tokens = split_to_list(input);
|
||||||
|
exec_rpn(tokens);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue