diff --git a/oryx-build-commands.txt b/oryx-build-commands.txt new file mode 100644 index 00000000..d647bdf7 --- /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 00000000..e69de29b diff --git a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp index 2ba1bec7..61309935 100644 --- a/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp +++ b/pydatastructs/miscellaneous_data_structures/_backend/cpp/stack/stack.cpp @@ -1,48 +1,238 @@ +#include +#include +#include +#include +#include +#include #include #include "ArrayStack.hpp" -static struct PyModuleDef stack_struct = { +static PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, - "_stack", - 0, - -1, - NULL, + "_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) { - Py_Initialize(); - PyObject *stack = PyModule_Create(&stack_struct); + return PyModule_Create(&moduledef); +} - if (PyType_Ready(&ArrayStackType) < 0) { - return NULL; - } - Py_INCREF(&ArrayStackType); - PyModule_AddObject(stack, "ArrayStack", reinterpret_cast(&ArrayStackType)); +namespace pydatastructs { - if (PyType_Ready(&ArrayType) < 0) { - return NULL; - } - Py_INCREF(&ArrayType); - PyModule_AddObject(stack, "Array", reinterpret_cast(&ArrayType)); + // DynamicOneDimensionalArray implementation + class DynamicOneDimensionalArray { + private: + std::vector arr; + + public: + void append(int x) { + arr.push_back(x); + } - if (PyType_Ready(&OneDimensionalArrayType) < 0) { - return NULL; - } - Py_INCREF(&OneDimensionalArrayType); - PyModule_AddObject(stack, "OneDimensionalArray", reinterpret_cast(&OneDimensionalArrayType)); + int get_last_filled() const { + if (arr.empty()) { + throw std::out_of_range("Array is empty"); + } + return arr.back(); + } - if (PyType_Ready(&DynamicArrayType) < 0) { - return NULL; - } - Py_INCREF(&DynamicArrayType); - PyModule_AddObject(stack, "DynamicArray", reinterpret_cast(&DynamicArrayType)); + void delete_last() { + if (arr.empty()) { + throw std::out_of_range("Array is empty"); + } + arr.pop_back(); + } + + size_t size() const { + return arr.size(); + } + + std::string to_string() const { + std::ostringstream oss; + for (int val : arr) { + oss << val << " "; + } + return oss.str(); + } + + 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 next; + + Node(int x) : value(x), next(nullptr) {} + }; + + // SinglyLinkedList implementation + class SinglyLinkedList { + private: + std::shared_ptr head; + size_t list_size; + + public: + SinglyLinkedList() : head(nullptr), list_size(0) {} + + void append_left(int x) { + auto new_node = std::make_shared(x); + new_node->next = head; + head = new_node; + list_size++; + } + + 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; + } + + int head_value() const { + if (head == nullptr) { + throw std::out_of_range("List is empty"); + } + return head->value; + } + + size_t size() const { + return list_size; + } + + std::string to_string() const { + std::ostringstream oss; + auto current = head; + while (current) { + oss << current->value << " "; + current = current->next; + } + return oss.str(); + } + }; +} - if (PyType_Ready(&DynamicOneDimensionalArrayType) < 0) { - return NULL; - } - Py_INCREF(&DynamicOneDimensionalArrayType); - PyModule_AddObject(stack, "DynamicOneDimensionalArray", reinterpret_cast(&DynamicOneDimensionalArrayType)); +namespace pydatastructs { + // Forward declaration of the SinglyLinkedList and DynamicOneDimensionalArray + class DynamicOneDimensionalArray; + class SinglyLinkedList; - return stack; + 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 items; + + public: + ArrayStack(std::shared_ptr items) : items(items) {} + + void push(int x) override { + items->append(x); + } + + 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; + } + + bool is_empty() const override { + return items->size() == 0; + } + + int peek() const override { + if (is_empty()) { + throw std::out_of_range("Stack is empty"); + } + return items->get_last_filled(); + } + + 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 stack; + + public: + LinkedListStack(std::shared_ptr 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 create_stack(const std::string& implementation, std::shared_ptr items = nullptr, Backend backend = Backend::CPP) { + if (implementation == "array") { + if (backend == Backend::CPP) { + // Use C++ backend for array stack + return std::make_shared(items); + } else { + // Use Python backend or default + return std::make_shared(items); + } + } else if (implementation == "linked_list") { + if (backend != Backend::PYTHON) { + throw std::invalid_argument("Linked list stack requires Python backend."); + } + return std::make_shared(std::make_shared()); + } else { + throw std::invalid_argument("Implementation not supported"); + } + } } diff --git a/pydatastructs/miscellaneous_data_structures/stack.py b/pydatastructs/miscellaneous_data_structures/stack.py index 38f72b43..71efd21a 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)