Skip to content

busang430/push_swap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This project has been created as part of the 42 curriculum by eel-kerc, zqian.


Table of Contents


Description

Push Swap is a sorting project where the goal is to sort data on a stack using a limited set of instructions and the fewest possible operations. It introduces the concepts of sorting algorithms and their complexity.

Top ↑ | Next ↓

Team Collaboration

This project was developed in partnership, with responsibilities divided as follows:

Area Contributor Responsibilities
Core & Storage zqian Input Parsing, Stack A/B Initialization, Data Structures.
Advanced Sorting zqian Chunk-Based Sorting ($O(n\sqrt{n})$), Radix Sort (Bitwise).
Mechanics & Analytics eel-kerc 11 Operations, Disorder Metric, Benchmark logic.
Recursive Algorithms eel-kerc Min Extraction, Recursive Merge Sort, Adaptive Strategy.
Verification eel-kerc Bonus Checker development.
Build System Joint Makefile architecture and project structure.
Top ↑ Next ↓

Operations

The goal is to sort numbers into stack a in ascending order. Below is a summary of the 11 available operations:

Type Command Description
Swap sa / sb Swap the first two elements at the top of stack a or b.
ss Execute sa and sb at the same time.
Push pa / pb Move the top element from one stack to the top of the other.
Rotate ra / rb Shift all elements up by one. The first becomes the last.
rr Execute ra and rb at the same time.
Reverse Rotate rra / rrb Shift all elements down by one. The last becomes the first.
rrr Execute rra and rrb at the same time.

Top ↑ | Next ↓

Concepts

Concept Description
Big O Notation Mathematical notation that describes the limiting behavior of a function when the argument tends towards a particular value or infinity.
O(n²) Quadratic complexity; performance drops significantly as input size increases (e.g., Bubble/Selection Sort).
O(n log n) Log-linear complexity; efficient for sorting large datasets (e.g., Merge Sort).
O(n√n) Complexity often achieved in chunk-based strategies by dividing data into square-root-sized blocks.
Bitwise Ops Directly manipulating bits; crucial for non-comparison algorithms like Radix Sort.
Disorder Metric A normalized value (0 to 1) based on adjacent pair comparisons (0 = sorted, 1 = reversed).

Top ↑ | Next ↓

Project Structure

Component Responsibility
Technical Implementation Efficient operations using Doubly Linked Lists.
Input Parsing Argument validation and robust error handling.
Initialization Efficient data loading and index calculation for Stack A.
Algorithm Selection Adaptive strategy choosing from Simple, Chunk, or Merge.
Bonus - Checker Verification system for sorting results via stdin.
Benchmarking Real-time performance analytics and disorder calculation.

Top ↑ | Next ↓

Algorithm Justification & Technical Choices

The sorting strategy is adaptively selected based on the number of elements and the complexity requirements.

Case Strategy Code Logic Why This Choice?
Simple (3-5) Min Extraction Scans min, optimal rotation (ra/rra), reduces to 3 for sort_three. Reaches theoretical minimum ops under strict 11-step limit.
Medium (Mid) Chunk-Based Divides into fixed thresholds (e.g., 5 or 11 chunks). Median-distance optimization. High efficiency for 100-500 elements; easy to tune.
Complex (Large) Recursive Merge Recursive split/merge mirroring Merge Sort via stack operations. High educational value in hierarchical data partitioning.
Special (Radix) Bitwise Sort Bit-by-bit (LSD to MSD) processing via bitwise checks and pushes. Study of low-level data manipulation and non-comparison sorting.

Top ↑ | Next ↓


Adaptive Strategy & Disorder Thresholds

Our final implementation features a Custom Adaptive Algorithm that dynamically selects the best sorting method based on the input's Disorder Metric.

  • Code Logic: The code calculates a disorder score (0 to 1) upon initialization. An adaptive router then evaluates this score against predefined thresholds and calls the most suitable function (min_extraction, chunk_sort, or merge_sort) to handle the specific stack configuration.
Disorder Regime Threshold Strategy Complexity Target
Low Disorder d < 0.2 Optimized O(n²) pass / Small Chunking O(n²)
Medium Disorder 0.2 ≤ d < 0.5 Standard Chunk-Based Sorting O(n√n)
High Disorder d ≥ 0.5 Recursive Merge Sort or Large Chunking O(n log n)

Rationale for Thresholds

  • Low Disorder (< 0.2): When the stack is nearly sorted, complex partitioning is counterproductive. We use a linear or near-linear approach to minimize operation overhead.
  • Medium Disorder (0.2 - 0.5): Standard data distribution. The chunking method (5 chunks for $n \le 100$, 11 for $n \le 500$) provides the best performance.
  • High Disorder (≥ 0.5): For highly reversed stacks, we pivot to advanced partitioning (Merge Sort or high-density chunking) to respect the $O(n \log n)$ complexity.

Checker Algorithm

Our checker must be compile with the rule bonus of the makefile to be used. Here is his algorithm :

  • Code Logic: The intialisation of the stacks work as the same of the original push_swap, as well as the error raises. When the stacks is initialized, it read from the stdout read(0) with get_next_line and check if the operation is valid.

  • Check Value: After the press of Ctrl + D, the code stop doing the operations. It check if the stacks is well sorted and if the stack b is empty (the stack = NULL).

  • Return Value: It can return four different value :

    • Nothing, if there is no argument is given.
    • Error\n, if there is wrong argument, int_max, dupplicate values - wrong operations given.
    • KO\n, if there is good parsing and operations but it doesn't sort the stack a or stack b is not empty.
    • OK\n, if there is good parsing, good operations and both stack a sorted and stack b empty.

