Code Monkey home page Code Monkey logo

push_swap's Introduction

push_swap

This project is part of the official curriculum at School 42.

Disclaimer

In School 42, almost every project must be written to comply with. coding standard (also known as the "Norm"). As a result, the implementation of certain parts may appear strange.

Overview

  • Official instructions
  • The goal of this project is to practice sorting algorithms and design a new one, optimized for a given data structure.
  • As per instructions, the project is realised using a C library compiled during previous projects.

Problem

The goal is to design an algorithm that would sort a list of integers without any duplicated. The algorithm should operate on two stacks, a and b, using the shortest sequence of the following operations:

  • sa – Swap the first two elements at the top of stack a. Do nothing if there is only one or no elements.
  • sb – Swap the first two elements at the top of stack b. Do nothing if there is only one or no elements.
  • ss – Do sa and sb at the same time.
  • pa – Take the first element at the top of b and put it at the top of a. Do nothing if b is empty.
  • pb – Take the first element at the top of a and put it at the top of b. Do nothing if a is empty.
  • ra – Shift up all elements of stackA by one. The first element becomes the last one.
  • rb – Shift up all elements of stack b by one. The first element becomes the last one.
  • rr – Do ra and rb at the same time.
  • rra – Shift down all elements of stack a by one. The last element becomes the first one.
  • rrb – Shift down all elements of stack b by one. The last element becomes the first one.
  • rrr – Do rra and rrb at the same time.

The project yields three programs:

  1. checker
    • Gets as an argument the stack a formatted as a list of integers (the first argument should be at the top of the stack)
    • Read instructions on the standard input, each instruction will be followed by \n. Once all the instructions have been read, checker will execute them on the stack received as an argument.
    • If after executing those instructions, stack a is actually sorted and b is empty, then checker must display OK followed by a \n on the standard output. In every other case, checker must display KO followed by a \n on the standard output.
    • In case of error, you must display Error followed by a \n on the standard error. Errors include for example: some arguments are not integers, some arguments are bigger than an integer, there are duplicates, an instruction don’t exist and/or is incorrectly formatted.
  2. push_swap
    • Gets as an argument the stack a formatted as a list of integers (the first argument should be at the top of the stack)
    • The program must display the smallest list of instructions possible to sort the stack a, the smallest number being at the top.
    • In case of error, you must display Error followed by a \n on the standard error. Errors include for example: some arguments aren’t integers, some arguments are bigger than an integer, and/or there are duplicates.
  3. random-list-generator
    • A simple Python script that outputs a random permutation of a given number of positive integer values

The project is then checked as follows

> ARG=$(./random-list-generator <number of values>); ./push_swap $ARG | ./checker $ARG
OK

(NOTE that the above command doesn't work on zsh, so if you're using it, run this instead sh -c 'ARG=$(./random-list-generator <number of values>); ./push_swap $ARG | ./checker $ARG'.)

Algorithm

For efficiency, two different algorithms are utilized

  • simple: for up to six values
  • advanced: for more than six values

Simple algorithm

  1. Manually code how to sort a stack of up to three values. With only six possible permutations this is easy to do.
  2. If there are over three values, push all values less than the median onto stack b, sort two stacks independently and then merge.

Advanced algorithm

STEP 1: SPLIT INTO TWO STACKS

Push all numbers, except for 2, from stack a to stack b.

STEP 2: MERGE STACKS

At each iteration, calculate the number of operations necessary to push a number from stack b to stack a, such that it ends up in the right place on stack a (without introducing any conflicts). Take into account that ra and rb can be accomplished simultaneously with rr etc. Do this for all numbers in stack b, select the one with the least number of operations and push back to stack a.

For example, say we have

STACK A: 4->5->1->2
STACK B: 6->3

and

6: 2 rotations (2 x ra) and 1 push (1 x pa)
3: 1 rotation (1 x rb) and 1 push (1 x pa)

Hence, we start by pushing 3. Then

STACK A: 3->4->5->1->2
STACK B: 6

we only have 6 left in stack b, so we push it with 2 x rra and 1 x pa.

STEP 3: ROTATE STACK A

At this point, stack b is empty and stack a is "circulary" sorted (i.e. it has no conflicts but the smallest number may not be on top).

For example, our stack a after steam 2 is

STACK A: 6->1->2->3->4->5

It would take 1 x ra and 5 x rra to get 1 to the top. Therefore, we choose perform 1 x ra and we're done.

Results

Here is a graph describing the performance of this algorithm in the range between 1 and 500 values. Each data point consists of 100 measurements.

And here's another one, for the range between 1 and 100 values. Each data point consists of 500 measurements.

Build and test

To build executables, run

git clone [email protected]:almayor/push_swap.git
cd push_swap
git submodule update --init --recursive
make

To run tests (unit and functional), run

make test

or, if you wish to skip unit tests,

make test TEST-UNIT=0

Finally, if you wish checker to print stacks after each operation (e.g. for debugging purposes), you can do with

./checker -v <numbers>

Acknowledgements

My thanks go to @jmalik at the Moscow branch of School 42, discussions with whom have greatly improved my understanding of the problem and contributed to STEP 2 of my algorithm. I am also grateful to the entire team behind School 42, as well as to my other fellow students for help and support. Finally, the push swap visualizer project by o-reo has been a veritable treasure


If you have any questions, please contact me on Github.

push_swap's People

Contributors

almayor avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.