This project has been created as part of the 42 curriculum by nstreet-.
push_swap is a 42 sorting project focused on algorithmic thinking, stack manipulation, and move optimization. The program receives a list of integers as command-line arguments and prints a sequence of valid push_swap operations that sorts the numbers in ascending order using two stacks, a and b.
This implementation uses:
- input validation for invalid numbers, duplicates, empty arguments, and integer overflow
- dedicated routines for very small inputs (
2,3, and5numbers) - rank assignment to normalize comparisons
- a two-phase strategy for larger inputs:
- push elements from stack
ato stackbusing a dynamic range - bring elements back to stack
awith the cheapest rotation cost, combining rotations when possible
- push elements from stack
The data structure is a doubly linked list-based stack, which makes push and rotation operations straightforward to express.
- Validates every argument before sorting
- Prints
Errorto standard error on invalid input - Exits silently when no sorting is needed
- Handles already sorted input without printing unnecessary operations
- Uses optimized paths for small stacks and a Turk-style heuristic for larger ones
makeThis builds the executable push_swap.
make
make clean
make fclean
make re./push_swap 2 1 3 6 5 8Example output:
sa
pb
pb
pb
sa
pa
pa
pa
The exact sequence may vary depending on the strategy used, but it must sort the input using only the allowed operations.
- Arguments must be valid
intvalues - Duplicate numbers are rejected
- Non-numeric input is rejected
- On invalid input, the program writes
Errorto standard error
Examples:
./push_swap 3 2 1
./push_swap -5 10 0 42
./push_swap 1 2 2
./push_swap hello 3 42numbers: swap if needed3numbers: sort with a minimal case-based routine4or5numbers: push the smallest values to stackb, sort the remaining3, then push back
For larger stacks, this implementation follows a Turk-style approach split into two phases.
Before any large sort starts, each value receives a rank based on how many values are smaller than it.
This transforms the problem from comparing raw integers to comparing positions in sorted order:
- the smallest value gets rank
0 - the largest value gets rank
n - 1
This makes the algorithm independent of the original numeric range and simplifies placement decisions.
The first phase moves values from stack a to stack b, but not in a naive order.
Instead, it uses a sliding window over the ranks:
- for inputs up to
100numbers, the window size is15 - for larger inputs, the window size is
33
The algorithm keeps a moving index i representing the next expected low rank.
At each step:
- if the top of
ahas a rank<= i, it is pushed tobandbis rotated immediately - if the top of
ahas a rank<= i + range, it is pushed tobwithout rotatingb - otherwise,
ais rotated until a suitable element appears at the top
This works like a sliding window because the accepted rank interval keeps moving forward as elements are pushed.
Lower ranks are sent deeper into b, while more recent values stay closer to the top. That distribution makes the second phase cheaper.
Once every value is in b, the program rebuilds the sorted stack in a.
For each candidate node in b, it computes:
- the position of that node in
b - the target position where it should be inserted in
a - the number of rotations needed in both stacks
Those raw positions are converted into signed step counts:
- positive values mean rotate upwards (
ra/rb) - negative values mean reverse rotate (
rra/rrb)
If both stacks need to move in the same direction, the algorithm can combine part of the work with:
rrwhen both need upward rotationsrrrwhen both need reverse rotations
So the move cost is:
- the larger of the two counts when directions match
- the sum of both counts when directions differ
The cheapest candidate is selected, executed, and pushed back to a with pa.
After all values return to a, the stack is almost sorted but may be rotated.
The final step rotates a until the minimum value is at the top, producing a fully sorted stack from top to bottom.
This keeps the implementation simple while reducing the total number of operations compared with a naive strategy.
includes/
push_swap.h
src/
main.c
parsing.c
stack.c
ops_swap.c
ops_push.c
ops_rotate.c
ops_rev_rotate.c
sorting_small.c
sorting_large.c
turk_phase_1.c
turk_phase_2.c
makefile
- 42
push_swapsubject PDF - Notes on linked lists and stack operations for implementing rotations and pushes safely
- https://pure-forest.medium.com/push-swap-turk-algorithm-explained-in-6-steps-4c6650a458c0
- https://github.com/alx-sch/push_swap
- https://medium.com/@ayogun/push-swap-c1f5d2d41e97