what does 'work through an algorithm by hand' mean? - algorithm

I'm doing this assignment and I don't understand the wording. Do you think it means to write in pseudocode or write a paragraph? Does anyone have any ideas?

It means to describe the algorithm with words and draw the array values in each step. Here is an example: https://www.geeksforgeeks.org/bubble-sort/

Before executing the algorithm, the array is:
4 2 12 1 7 9 9
After executing the algorithm, the array is:
1 2 4 7 9 9 12
During the execution of the algorithm, the array slowly changes from what is was before, to what it will be after. Your assignment requires you to show all the intermediate steps.
For instance, the very first step of execution will be "compare element at position 0 with position 1; if element at position 1 is lower, then swap the two elements". The first two elements are 4 and 2; 2 is lower; hence they should be swapped; the resulting array is:
2 4 12 1 7 9 9
Then the second step will be "compare elements at position 1 and 2", which are 4 and 12; etc.

Related

Can you check for duplicates by taking the sum of the array and then the product of the array?

Let's say we have an array of size N with values from 1 to N inside it. We want to check if this array has any duplicates. My friend suggested two ways that I showed him were wrong:
Take the sum of the array and check it against the sum 1+2+3+...+N. I gave the example 1,1,4,4 which proves that this way is wrong since 1+1+4+4 = 1+2+3+4 despite there being duplicates in the array.
Next he suggested the same thing but with multiplication. i.e. check if the product of the elements in the array is equal to N!, but again this fails with an array like 2,2,3,2, where 2x2x3x2 = 1x2x3x4.
Finally, he suggested doing both checks, and if one of them fails, then there is a duplicate in the array. I can't help but feel that this is still incorrect, but I can't prove it to him by giving him an example of an array with duplicates that passes both checks. I understand that the burden of proof lies with him, not me, but I can't help but want to find an example where this doesn't work.
P.S. I understand there are many more efficient ways to solve such a problem, but we are trying to discuss this particular approach.
Is there a way to prove that doing both checks doesn't necessarily mean there are no duplicates?
Here's a counterexample: 1,3,3,3,4,6,7,8,10,10
Found by looking for a pair of composite numbers with factorizations that change the sum & count by the same amount.
I.e., 9 -> 3, 3 reduces the sum by 3 and increases the count by 1, and 10 -> 2, 5 does the same. So by converting 2,5 to 10 and 9 to 3,3, I leave both the sum and count unchanged. Also of course the product, since I'm replacing numbers with their factors & vice versa.
Here's a much longer one.
24 -> 2*3*4 increases the count by 2 and decreases the sum by 15
2*11 -> 22 decreases the count by 1 and increases the sum by 9
2*8 -> 16 decreases the count by 1 and increases the sum by 6.
We have a second 2 available because of the factorization of 24.
This gives us:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24
Has the same sum, product, and count of elements as
1,3,3,4,4,5,6,7,9,10,12,13,14,15,16,16,17,18,19,20,21,22,22,23
In general you can find these by finding all factorizations of composite numbers, seeing how they change the sum & count (as above), and choosing changes in both directions (composite <-> factors) that cancel out.
I've just wrote a simple not very effective brute-force function. And it shows that there is for example
1 2 4 4 4 5 7 9 9
sequence that has the same sum and product as
1 2 3 4 5 6 7 8 9
For n = 10 there are more such sequences:
1 2 3 4 6 6 6 7 10 10
1 2 4 4 4 5 7 9 9 10
1 3 3 3 4 6 7 8 10 10
1 3 3 4 4 4 7 9 10 10
2 2 2 3 4 6 7 9 10 10
My write-only c++ code is here: https://ideone.com/2oRCbh

Modified algorithm for building a Heap

