Insertion sort explanation - pascal

I am trying to understand the code of insertion sort, but i am really confused and i don't understand what i,j,index are doing in the code.. Can someone please help me understand more
Procedure InsertionSort(numbers : Array of Integer; size : Integer);
Var i, j, index : Integer
Begin
For i := 2 to size-1 do
Begin
index := numbers[i];
j := i;
While ((j > 1) AND (numbers[j-1] > index)) do
Begin
numbers[j] := numbers[j-1];
j := j - 1;
End;
numbers[j] := index;
End;
End.

Imo, the name index may be somewhat misleading. In this context I would have called it currentValue or something like that. That said:
Imagine an numbers -> [5, 3, 7, 2, 9, 1, 8, 4]
The algorithm start at 2 so:
i == 2; currentValue := numbers[i] (== 7)
Now the algorithm move all values located in indices (j) < i as long as j > 1 with a value < 7 one place up:
numbers[1] == 3 < 7 -> numbers[2] = 3
numbers[0] == 5 < 7 -> numbers[1] = 5
and finally write currentValue into numbers[0]. So the result after first pass would be
[7, 5, 3, 2, 9, 1, 8, 4]
Second pass (2 is smaller than any thing in the places before, so nothing happens):
[7, 5, 3, 2, 9, 1, 8, 4]
Third pass (9 is largest element in numbers[0] to numbers[4]):
[9, 7, 5, 3, 2, 1, 8, 4]
and so on ...

Related

Sorting a subsequence of an array without an additional array

I'm new to programming. I start to learn Ruby freshly and I can't understand how to implement an algorithm for permuting negative(or positive) elements of an array without using an additional array.
For example:
Like this: [-10, 3, -1, 0, -9 ] -> [-10, 3, -9, 0, -1 ] (sort only negatives)
Either that: [-5, 5, -8, 2, 1] -> [-5, 1, -8, 2, 5] (sort only positives)
def sort_positives(arr)
(arr.size-1).times do |i|
next if arr[i] <= 0
smallest = i
(i+1..arr.size-1).each do |j|
smallest = j if arr[j] > 0 && arr[j] < arr[smallest]
end
if smallest > i
tmp = arr[i]
arr[i] = arr[smallest]
arr[smallest] = tmp
end
end
arr
end
arr = [-2, 5, 3, -4, 6, 1, -3]
sort_positives arr
#=> [-2, 1, 3, -4, 5, 6, -3]
arr
#=> [-2, 1, 3, -4, 5, 6, -3]
sort_negatives is a straightforward modification to sort_positives.
def swap(arr, i, j)
arr[i] = arr[i] ^ arr[j]
arr[j] = arr[j] ^ arr[i]
arr[i] = arr[j] ^ arr[i]
end
def sort_negative(arr)
size = arr.size
i = 0
while i < size - 1
next if arr[i] > 0 # first index of negative number
next_neg = 0
min_neg = i
(i + 1).upto(size - 1) do |j|
if arr[i] < 0 && arr[j] < 0
next_neg = j if next_neg == 0
min_neg = j if arr[min_neg] > arr[j]
end
end
swap(arr, i, min_neg) if min_neg > i
if next_neg > 0
i = next_neg # jump to next negative number
else
break
end
end
end
arr = [-10, 0, 2, 6, 10, -1, 7, 20, 1, 0, -9, 13, 6, 88, -11, -156]
sort_negative(arr)
puts arr.inspect # [-156, 0, 2, 6, 10, -11, 7, 20, 1, 0, -10, 13, 6, 88, -9, -1]

How to get exchange by coins with two denominations?

