There is no comparison function in the description of the problem, so I would define compare (lista, listb) to compare the first node of the list with the first node of the listb and return -1 for <, 0 for =, 1 for more or everything that is really needed to sort the merge is 0 for <= and 1 for>.
There is also no return value indicating that the list is empty when pa or pb is executed. I would define pa or pb to return 1 if the source list is not empty, and 0 if the source list is empty (no node to copy).
It is not clear whether the target is the smallest number of instructions, refers to the number of instructions in the source code or the number of instructions executed during sorting.
-
The smallest number of commands in the code will rotate list2 based on a comparison with list1 to insert nodes into list2 in the right place. Start with pb and set list2 to 1. Then rb or rrb is executed to rotate list2 to where the next pb should be executed. The code will track the "offset" of list2 to the smallest node to avoid an infinite loop in a rotating list2. Complexity is O (n ^ 2).
-
I think the fastest sorting, and possibly the least number of instructions executed, is a merge sort from bottom to top.
Do a merge sort from bottom to top as you rotate lists, using them as circular buffers / lists. Copy list1 to list2 to generate the number of nodes using the sequence | count = 0 | whereas (pb) {rb | count + = 1}.
Using the counter, move all the other nodes from list2 to list1, using {pa, rr}, n / 2 times. Always keep track of the actual number of nodes in each list to find out when the logical end of the list is reached. Also track the run counter for each list to see when the logical end of the run is reached. At the moment, you have two lists where even nodes are in list1, and odd nodes are in list2.
The launch size starts at 1 and doubles on each pass. For the first pass, with run size 1, even nodes with odd nodes are combined, creating sorted runs of size 2, alternating the addition of sorted pairs of nodes in list1 and list2. For example, if you add to the list1 and list1 node <= list2 node, use {ra, run1count - = 1}, otherwise use {pa, ra, run2count - = 1}. When the end of execution has been reached, add the rest of the remaining run to the end of the list. In the next pass, the merge sorts the runs from 2 nodes from the lists, alternately adding the sorted runs of 4 nodes to each list. Continue this for runs 8, 16, ... until all nodes are in the same list.
So, to go through the counting of nodes, one pass separates the even and odd nodes, and ceil (log2 (n)) proceeds to sort the merge. The overhead for linked list operations is small (rotate removes and adds node), so general merging should be pretty quick.
The number of instructions on the counter can be reduced by using while (pb) {count + = 1}, which would copy list1 to list2 in reverse order. Then flipping list2 to list1 will also be done using rrr to cancel them.
Complexity is O (n log (n)).