I am quite new to programming and I am trying to understand a certain problem regarding heap sort. In a book I'm reading, there is a modified algorithm for building a max heap, which is:
BuildHeap(A)
A.heap-size = 1
for i = 2 to A.length
Heap-Insert(A, A[i])
So from my understanding, this algorithm takes in an array and defines the size of the heap to be 1 and then iterates from 2 to the total length of the array and then inserts the value into the heap.
But how would this build a max heap? If I had an array of [4, 7, 2, 3, 9, 1], then wouldn't the algorithm start at value 2 and then simply add all the values from the A[2] to A.length to the heap without actually building a max heap?
I do not understand how the heap-size = 1 does anything in the algorithm other than restrict the total size of the heap. I am confused as to how you would build a max heap.
From what it states in the book, the normal max heap works by first inserting every array value into a heap, and then starting at the A/2 place, then working backwards and swapping values that are larger than the current value being assessed by calling Max-Heapify.
So how would this max heap work since there is no Max-Heapify(A, largest) call, but instead there is simply a heap-insert(A, A[i])?
First of all, this question is not about heap sort, which is just one of the applications for a heap. You are asking about the heap construction.
The pseudo code you presented is indeed an alternative (and less efficient) way of building a heap, and this would actually be the algorithm that many would come up with when they wouldn't have known about the standard algorithm of Floyd.
So taking a look at the code:
BuildHeap(A)
A.heap-size = 1
for i = 2 to A.length
Heap-Insert(A, A[i])
Most of the logic of this algorithm is berried inside the Heap-Insert function, which is not just a simple "append" to an array: it does much more than that. Wikipedia describes that hidden algorithm as follows:
Add the element to the bottom level of the heap at the leftmost open space.
Compare the added element with its parent; if they are in the correct order, stop.
If not, swap the element with its parent and return to the previous step.
You write in your question:
there is no Max-Heapify(A, largest)
Indeed, it would be too simple if you already knew what the largest value was before using the heap. You need to first insert a value (any value) in a heap, and let the heap do its magic (inside Heap-Insert) to make sure that the largest value ends up in the first (top) position in the array A, i.e. in A[1].
The first step of the quoted algorithm is thus important: Heap-Insert expects the new value to be inserted at the end.
Let's work through the example [4, 7, 2, 3, 9, 1], and let's put a pipe symbol to indicate the end of the heap. At the start, the heap size is 1, so we have:
4 | 7 2 3 9 1
Let's also represent a more visually appealing binary tree at the right side -- it just has a root element:
4 | 7 2 3 9 1 4
Then we call Heap-Insert(A, A[2]), which is Heap-Insert(A, 7). The implementation of Heap-Insert will increase the size of the heap, and put that value in the last slot, so we get:
4 7 | 2 3 9 1 4
/
7
Heap-Insert has not finished yet -- this was just the first step it performs. Now it "bubbles up" that 7 following steps 2 and 3 of that quoted algorithm, and so we get:
7 4 | 2 3 9 1 7
/
4
At the second iteration of the pseudo code loop, we call Heap-Insert(A, 2), so Heap-Insert performs its first step:
7 4 2 | 3 9 1 7
/ \
4 2
...and finds out that nothing needs to change when performing step 2 and 3.
We continue inserting 3:
7 4 2 3 | 9 1 7
/ \
4 2
/
3
...and again nothing needs to change as 3 is less than 4 (remember that A[2] is the parent of A[4].
We continue inserting 9:
7 4 2 3 9 | 1 7
/ \
4 2
/ \
3 9
And here 9 > 4, and also 9 > 7, so Heap-Insert will further modify A to this:
9 7 2 3 4 | 1 9
/ \
7 2
/ \
3 4
One more to go:
9 7 2 3 4 1 9
/ \
7 2
/ \ /
3 4 1
And Heap-Insert has nothing more to do as 1 < 2.

Diagonal number pattern logic

I want to device an algorithm to display the following pattern:
1
9 2
10 8 3
14 11 7 4
15 13 12 6 5
Is there a way to convert it into the following array and use the indices of the above matrix and find out the position of the number in the array:
1 9 2 10 8 3 ...
I can't find a pattern to calculate the element using the matrix co-ordinates, that is why I was trying to device the above method of somehow determining the position of the next number in the array.
Just clues:
You need to know formula for sum of arithmetic progression (here sum of natural numbers 1 + 2 + 3 +.. N)
1st step: determine number of diagonal where k-th item of array stands.
2nd step: get direction of this diagonal filling
3rd step: get number of place at this diagonal
4th step: find what number stands here

Which sorting algorithm produces these steps?

This was a multiple-choice question in an exam today, and (at least) one of the answers should be true, but to me they all look wrong.
The sorting steps are:
5 2 6 1 3 4
4 2 6 1 3 5
4 2 5 1 3 6
4 2 3 1 5 6
1 2 3 4 5 6
The available answers were: Bubble Sort, Insertion Sort, Selection Sort, Merge Sort and Quick Sort.
I think that is a Quick sort. Here we can see the following steps:
A random selection of the reference element in the array (pivotValue), with respect to which reorders the elements of the array.
Move all of the values that are larger than the reference to the right, and all the values that the lower support left
Repeat algorithm for unsorted the left and right side of the array, while each element will not appear on its position
Why I think so:
It definitely isn't a Bubble Sort because it compares the first two elements of the array beginning so, the first step should be 2 5 6 1 3 4
It isn't a Insertion Sort because it's a sequential algorithm. In the first step we see that compared the first and the last element
It isn't a Selection Sort because it find the lowest value and move it to the top so, the first step should be 1 5 2 6 3 4
It isn't a Merge Sort because the array is divided into two subarrays. In this case we see interaction "first" and "second" parts
None of them.
bubble sort: no. After k steps, the last k elements should be the k largest, sorted.
insertion sort: no. After k steps, the k first elements should be sorted.
selection sort: no. After k steps, the k first elements should be the s smallest, sorted.
merge sort: no. After k steps, a value can only have moved 2^k - 1 places. (5 moves 5 places at k=1)
quick sort: no. Whatever the pivot is, 1 and 6 being the extreme values, they can stay in this initial position.
On the quick sort: To make it clear that it is not possible, lets enumerate the results of each pivot for the first step:
5 : [2134] - 5 - [6]. (2134 may be in any order)
2 : [1] - 2 - [5634]
6 : [52134] - 6
1 : 1 - [52634]
3 : [21] - 3 - [564]
4 : [213] - 4 - [56]
One obvious way of seeing that all those are incompatible with the OP's output is that in each case, the 1 is before the 6, no matter how you implement the pivot or the partition.
To solve this all you have to do is make a function for each sort algorithm but include a statement to print the array out after each swap. Then apply your print friendly sort algorithms to the initial array [5 2 6 1 3 4] and see which sort method produces the same output. Additionally, this will help you compare all the different methods.

Ascending Cardinal Numbers in APL

In the FinnAPL Idiom Library, the 19th item is described as “Ascending cardinal numbers (ranking, all different) ,” and the code is as follows:
⍋⍋X
I also found a book review of the same library by R. Peschi, in which he said, “'Ascending cardinal numbers (ranking, all different)' How many of us understand why grading the result of Grade Up has that effect?” That's my question too. I searched extensively on the internet and came up with zilch.
Ascending Cardinal Numbers
For the sake of shorthand, I'll call that little code snippet “rank.” It becomes evident what is happening with rank when you start applying it to binary numbers. For example:
X←0 0 1 0 1
⍋⍋X ⍝ output is 1 2 4 3 5
The output indicates the position of the values after sorting. You can see from the output that the two 1s will end up in the last two slots, 4 and 5, and the 0s will end up at positions 1, 2 and 3. Thus, it is assigning rank to each value of the vector. Compare that to grade up:
X←7 8 9 6
⍋X ⍝ output is 4 1 2 3
⍋⍋X ⍝ output is 2 3 4 1
You can think of grade up as this position gets that number and, you can think of rank as this number gets that position:
7 8 9 6 ⍝ values of X
4 1 2 3 ⍝ position 1 gets the number at 4 (6)
⍝ position 2 gets the number at 1 (7) etc.
2 3 4 1 ⍝ 1st number (7) gets the position 2
⍝ 2nd number (8) gets the position 3 etc.
It's interesting to note that grade up and rank are like two sides of the same coin in that you can alternate between the two. In other words, we have the following identities:
⍋X = ⍋⍋⍋X = ⍋⍋⍋⍋⍋X = ...
⍋⍋X = ⍋⍋⍋⍋X = ⍋⍋⍋⍋⍋⍋X = ...
Why?
So far that doesn't really answer Mr Peschi's question as to why it has this effect. If you think in terms of key-value pairs, the answer lies in the fact that the original keys are a set of ascending cardinal numbers: 1 2 3 4. After applying grade up, a new vector is created, whose values are the original keys rearranged as they would be after a sort: 4 1 2 3. Applying grade up a second time is about restoring the original keys to a sequence of ascending cardinal numbers again. However, the values of this third vector aren't the ascending cardinal numbers themselves. Rather they correspond to the keys of the second vector.
It's kind of hard to understand since it's a reference to a reference, but the values of the third vector are referencing the orginal set of numbers as they occurred in their original positions:
7 8 9 6
2 3 4 1
In the example, 2 is referencing 7 from 7's original position. Since the value 2 also corresponds to the key of the second vector, which in turn is the second position, the final message is that after the sort, 7 will be in position 2. 8 will be in position 3, 9 in 4 and 6 in the 1st position.
Ranking and Shareable
In the FinnAPL Idiom Library, the 2nd item is described as “Ascending cardinal numbers (ranking, shareable) ,” and the code is as follows:
⌊.5×(⍋⍋X)+⌽⍋⍋⌽X
The output of this code is the same as its brother, ascending cardinal numbers (ranking, all different) as long as all the values of the input vector are different. However, the shareable version doesn't assign new values for those that are equal:
X←0 0 1 0 1
⌊.5×(⍋⍋X)+⌽⍋⍋⌽X ⍝ output is 2 2 4 2 4
The values of the output should generally be interpreted as relative, i.e. The 2s have a relatively lower rank than the 4s, so they will appear first in the array.

Resources