Develop a method change(amount) that for any integer amount in the range from 24 to 1000 returns a list consisting of numbers 5 and 7 only, such that their sum is equal to amount. For example, change(28) may return [7, 7, 7, 7], while change(49) may return [7, 7, 7, 7, 7, 7, 7] or [5, 5, 5, 5, 5, 5, 5, 7, 7] or [7, 5, 5, 5, 5, 5, 5, 5, 7].
I have written something like this. But it isn't working right.
enter code here
def change (amount):
assert (amount >=24)
if amount == 24:
return [5, 5, 7, 7]
if amount == 29:
return [5, 5, 5, 7, 7]
if amount == 40:
return [5, 5, 5, 5, 5, 5, 5, 5]
coins = change(amount - 5)
coins.append(5)
return coins
for coins in range(24, 1000):
print(coins)
Actually, you should find two numbers:
the number of coins with value 7 (let it be countA) and
the number of coins with value 5 (let it be countB)
As you can see 0 <= countA <= sum/7. Then sum - countA * 7 should be divided by 5 without remainder.
So, the simple implementation in java can be like this:
import java.util.Collections;
// ...
public List<Integer> getExchange(int sum)
{
int coinA = 7;
int coinB = 5;
int maxCountOfCoinA = sum / coinA;
int countA = 0;
int countB = 0;
for (int count = 0; count <= maxCountOfCoinA; count++)
{
int remains = sum - count * coinA;
if (remains % coinB == 0)
{
countA = count;
countB = remains / coinB;
break;
}
}
List<Integer> result = new ArrayList<>();
result.addAll(Collections.nCopies(countA, coinA));
result.addAll(Collections.nCopies(countB, coinB));
return result;
}

What is the best approach to solve this problem?

If an array contained [1, 10, 3, 5, 2, 7] and k = 2, combine the set as {110, 35, 27}, sort the set {27, 35, 110} and split the set into array as [2, 7, 3, 5, 1, 10]
Here is a way to implement this in JavaScript:
const k = 2;
const arr = [1, 10, 3, 5, 2, 7];
// STEP 1 - Combine the set by k pair number
const setCombined = []
for(let i = 0; i < arr.length; ++i) {
if(i % k === 0) {
setCombined.push(parseInt(arr.slice(i, i + k ).join('')))
}
}
console.log('STEP1 - combined: \n', setCombined);
// STEP 2 - Sort
const sortedArray = setCombined.sort((a, b) => a - b)
console.log('STEP2 - sorted: \n', sortedArray);
// STEP 3 - Split sorted
const splitArray = sortedArray.join('').split('').map(e => parseInt(e))
console.log('STEP3 - split: \n', splitArray);
I was not sure though when you said to combine set, if you really ment to keep only unique values or not... Let me know

Generating integer partition by its number

