Pushswap Epitech Project
Authorized functions
The list of authorized functions are only:
Description
The goal of the project is to return the series of actions for sorting a list. You will have two lists : l_a
and l_b
.
The l_b
starts empty and l_a
contain the list of integers you need to sort.
The objective can be to sort the l_a
list, but there is a mystery strategy of only printing and not sorting, that gives you great performances, but I don’t know this technique so you are going to sort the l_a
list.
If you want to try the mysterious strategy, I only know that you need to print a specific number of bubble sort actions.
So from the beginning I tell you you will need actions, and here the list of them :
Note
sa: swap the first two elements of
l_a
.sb: swap the first two elements of
l_b
.sc: swap the first two elements of
l_a
and swap the first two elements ofl_b
.pa: take the first element from
l_b
and move it to the first position on thel_a
list.pb: take the first element from
l_a
and move it to the first position on thel_b
list.ra: the first element of
l_a
will become the last.rb: the first element of
l_b
will become the last.rr: the first element of
l_a
will become the last and the first element ofl_b
will become the last.rra: the last element of
l_a
will become the first.rrb: the last element of
l_b
will become the first.rrr: the last element of
l_a
will become the first and the last element ofl_b
will become the first.
The l_a
list is passed as paramter.
Exemple
We are going to take l_a
= [1, 2, 3, 4, 5] and l_b
= [] (empty).
Example
sa:
l_a
= [2, 1, 3, 4, 5]sb:
l_b
= []sc:
l_a
= [2, 1, 3, 4, 5] andl_b
= []pa:
l_a
= [1, 2, 3, 4, 5] andl_b
= []pb:
l_a
= [2, 3, 4, 5] andl_b
= [1]ra:
l_a
= [2, 3, 4, 5, 1]rb:
l_b
= []rr:
l_a
= [2, 3, 4, 5, 1] andl_b
= []rra:
l_a
= [5, 1, 2, 3, 4]rrb:
l_b
= []rrr:
l_a
= [5, 2, 1, 3, 4] andl_b
= []
Tutorial
The project Pushswap is quite simple when you understand how to do. It is splited into 3 parts:
Linked List the
l_a
with args passed as parameters.Actions asked on the subject.
Algorithm radix sort by Bit Shifting method.
The project can be done by multiple different way:
By using array.
By using simply linked list.
By using doubly linked list.
By using doubly circular linked list.
I am sure you know which one we will choose 😂 …. doubly circular linked list
. You: 😭: readding this tutorial. Don’t be afraid, it is not as complicated as you’re thinking !
Linked List
To create a doubly circular linked list you need to have a linked list following this schema:
This schema shows you how to construct it. So now let take a look at some code.
|
|
This is how can looks your linked list. A next
and a prev
for the links and data your list of integers.
To create you doubly circular linked list you will need to save temporarily the pointer of the first node to make the last node point on it. You will also need to keep a pointer on the previous node to make point the prev
of the next to his previous node.
|
|
Note
- my_atoi: convert a string into an integer.
Here you have a node linked to itself, that’s what we want for only one element, but it will change a bit for the next step of adding other nodes.
For adding other nodes, you need to initialise a new_node, fill his data by the integer you want and make it point to the first node. When you have done that, make point your next current node on the new node you have created. Move to the next node of your current node and now you can link the prev
with your previous node.
A bit hard to understand ? Take a look on the code:
|
|
Tip
init_linked_list
right after.Only one thing is missing here ! The last link !!
|
|
You were on the last node, you moved to the next that point on the first and you have linked the previous of the first on his previous that is the end’s node. So you should have something looking like this:
|
|
I let you understand by yourself how are working the references I sent to the others_nodes
function.
Actions
Actions are, NO FAKE, the EASIEST part of the project !
sa, sb and sc
Note
If you read the subject :
sa: swap the first two elements of
l_a
.sb: swap the first two elements of
l_b
.sc: swap the first two elements of
l_a
and swap the first two elements ofl_b
.
Let’s call a s_action function that will swap the two first elements of a list.
|
|
Next !
pa and pb
Note
If you read the subject :
pa: take the first element from
l_b
and move it to the first position on thel_a
list.pb: take the first element from
l_a
and move it to the first position on thel_b
list.
Let’s call a p_action
or push_to_other_list
function that will move the first element of a list at the first position of another. But !…
You will first need a delete_node
function that will check if a linked list contain only one or more node. If it contains only one, then set the linked list at NULL
. If the list contains more, you will need to make your previous node (from the node you want to delete) point on the next (from the node you want to delete).
|
|
Now you have the delete_node
function you can save the node you want to delete into a saver and delete the integer from the linked list.
|
|
Only what you need now is to insert the saved node into the next linked list. So check if this list is empty. When it is empty, just place the node in it and make point on itself. If the linked list contains nodes, it will be a bit harder. I let you take a look on the code and I explain you after.
|
|
Here you are on the first node, so you save the previous to insert it on the previous and the first node. Remember the previous of the first is the end. So you change that and you place your saver on the previous of your first node. This new first node need to his next
point on the now second node (that was your first node previously). Likewise, you need to your previous of your first node point on the previous of the previously first node, so you make point on the one you saved (stock variable). And so now the end’s node needs to point to the first node. You now have the element of the other list at the first position in this list. But, your current pointer is pointing to the second, so you move to the first element of your list by using to = to->prev
.
Hard but you have succeeded !
Next !
ra, rb and rr
Note
If you read the subject :
ra: the first element of
l_a
will become the last.rb: the first element of
l_b
will become the last.rr: the first element of
l_a
will become the last and the first element ofl_b
will become the last.
Let’s call a r_action
or first_to_end
function that will move the first element at the end of this list.
|
|
Here is, you have just moved your pointer to the next, so the first becomes the end as you have a doubly circular linked list.
Next !
rra, rrb and rrr
Note
If you read the subject :
rra: the last element of
l_a
will become the first.rrb: the last element of
l_b
will become the first.rrr: the last element of
l_a
will become the first and the last element ofl_b
will become the first.
Let’s call a rr_action
or end_to_first
function that will move the end element at the first position of this list, and I am sure that you know how to do it !
|
|
Algorithm
First of all, before starting the algorithm in your code you would maybe checks if the list is already sorted. So write a function that check with bubble travel if your list is sorted.
|
|
Note
l_a = l_a->next
which make you come back at the beginning of your linked list.So now, for the algorithm, you will need to bitshift. What is the bitshift ?
The bitshift transform your numbers on bits, an integer in on 32 bits:
31: for the positive part
The ‘1’ of 31 + 1 = 32: for the negative part
You need a loop for looking the 31 bits and a last check for the negative bit. So lets do something like that:
|
|
Why did I save 'i'
and 'k'
? Because with The Epitech’s coding style we can’t have more than 4 parameters per function and here you will need more, so you save values in structure like 'i'
and 'k'
.
Now you know that, you can create the positive function with bitshifting radix algorithm.
You need to loop on each element from the args that are in your l_a
list and look if the save->i
bit of your bitshifted number has the same weight. If it has the number will be placed in the l_b
list. Like so, you will sort par each weight of bits. If I represent in on a schema it will do that:
As you can see the smaller number as been putted at the end of the list. You only need to loop on every bit and the project is done !
|
|
I reseume: You look “every” bit (31 bits) on every arg. At each look, you compare the bit’s weight. If it weight one you push in the l_b
list, otherwise you put your first node at the end (to travel your linked list). When you have traveled the entire list, fill at the end of the l_a
list the l_b
.
After doing positives, do the same for the negative.
|
|
And it is done ! You should now have a main loop like that, with the negative after the loop:
|
|
Note
'\n'
and not " \n"
. So you display a rb action which does nothing because your l_b
list is empty.You have finished your project well done !
Bonus ideas
Print the evolution of the sort
Print in color
Print with a grafical library
Do for floats
Optimisation for small list (by using another algorithm)