From fc5ca10c3c6492d2e1089921e2aa844e8242e099 Mon Sep 17 00:00:00 2001 From: Kushagra9399 <146541055+Kushagra9399@users.noreply.github.com> Date: Mon, 3 Mar 2025 22:42:31 +0530 Subject: [PATCH 1/4] Update stack.cpp Here is the updated code for stack.py in c++ implementation. I have checked the array.py and array.cpp and then imported the required modules/ libraries. --- .../_backend/cpp/stack/stack.cpp | 155 ++++++++++++++---- 1 file changed, 127 insertions(+), 28 deletions(-) diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp index 2ba1bec7a..20cada5b6 100644 --- a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp +++ b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp @@ -1,48 +1,147 @@ #include <Python.h> -#include "ArrayStack.hpp" +#include <vector> +#include <stdexcept> +#include "SinglyLinkedList.hpp" +#include "DynamicOneDimensionalArray.hpp" -static struct PyModuleDef stack_struct = { +// Forward declarations for types in the module +extern PyTypeObject ArrayStackType; +extern PyTypeObject LinkedListStackType; + +static struct PyModuleDef stackmodule = { PyModuleDef_HEAD_INIT, "_stack", - 0, + "Stack Data Structure Module", -1, - NULL, + NULL }; -PyMODINIT_FUNC PyInit__stack(void) { - Py_Initialize(); - PyObject *stack = PyModule_Create(&stack_struct); +// Stack base class (Abstract class) +class Stack { +public: + virtual void push(PyObject* x) = 0; + virtual PyObject* pop() = 0; + virtual bool is_empty() = 0; + virtual PyObject* peek() = 0; + virtual Py_ssize_t __len__() = 0; + virtual const char* __str__() = 0; +}; - if (PyType_Ready(&ArrayStackType) < 0) { - return NULL; +// ArrayStack Implementation (Derived class) +class ArrayStack : public Stack { +public: + std::vector<PyObject*> items; // Dynamic array to store items + + ArrayStack() {} + + ArrayStack(std::vector<PyObject*> initial_items) { + items = initial_items; } - Py_INCREF(&ArrayStackType); - PyModule_AddObject(stack, "ArrayStack", reinterpret_cast<PyObject*>(&ArrayStackType)); - if (PyType_Ready(&ArrayType) < 0) { - return NULL; + void push(PyObject* x) override { + items.push_back(x); } - Py_INCREF(&ArrayType); - PyModule_AddObject(stack, "Array", reinterpret_cast<PyObject*>(&ArrayType)); - if (PyType_Ready(&OneDimensionalArrayType) < 0) { - return NULL; + PyObject* pop() override { + if (is_empty()) { + throw std::out_of_range("Stack is empty"); + } + PyObject* top_element = items.back(); + items.pop_back(); + return top_element; } - Py_INCREF(&OneDimensionalArrayType); - PyModule_AddObject(stack, "OneDimensionalArray", reinterpret_cast<PyObject*>(&OneDimensionalArrayType)); - if (PyType_Ready(&DynamicArrayType) < 0) { - return NULL; + bool is_empty() override { + return items.empty(); } - Py_INCREF(&DynamicArrayType); - PyModule_AddObject(stack, "DynamicArray", reinterpret_cast<PyObject*>(&DynamicArrayType)); - if (PyType_Ready(&DynamicOneDimensionalArrayType) < 0) { - return NULL; + PyObject* peek() override { + if (is_empty()) { + throw std::out_of_range("Stack is empty"); + } + return items.back(); + } + + Py_ssize_t __len__() override { + return items.size(); + } + + const char* __str__() override { + std::string result = "["; + for (size_t i = 0; i < items.size(); ++i) { + result += PyUnicode_AsUTF8(PyObject_Str(items[i])); + if (i != items.size() - 1) { + result += ", "; + } + } + result += "]"; + return result.c_str(); + } +}; + +// LinkedListStack Implementation (Derived class) +class LinkedListStack : public Stack { +public: + SinglyLinkedList stack; // Linked list to store the stack elements + + LinkedListStack() {} + + LinkedListStack(std::vector<PyObject*> initial_items) { + for (auto& item : initial_items) { + push(item); + } + } + + void push(PyObject* x) override { + stack.appendleft(x); + } + + PyObject* pop() override { + if (is_empty()) { + throw std::out_of_range("Stack is empty"); + } + return stack.popleft(); } - Py_INCREF(&DynamicOneDimensionalArrayType); - PyModule_AddObject(stack, "DynamicOneDimensionalArray", reinterpret_cast<PyObject*>(&DynamicOneDimensionalArrayType)); + bool is_empty() override { + return stack.size() == 0; + } + + PyObject* peek() override { + return stack.head; + } + + Py_ssize_t __len__() override { + return stack.size(); + } + + const char* __str__() override { + std::string result = "["; + auto node = stack.head; + while (node != nullptr) { + result += PyUnicode_AsUTF8(PyObject_Str(node->data)); + if (node->next != nullptr) { + result += ", "; + } + node = node->next; + } + result += "]"; + return result.c_str(); + } +}; + +// Python Module Initialization +PyMODINIT_FUNC PyInit__stack(void) { + PyObject *stack_module = PyModule_Create(&stackmodule); + if (PyType_Ready(&ArrayStackType) < 0) + return NULL; + Py_INCREF(&ArrayStackType); + PyModule_AddObject(stack_module, "ArrayStack", (PyObject*)&ArrayStackType); + + if (PyType_Ready(&LinkedListStackType) < 0) + return NULL; + Py_INCREF(&LinkedListStackType); + PyModule_AddObject(stack_module, "LinkedListStack", (PyObject*)&LinkedListStackType); - return stack; + return stack_module; } From 5c8214c82bbe6b2d986f0a37b9e0137455f6b924 Mon Sep 17 00:00:00 2001 From: Kushagra9399 <146541055+Kushagra9399@users.noreply.github.com> Date: Sat, 8 Mar 2025 23:46:28 +0530 Subject: [PATCH 2/4] Update stack.cpp I have updated this file by add implementation using linkedlist and array. --- .../_backend/cpp/stack/stack.cpp | 317 +++++++++++------- 1 file changed, 197 insertions(+), 120 deletions(-) diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp index 20cada5b6..1eeddbdcd 100644 --- a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp +++ b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp @@ -1,147 +1,224 @@ -#include <Python.h> +#include <iostream> #include <vector> #include <stdexcept> -#include "SinglyLinkedList.hpp" -#include "DynamicOneDimensionalArray.hpp" - -// Forward declarations for types in the module -extern PyTypeObject ArrayStackType; -extern PyTypeObject LinkedListStackType; - -static struct PyModuleDef stackmodule = { - PyModuleDef_HEAD_INIT, - "_stack", - "Stack Data Structure Module", - -1, - NULL -}; - -// Stack base class (Abstract class) -class Stack { -public: - virtual void push(PyObject* x) = 0; - virtual PyObject* pop() = 0; - virtual bool is_empty() = 0; - virtual PyObject* peek() = 0; - virtual Py_ssize_t __len__() = 0; - virtual const char* __str__() = 0; -}; - -// ArrayStack Implementation (Derived class) -class ArrayStack : public Stack { -public: - std::vector<PyObject*> items; // Dynamic array to store items - - ArrayStack() {} - - ArrayStack(std::vector<PyObject*> initial_items) { - items = initial_items; - } +#include <memory> +#include <sstream> +#include <typeinfo> + +namespace pydatastructs { + + // DynamicOneDimensionalArray implementation + class DynamicOneDimensionalArray { + private: + std::vector<int> arr; + + public: + void append(int x) { + arr.push_back(x); + } - void push(PyObject* x) override { - items.push_back(x); - } + int get_last_filled() const { + if (arr.empty()) { + throw std::out_of_range("Array is empty"); + } + return arr.back(); + } - PyObject* pop() override { - if (is_empty()) { - throw std::out_of_range("Stack is empty"); + void delete_last() { + if (arr.empty()) { + throw std::out_of_range("Array is empty"); + } + arr.pop_back(); } - PyObject* top_element = items.back(); - items.pop_back(); - return top_element; - } - bool is_empty() override { - return items.empty(); - } + size_t size() const { + return arr.size(); + } - PyObject* peek() override { - if (is_empty()) { - throw std::out_of_range("Stack is empty"); + std::string to_string() const { + std::ostringstream oss; + for (int val : arr) { + oss << val << " "; + } + return oss.str(); } - return items.back(); - } - Py_ssize_t __len__() override { - return items.size(); - } + void set_dtype(const std::type_info& type) { + // In the context of C++, we typically don't need to worry about dynamic types like in Python. + } + }; + + // SinglyLinkedList Node definition + struct Node { + int value; + std::shared_ptr<Node> next; + + Node(int x) : value(x), next(nullptr) {} + }; + + // SinglyLinkedList implementation + class SinglyLinkedList { + private: + std::shared_ptr<Node> head; + size_t list_size; + + public: + SinglyLinkedList() : head(nullptr), list_size(0) {} + + void append_left(int x) { + auto new_node = std::make_shared<Node>(x); + new_node->next = head; + head = new_node; + list_size++; + } - const char* __str__() override { - std::string result = "["; - for (size_t i = 0; i < items.size(); ++i) { - result += PyUnicode_AsUTF8(PyObject_Str(items[i])); - if (i != items.size() - 1) { - result += ", "; + int pop_left() { + if (head == nullptr) { + throw std::out_of_range("List is empty"); } + int value = head->value; + head = head->next; + list_size--; + return value; } - result += "]"; - return result.c_str(); - } -}; -// LinkedListStack Implementation (Derived class) -class LinkedListStack : public Stack { -public: - SinglyLinkedList stack; // Linked list to store the stack elements + int head_value() const { + if (head == nullptr) { + throw std::out_of_range("List is empty"); + } + return head->value; + } - LinkedListStack() {} + size_t size() const { + return list_size; + } - LinkedListStack(std::vector<PyObject*> initial_items) { - for (auto& item : initial_items) { - push(item); + std::string to_string() const { + std::ostringstream oss; + auto current = head; + while (current) { + oss << current->value << " "; + current = current->next; + } + return oss.str(); } - } + }; +} - void push(PyObject* x) override { - stack.appendleft(x); - } - PyObject* pop() override { - if (is_empty()) { - throw std::out_of_range("Stack is empty"); +namespace pydatastructs { + // Forward declaration of the SinglyLinkedList and DynamicOneDimensionalArray + class DynamicOneDimensionalArray; + class SinglyLinkedList; + + enum class Backend { PYTHON, CPP }; + + // Abstract Stack class + class Stack { + public: + virtual ~Stack() {} + virtual void push(int x) = 0; + virtual int pop() = 0; + virtual bool is_empty() const = 0; + virtual int peek() const = 0; + virtual size_t size() const = 0; + virtual std::string to_string() const = 0; + }; + + // ArrayStack class for stack implementation using dynamic array + class ArrayStack : public Stack { + private: + std::shared_ptr<DynamicOneDimensionalArray> items; + + public: + ArrayStack(std::shared_ptr<DynamicOneDimensionalArray> items) : items(items) {} + + void push(int x) override { + items->append(x); } - return stack.popleft(); - } - bool is_empty() override { - return stack.size() == 0; - } + int pop() override { + if (is_empty()) { + throw std::out_of_range("Stack is empty"); + } + int top_element = items->get_last_filled(); + items->delete_last(); + return top_element; + } - PyObject* peek() override { - return stack.head; - } + bool is_empty() const override { + return items->size() == 0; + } - Py_ssize_t __len__() override { - return stack.size(); - } + int peek() const override { + if (is_empty()) { + throw std::out_of_range("Stack is empty"); + } + return items->get_last_filled(); + } - const char* __str__() override { - std::string result = "["; - auto node = stack.head; - while (node != nullptr) { - result += PyUnicode_AsUTF8(PyObject_Str(node->data)); - if (node->next != nullptr) { - result += ", "; + size_t size() const override { + return items->size(); + } + + std::string to_string() const override { + return items->to_string(); + } + }; + + // LinkedListStack class for stack implementation using singly linked list + class LinkedListStack : public Stack { + private: + std::shared_ptr<SinglyLinkedList> stack; + + public: + LinkedListStack(std::shared_ptr<SinglyLinkedList> stack) : stack(stack) {} + + void push(int x) override { + stack->append_left(x); + } + + int pop() override { + if (is_empty()) { + throw std::out_of_range("Stack is empty"); + } + return stack->pop_left(); + } + + bool is_empty() const override { + return stack->size() == 0; + } + + int peek() const override { + return stack->head_value(); + } + + size_t size() const override { + return stack->size(); + } + + std::string to_string() const override { + return stack->to_string(); + } + }; + + // Stack factory function + std::shared_ptr<Stack> create_stack(const std::string& implementation, std::shared_ptr<DynamicOneDimensionalArray> items = nullptr, Backend backend = Backend::CPP) { + if (implementation == "array") { + if (backend == Backend::CPP) { + // Use C++ backend for array stack + return std::make_shared<ArrayStack>(items); + } else { + // Use Python backend or default + return std::make_shared<ArrayStack>(items); + } + } else if (implementation == "linked_list") { + if (backend != Backend::PYTHON) { + throw std::invalid_argument("Linked list stack requires Python backend."); } - node = node->next; + return std::make_shared<LinkedListStack>(std::make_shared<SinglyLinkedList>()); + } else { + throw std::invalid_argument("Implementation not supported"); } - result += "]"; - return result.c_str(); } -}; - -// Python Module Initialization -PyMODINIT_FUNC PyInit__stack(void) { - PyObject *stack_module = PyModule_Create(&stackmodule); - if (PyType_Ready(&ArrayStackType) < 0) - return NULL; - Py_INCREF(&ArrayStackType); - PyModule_AddObject(stack_module, "ArrayStack", (PyObject*)&ArrayStackType); - - if (PyType_Ready(&LinkedListStackType) < 0) - return NULL; - Py_INCREF(&LinkedListStackType); - PyModule_AddObject(stack_module, "LinkedListStack", (PyObject*)&LinkedListStackType); - - return stack_module; } From 206991710df58c12bb9d2c0bd88af2fc9f283e0b Mon Sep 17 00:00:00 2001 From: Kushagra9399 <146541055+Kushagra9399@users.noreply.github.com> Date: Sat, 8 Mar 2025 23:51:00 +0530 Subject: [PATCH 3/4] Update stack.cpp Try solving errors in test cases --- .../_backend/cpp/stack/stack.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp index 1eeddbdcd..8a9d0dea9 100644 --- a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp +++ b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp @@ -4,6 +4,19 @@ #include <memory> #include <sstream> #include <typeinfo> +#include <Python.h> + +static PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_stack", /* name of module */ + nullptr, /* module documentation */ + -1, /* size of per-interpreter state of the module */ + nullptr /* methods of the module */ +}; + +PyMODINIT_FUNC PyInit__stack(void) { + return PyModule_Create(&moduledef); +} namespace pydatastructs { From 6dedf484ef632c3aa379706527d67c63393b291f Mon Sep 17 00:00:00 2001 From: Kushagra9399 <146541055+Kushagra9399@users.noreply.github.com> Date: Sat, 29 Mar 2025 15:03:11 +0000 Subject: [PATCH 4/4] Updating ArrayStack.cpp --- oryx-build-commands.txt | 2 ++ .../_backend/cpp/stack/__init__.py | 0 .../miscellaneous_data_structures/_backend/cpp/stack/stack.cpp | 1 + pydatastructs/miscellaneous_data_structures/stack.py | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 oryx-build-commands.txt create mode 100644 pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/__init__.py diff --git a/oryx-build-commands.txt b/oryx-build-commands.txt new file mode 100644 index 000000000..d647bdf7f --- /dev/null +++ b/oryx-build-commands.txt @@ -0,0 +1,2 @@ +PlatformWithVersion=Python +BuildCommands=conda env create --file environment.yml --prefix ./venv --quiet diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/__init__.py b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp index 8a9d0dea9..613099351 100644 --- a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp +++ b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp @@ -5,6 +5,7 @@ #include <sstream> #include <typeinfo> #include <Python.h> +#include "ArrayStack.hpp" static PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, diff --git a/pydatastructs/miscellaneous_data_structures/stack.py b/pydatastructs/miscellaneous_data_structures/stack.py index 38f72b43f..71efd21af 100644 --- a/pydatastructs/miscellaneous_data_structures/stack.py +++ b/pydatastructs/miscellaneous_data_structures/stack.py @@ -1,5 +1,5 @@ from pydatastructs.linear_data_structures import DynamicOneDimensionalArray, SinglyLinkedList -from pydatastructs.miscellaneous_data_structures._backend.cpp import _stack +from pydatastructs.miscellaneous_data_structures._backend.cpp.stack import _stack from pydatastructs.utils.misc_util import ( _check_type, NoneType, Backend, raise_if_backend_is_not_python)