Top ↑ | Next ↓

Instructions

Installation

Designed for Linux systems. Ensure you have a C compiler (gcc/clang) and make installed.

git clone GIT push_swap
cd push_swap

Compilation

The project includes a Makefile with the following standard rules:

Rule Purpose
make / all Compiles the mandatory part (push_swap).
bonus Compiles the bonus checker program (checker).
clean Removes all intermediate object files (.o).
fclean Removes object files and generated executables.
re Full re-compilation (fclean + all).
# To build the mandatory part:
make

# To build the checker (bonus):
make bonus

Execution

1. Running Push Swap

The push_swap program takes a list of integers as arguments and outputs the shortest sequence of instructions to sort them.

# Using separate arguments
./push_swap 2 1 3 6 5 8

# Using a single quoted string
./push_swap "2 1 3 6 5 8"

2. Small Dataset Examples (3 & 5 elements)

For small datasets, the algorithm is optimized to reach peak efficiency, consistently staying within the limits for a perfect score.

3 Elements (Total: 6 Permutations)

# Example with 3 numbers:
./push_swap --simple 3 1 2
Operations Count Percentage
0 1 16.7%
1 3 50.0%
2 2 33.3%
*Average: 1.17 ops Max: 2 ops*

5 Elements (Total: 120 Permutations)

# Example with 5 numbers:
./push_swap --simple 5 2 4 1 3
Operations Count Percentage
0 1 0.8%
3 2 1.7%
4 1 0.8%
5 6 5.0%
6 19 15.8%
7 30 25.0%
8 30 25.0%
9 20 16.7%
10 9 7.5%
11 2 1.7%
*Average: 7.47 ops Max: 11 ops*

3. Running the Checker (Bonus)

The checker program verifies if the sequence of operations generated by push_swap correctly sorts the stack. You can pipe the output of push_swap into checker:

ARG="4 67 3 87 23"; ./push_swap $ARG | ./checker $ARG

Expected Outputs:

Output Meaning
OK The stack is sorted and Stack B is empty.
KO The stack is not sorted correctly.
Error Invalid input: non-integers, out of range, or duplicates.

4. Large Dataset Testing

You can use the shuf utility (available on most Linux systems) to generate random datasets for testing performance:

# Test with 50 random numbers
shuf -i 0-9999 -n 50 > args.txt ; ./push_swap $(cat args.txt)

# Test with 100 random numbers
shuf -i 0-9999 -n 100 > args.txt ; ./push_swap $(cat args.txt)

# Test with 500 random numbers
shuf -i 0-9999 -n 500 > args.txt ; ./push_swap $(cat args.txt)

5. Benchmark Mode

The program includes a built-in benchmark mode to analyze sorting performance, including disorder metrics and operation breakdowns. Benchmark data is sent to stderr (file descriptor 2).

Run with benchmark enabled:

shuf -i 0-9999 -n 500 > args.txt ; ./push_swap --bench $(cat args.txt) 2> bench.txt | ./checker $(cat args.txt)
cat bench.txt

Example Benchmark Output:

[bench] disorder:  49.93%
[bench] strategy:  Adaptive / O(n√n)
[bench] total_ops: 7997
[bench] sa:  0 sb:  0 ss:  0 pa:  500 pb:  500
[bench] ra:  4840 rb:  1098 rr:  0 rra:  0 rrb:  1059 rrr:  0

Pipe operations to checker while saving benchmark:

ARG="4 67 3 87 23"; ./push_swap --bench --adaptive $ARG 2> bench.txt | ./checker $ARG

6. Error Management Examples

The program handles invalid inputs gracefully, displaying Error to standard error:

./push_swap --adaptive 0 one 2 3
# Output: Error

./push_swap --simple 3 2 3
# Output: Error (duplicate detected)

Top ↑ | Next ↓

Resources

Documentation & 42 Guides

Tutorials & Technical Blogs

Video Tutorials

Reference Implementations (GitHub)

C Language & Bitwise References

Top ↑

AI Usage & Technical Exploration

As part of the project requirements, here is a summary of how AI (ChatGPT) was utilized during development:

  • Documentation & Structure: AI was used to organize and structure this README.md to ensure clarity and professional presentation.
  • Performance Testing: AI assisted in designing and executing comprehensive tests for small datasets (3 and 5 elements) to ensure peak efficiency.
  • Technical Topics Explored:
    1. Algorithm Selection & Optimization: Researching efficient sorting strategies based on input size.
    2. Chunk-Based Sorting Logic: Understanding the conceptual mechanics and performance impact of chunk boundaries.
    3. Stack Structure Design: Designing robust data structures in C (e.g., doubly linked lists with metadata).
    4. Memory Management: Ensuring proper malloc and free handling within complex structs.
    5. Operation Logic: Sequencing stack operations (sa, ra, pb, etc.) for maximum efficiency.

Note: Shell vs. Bash

You may notice the ```bash tags in the instructions above. Here is a quick breakdown of the difference:

  • Shell: A generic term for any program that provides a command-line interface to the operating system (e.g., the terminal window). It acts as a "shell" around the OS kernel.
  • Bash (Bourne Again SHell): A specific implementation of a shell. It is the default on most Linux distributions.
  • The Difference: Think of Shell as the category "Smartphone" and Bash as a specific model like "iPhone". Other shells include Zsh (default on macOS), Dash, and Fish. For this project, most commands will work identically across any modern shell.

Top ↑

About

push_swap

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published