I'm trying to generate decent partition of given integer number N numbered K in lexicographical order, e.g. for N = 5, K = 3 we got:
5 = 1 + 1 + 1 + 1 + 1
5 = 1 + 1 + 1 + 2
5 = 1 + 1 + 3
5 = 1 + 2 + 2
5 = 1 + 4
5 = 2 + 3
5 = 5
And the third one is 1 + 1 + 3.
How can I generate this without generating every partition(in C language, but most of all I need algorithm)?
Going to find maximal number in partition(assuming we can find number of partitions d[i][j], where i is number and j is maximal integer in its partition), then decrease the original number and number we are looking for. So yes, I'm trying to use dynamic programming. Still working on code.
This doesn't work at all:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *F1, *F2;
main()
{
long long i, j, p, n, k, l, m[102][102];
short c[102];
F1 = fopen("num2part.in", "r");
F2 = fopen ("num2part.out", "w");
n = 0;
fscanf (F1, "%lld %lld", &n, &k);
p = 0;
m[0][0] = 1;
for ( i = 0; i <= n; i++)
{
for (j = 1; j <= i; j++)
{
m[i][j] = m[i - j][j] + m[i][j - 1];
}
for (j = i + 1; j <= n; j++)
{
m[i][j] = m[i][i];
}
}
l = n;
p = n;
j = n;
while (k > 0)
{
while ( k < m[l][j])
{
if (j == 0)
{
while (l > 0)
{
c[p] = 1;
p--;
l--;
}
break;
}
j--;
}
k -=m[l][j];
c[p] = j + 1;
p--;
l -= c[p + 1];
}
//printing answer here, answer is contained in array from c[p] to c[n]
}
Here is some example Python code that generates the partitions:
cache = {}
def p3(n,val=1):
"""Returns number of ascending partitions of n if all values are >= val"""
if n==0:
return 1 # No choice in partitioning
key = n,val
if key in cache:
return cache[key]
# Choose next value x
r = sum(p3(n-x,x) for x in xrange(val,n+1))
cache[key]=r
return r
def ascending_partition(n,k):
"""Generate the k lexicographically ordered partition of n into integer parts"""
P = []
val = 1 # All values must be greater than this
while n:
# Choose the next number
for x in xrange(val,n+1):
count = p3(n-x,x)
if k >= count:
# Keep trying to find the correct digit
k -= count
elif count: # Check that there are some valid positions with this digit
# This must be the correct digit for this location
P.append(x)
n -= x
val = x
break
return P
n=5
for k in range(p3(n)):
print k,ascending_partition(n,k)
It prints:
0 [1, 1, 1, 1, 1]
1 [1, 1, 1, 2]
2 [1, 1, 3]
3 [1, 2, 2]
4 [1, 4]
5 [2, 3]
6 [5]
This can be used to generate an arbitrary partition without generating all the intermediate ones. For example, there are 9253082936723602 partitions of 300.
print ascending_partition(300,10**15)
prints
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 4, 5, 7, 8, 8, 11, 12, 13, 14, 14, 17, 17, 48, 52]
def _yieldParts(num,lt):
''' It generate a comination set'''
if not num:
yield ()
for i in range(min(num,lt),0,-1):
for parts in _yieldParts(num-i,i):
yield (i,)+parts
def patition(number,kSum,maxIntInTupple):
''' It generates a comination set with sum of kSum is equal to number
maxIntInTupple is for maximum integer can be in tupple'''
for p in _yieldParts(number,maxIntInTupple):
if(len(p) <=kSum):
if(len(p)<kSum):
while len(p) < kSum:
p+=(0,)
print p
patition(40,8,40)
Output:
-------
(40,0,0,0,0,0,0,0)
(39,1,0,0,0,0,0,0)
.
.
.
.

closest to zero [absolute value] sum of consecutive subsequence of a sequence of real values

this is an algorithmic playground for me! I've seen variations of this problem tackling maximum consecutive subsequence but this is another variation as well.
the formal def:
given A[1..n] find i and j so that abs(A[i]+A[i+1]+...+A[j]) is closest to zero among others.
I'm wondering how to get O(n log^2 n), or even O(n log n) solution.
Calculate the cumulative sum.
Sort it.
Find the sequential pair with least difference.
function leastSubsequenceSum(values) {
var n = values.length;
// Store the cumulative sum along with the index.
var sums = [];
sums[0] = { index: 0, sum: 0 };
for (var i = 1; i <= n; i++) {
sums[i] = {
index: i,
sum: sums[i-1].sum + values[i-1]
};
}
// Sort by cumulative sum
sums.sort(function (a, b) {
return a.sum == b.sum ? b.index - a.index : a.sum - b.sum;
});
// Find the sequential pair with the least difference.
var bestI = -1;
var bestDiff = null;
for (var i = 1; i <= n; i++) {
var diff = Math.abs(sums[i-1].sum - sums[i].sum);
if (bestDiff === null || diff < bestDiff) {
bestDiff = diff;
bestI = i;
}
}
// Just to make sure start < stop
var start = sums[bestI-1].index;
var stop = sums[bestI].index;
if (start > stop) {
var tmp = start;
start = stop;
stop = tmp;
}
return [start, stop-1, bestDiff];
}
Examples:
>>> leastSubsequenceSum([10, -5, 3, -4, 11, -4, 12, 20]);
[2, 3, 1]
>>> leastSubsequenceSum([5, 6, -1, -9, -2, 16, 19, 1, -4, 9]);
[0, 4, 1]
>>> leastSubsequenceSum([3, 16, 8, -10, -1, -8, -3, 10, -2, -4]);
[6, 9, 1]
In the first example, [2, 3, 1] means, sum from index 2 to 3 (inclusive), and you get an absolute sum of 1:
[10, -5, 3, -4, 11, -4, 12, 20]
^^^^^

Resources