program written in dafny, implementing the Merge Sorted Arrays in-Place algorithm - assertion

Here is the program that given to me in dafny:
method Main() {
var a, b := new int[3] [3,5,8], new int[2] [4,7];
print "Before merging the following two sorted arrays:\n";
print a[..];
print "\n";
print b[..];
ghost var AB := multiset(a[..]+b[..]);
assert Sorted(a[..]) && Sorted(b[..]);
MergeSortedArraysInPlace(a, b, AB);
assert multiset(a[..]+b[..]) == AB;
assert Sorted(a[..]+b[..]);
print "\nAfter merging:\n";
print a[..]; // [3,4,5]
print "\n";
print b[..]; // [7,8]
}
predicate Sorted(q: seq<int>)
{
forall i,j :: 0 <= i <= j < |q| ==> q[i] <= q[j]
}
method MergeSortedArraysInPlace(a: array<int>, b: array<int>, ghost AB: multiset<int>)
requires Sorted(a[..]) && Sorted(b[..])
requires multiset(a[..]+b[..]) == AB
requires a != b
ensures Sorted(a[..]+b[..])
ensures multiset(a[..]+b[..]) == AB
modifies a, b
now i need to Implement iteratively, correctly, efficiently and clearly the MergeSortedArraysInPlace method.
Restriction: Merge the arrays in place, using constant additional space only.
so the implementation that i wrote is the following:
method MergeSortedArraysInPlace(a: array<int>, b: array<int>, ghost AB: multiset<int>)
requires Sorted(a[..]) && Sorted(b[..])
requires multiset(a[..]+b[..]) == AB
requires a != b
ensures Sorted(a[..]+b[..])
ensures multiset(a[..]+b[..]) == AB
modifies a, b
{
var i := 0;
var j := 0;
while (i < a.Length && j < b.Length)
decreases a.Length - i, if i < a.Length then b.Length - j else 0 - 1
{
// if a[i] <= b[j] then both array is
// already sorted
if (a[i] <= b[j]) {
i := i + 1;
}
// if a[i]>b[j] then first we swap
// both element so that a[i] become
// smaller means a[] become sorted then
// we check that b[j] is smaller than all
// other element in right side of b[j] if
// b[] is not sorted then we linearly do
// sorting means while adjacent element are
// less than new b[j] we do sorting like
// by changing position of element by
// shifting one position toward left
else if (a[i] > b[j]) {
var t := a[i];
a[i] := b[j];
b[j] := t;
i := i +1;
if (j < b.Length - 1 && b[j + 1] < b[j]) {
var temp := b[j];
var tempj := j + 1;
while (tempj < b.Length && b[tempj] < temp)
decreases b.Length - tempj, if tempj < b.Length then temp - b[tempj] else 0 - 1
invariant 0 <= tempj < b.Length
{
b[tempj - 1] := b[tempj];
tempj := tempj+1;
if(tempj == b.Length){
break;
}
}
b[tempj - 1] := temp;
}
}
}
}
But for some reason I still get "A postcondition might not hold on this return path."
on the following post conditions:
ensures Sorted(a[..]+b\[..])
ensures multiset(a[..]+b\[..]) == AB
I don't know what the problem could be, I would appreciate your help :)

If you need to sort each array in place, you can use an algorithm like Insertion Sort, which can sort an array in place with constant additional space.
Here is an implementation of Insertion Sort that sorts the given arrays a and b in place:
method SortInPlace(a: array<int>)
modifies a
{
var i := 1;
while (i < a.Length)
invariant 1 <= i <= a.Length
decreases a.Length - i
{
var j := i;
while (j > 0 && a[j - 1] > a[j])
invariant 0 <= j < i
decreases j
{
var temp := a[j];
a[j] := a[j - 1];
a[j - 1] := temp;
j := j - 1;
}
i := i + 1;
}
}
method Main() {
var a := new int[3] [3,5,8];
var b := new int[2] [4,7];
print "Before sorting the following two arrays:\n";
print a[..];
print "\n";
print b[..];
SortInPlace(a);
SortInPlace(b);
print "\nAfter sorting in place:\n";
print a[..];
print "\n";
print b[..];
}
In this implementation, the SortInPlace method takes an array a as input and sorts it in place using Insertion Sort. The Main method creates two arrays a and b, prints their contents, sorts them in place using SortInPlace, and then prints their contents again to verify that they are sorted.
Note that if you need to sort multiple arrays, you can simply call the SortInPlace method on each array.

Related

Inaccuracy in code which returns the next permutation of an array

I was solving a question on leetcode with the description:
The next permutation of an array of integers is the next lexicographically greater permutation of its integer. More formally, if all the permutations of the array are sorted in one container according to their lexicographical order, then the next permutation of that array is the permutation that follows it in the sorted container. If such arrangement is not possible, the array must be rearranged as the lowest possible order (i.e., sorted in ascending order).
This is what I came up with in C++:
void nextPermutation(vector<int>& nums) {
int index = -1, j = nums.size() - 1;
for (int i = nums.size() - 1; i > 0; i--)
{
if(nums[i - 1] < nums[i])
{
index = i - 1;
break;
}
}
if(index == -1)
{
reverse(nums.begin(), nums.end());
return;
}
for (int i = nums.size() - 1; i >= index + 1; i--)
{
if(nums[i] > nums[index])
{
j = i;
}
break;
}
swap(nums[index], nums[j]);
reverse(nums.begin() + index + 1, nums.end());
}
Here I traversed the array from left to right and look for an element which is smaller than the element on its right(named it index), and then traversed it again looking for a number just bigger than the number before and swapped them and then reversed the array after index
This code works for the example cases but fails in a case where:
Input: [2,3,1]
MyOutput: [1,2,3]
Expected Output: [3,1,2]
I do not understand what I did wrong and everything should be working but its not.
Your issue is that the break statement in second loop is outside the if block.
if (nums[i] > nums[index])
{
j = i;
}
break; // <--------- this should be inside if
Putting it inside, gives the correct result.
if (nums[i] > nums[index])
{
j = i;
break;
}
Demo: https://godbolt.org/z/147We9c4q

How to invoke lemma in dafny in bubblesort example?

How to invoke lemma as the reasoning for equality to be true. Consider the following example in dafny where I've created a lemma to say that the sum from 0 to n is n choose 2. Dafny seems to have no problem justifying this lemma. I want to use that lemma to say that the number of swaps in bubblesort has an upper bound of the sum from 0 to n which is equivalent to n choose 2. That being the case, I currently have an error when I try to say it's true by the lemma. Why is this happening and how can I say that equality is true given a lemma?
method BubbleSort(a: array?<int>) returns (n: nat)
modifies a
requires a != null
ensures n <= (a.Length * (a.Length - 1))/2
{
var i := a.Length - 1;
n := 0;
while (i > 0)
invariant 0 <= i < a.Length
{
var j := 0;
while (j < i)
invariant j <= i
invariant n <= SumRange(i, a.Length)
{
if(a[j] > a[j+1])
{
a[j], a[j+1] := a[j+1], a[j];
n := n + 1;
}
j := j + 1;
}
i := i -1;
}
assert n <= SumRange(i, a.Length) == (a.Length * (a.Length - 1))/2 by {SumRangeNChoose2(a.Length)};
assert n <= (a.Length * (a.Length - 1))/2
}
function SumRange(lo: int, hi: int): int
decreases hi - lo
{
if lo == hi then hi
else if lo >= hi then 0
else SumRange(lo, hi - 1) + hi
}
lemma SumRangeNChoose2(n: nat)
ensures SumRange(0, n) == (n * (n - 1))/2
{}
You just have a syntax error. There should be no semicolon after the } on the second to last line of BubbleSort. Also, there should be a semicolon after the assertion on the following line.
After you fix the syntax errors, there are several deeper errors in the code about missing invariants, etc. But they can all be fixed using the annotations from my answer to your other question.

How do i reduce the repeadly use of % operator for faster execution in C

This is code -
for (i = 1; i<=1000000 ; i++ ) {
for ( j = 1; j<= 1000000; j++ ) {
for ( k = 1; k<= 1000000; k++ ) {
if (i % j == k && j%k == 0)
count++;
}
}
}
or is it better to reduce any % operation that goes upto million times in any programme ??
edit- i am sorry ,
initialized by 0, let say i = 1 ok!
now, if i reduce the third loop as #darshan's answer then both the first
&& second loop can run upto N times
and also it calculating % , n*n times. ex- 2021 mod 2022 , then 2021 mod 2023..........and so on
so my question is- % modulus is twice (and maybe more) as heavy as compared to +, - so there's any other logic can be implemented here ?? which is alternate for this question. and gives the same answer as this logic will give..
Thank you so much for knowledgeable comments & help-
Question is:
3 integers (A,B,C) is considered to be special if it satisfies the
following properties for a given integer N :
A mod B=C
B mod C=0
1≤A,B,C≤N
I'm so curious if there is any other smartest solution which can greatly reduces time complexity.
A much Efficient code will be the below one , but I think it can be optimized much more.
First of all modulo (%) operator is quite expensive so try to avoid it on a large scale
for(i = 0; i<=1000000 ; i++ )
for( j = 0; j<= 1000000; j++ )
{
a = i%j;
for( k = 0; k <= j; k++ )
if (a == k && j%k == 0)
count++;
}
We placed a = i%j in second loop because there is no need for it to be calculated every time k changes as it is independent of k and for the condition j%k == 0 to be true , k should be <= j hence change looping restrictions
First of all, your code has undefined behavior due to division by zero: when k is zero then j%k is undefined, so I assume that all your loops should start with 1 and not 0.
Usually the % and the / operators are much slower to execute than any other operation. It is possible to get rid of most invocations of the % operators in your code by several simple steps.
First, look at the if line:
if (i % j == k && j%k == 0)
The i % j == k has a very strict constrain over k which plays into your hands. It means that it is pointless to iterate k at all, since there is only one value of k that passes this condition.
for (i = 1; i<=1000000 ; i++ ) {
for ( j = 1; j<= 1000000; j++ ) {
k = i % j;
// Constrain k to the range of the original loop.
if (k <= 1000000 && k > 0 && j%k == 0)
count++;
}
}
To get rid of "i % j" switch the loop. This change is possible since this code is affected only by which combinations of i,j are tested, not in the order in which they are introduced.
for ( j = 1; j<= 1000000; j++ ) {
for (i = 1; i<=1000000 ; i++ ) {
k = i % j;
// Constrain k to the range of the original loop.
if (k <= 1000000 && k > 0 && j%k == 0)
count++;
}
}
Here it is easy to observe how k behaves, and use that in order to iterate on k directly without iterating on i and so getting rid of i%j. k iterates from 1 to j-1 and then does it again and again. So all we have to do is to iterate over k directly in the loop of i. Note that i%j for j == 1 is always 0, and since k==0 does not pass the condition of the if we can safely start with j=2, skipping 1:
for ( j = 2; j<= 1000000; j++ ) {
for (i = 1, k=1; i<=1000000 ; i++, k++ ) {
if (k == j)
k = 0;
// Constrain k to the range of the original loop.
if (k <= 1000000 && k > 0 && j%k == 0)
count++;
}
}
This is still a waste to run j%k repeatedly for the same values of j,k (remember that k repeats several times in the inner loop). For example, for j=3 the values of i and k go {1,1}, {2,2}, {3,0}, {4,1}, {5,2},{6,0},..., {n*3, 0}, {n*3+1, 1}, {n*3+2, 2},... (for any value of n in the range 0 < n <= (1000000-2)/3).
The values beyond n= floor((1000000-2)/3)== 333332 are tricky - let's have a look. For this value of n, i=333332*3=999996 and k=0, so the last iteration of {i,k}: {n*3,0},{n*3+1,1},{n*3+2, 2} becomes {999996, 0}, {999997, 1}, {999998, 2}. You don't really need to iterate over all these values of n since each of them does exactly the same thing. All you have to do is to run it only once and multiply by the number of valid n values (which is 999996+1 in this case - adding 1 to include n=0).
Since that did not cover all elements, you need to continue the remainder of the values: {999999, 0}, {1000000, 1}. Notice that unlike other iterations, there is no third value, since it would set i out-of-range.
for (int j = 2; j<= 1000000; j++ ) {
if (j % 1000 == 0) std::cout << std::setprecision(2) << (double)j*100/1000000 << "% \r" << std::flush;
int innerCount = 0;
for (int k=1; k<j ; k++ ) {
if (j%k == 0)
innerCount++;
}
int innerLoopRepeats = 1000000/j;
count += innerCount * innerLoopRepeats;
// complete the remainder:
for (int k=1, i= j * innerLoopRepeats+1; i <= 1000000 ; k++, i++ ) {
if (j%k == 0)
count++;
}
}
This is still extremely slow, but at least it completes in less than a day.
It is possible to have a further speed up by using an important property of divisibility.
Consider the first inner loop (it's almost the same for the second inner loop),
and notice that it does a lot of redundant work, and does it expensively.
Namely, if j%k==0, it means that k divides j and that there is pairK such that pairK*k==j.
It is trivial to calculate the pair of k: pairK=j/k.
Obviously, for k > sqrt(j) there is pairK < sqrt(j). This implies that any k > sqrt(j) can be extracted simply
by scanning all k < sqrt(j). This feature lets you loop over only a square root of all interesting values of k.
By searching only for sqrt(j) values gives a huge performance boost, and the whole program can finish in seconds.
Here is a view of the second inner loop:
// complete the remainder:
for (int k=1, i= j * innerLoopRepeats+1; i <= 1000000 && k*k <= j; k++, i++ ) {
if (j%k == 0)
{
count++;
int pairI = j * innerLoopRepeats + j / k;
if (pairI != i && pairI <= 1000000) {
count++;
}
}
}
The first inner loop has to go over a similar transformation.
Just reorder indexation and calculate A based on constraints:
void findAllSpecial(int N, void (*f)(int A, int B, int C))
{
// 1 ≤ A,B,C ≤ N
for (int C = 1; C < N; ++C) {
// B mod C = 0
for (int B = C; B < N; B += C) {
// A mod B = C
for (int A = C; A < N; A += B) {
f(A, B, C);
}
}
}
}
No divisions not useless if just for loops and adding operations.
Below is the obvious optimization:
The 3rd loop with 'k' is really not needed as there is already a many to One mapping from (I,j) -> k
What I understand from the code is that you want to calculate the number of (i,j) pairs such that the (i%j) is a factor of j. Is this correct or am I missing something?

Finding a testcase which fails the code in the 4 sum problem

We need to find whether there exists 4 numbers a, b, c and d (all numbers should be at different indices) in an array whose sum equals to a constant k.
Now its hashing based solution goes like this: Make a hash having key as sum of every pair in array and value as array of pairs of indices whose sum is the key. Now iterate over every pair in array and try to find the remaining sum in the hash table we made, while also checking that no 2 indices should be common.
While the above solution is fine, a solution I saw on geeksforgeeks.com did this: In the hash table the value is a pair instead of array of pairs. It only stores the last pair which concludes to a sum. It clearly looks wrong to me but I still can't find a test case where it fails.
Their code:
// A hashing based  CPP program to find if there are 
// four elements with given sum.
#include <bits/stdc++.h>
using namespace std;
// The function finds four elements with given sum X
void findFourElements (int arr[], int n, int X)
{
    // Store sums of all pairs in a hash table
    unordered_map<int, pair<int, int>> mp;
    for (int i = 0; i < n-1; i++)
        for (int j = i+1; j < n; j++)
            mp[arr[i] + arr[j]] = {i, j};   
    // Traverse through all pairs and search
    // for X - (current pair sum).    
    for (int i = 0; i < n-1; i++)
    {
        for (int j = i+1; j < n; j++)
        {
            int sum = arr[i] + arr[j];
  
            // If X - sum is present in hash table,            
            if (mp.find(X - sum) != mp.end())
            {   
                // Making sure that all elements are
                // distinct array elements and an element
                // is not considered more than once.
                pair<int, int> p = mp[X - sum];
                if (p.first != i && p.first != j &&
                        p.second != i && p.second != j)
                {
                    cout << arr[i] << ", " << arr[j] << ", "
                         << arr[p.first] << ", "
                         << arr[p.second];
                    return;
                }
            }
        }
    }
}
  
// Driver program to test above function
int main()
{
    int arr[] = {10, 20, 30, 40, 1, 2};
    int n = sizeof(arr) / sizeof(arr[0]);
    int X = 91;
    findFourElements(arr, n, X);
    return 0;
}
How can I find a testcase where this code fails, or if it is correct, how?
The algorithm is correct. Consider a quadruple (a, b, c, d) which satisfies the following: (1) arr[a] + arr[b] + arr[c] + arr[d] == k; (2) a < b < c < d.
It is obvious that four distinct element of the array sum to k if and only if such quadruple (a, b, c, d) exists.
Now consider the pair (a, b). You have mentioned the program records the last pair (e, f) (e < f) that is a compliment of (a, b) (i.e. arr[a] + arr[b] + arr[e] + arr[f] == k). Note that since (e, f) is the last pair with such property, so e >= c. Therefore a < b < e < f. Now we have found a valid quadruple (a, b, e, f).
Since the second loop traverse through all pairs, the pair (a, b) must have been visited, and the quadruple must have been detected. Therefore the algorithm is correct.
It only stores the last pair which concludes to a sum.
Not quite. It stores all of the pairs, just like you stored all of your arrays of length 2. Their algorithm does that here:
// Store sums of all pairs in a hash table
unordered_map<int, pair<int, int>> mp;
for (int i = 0; i < n-1; i++)
for (int j = i+1; j < n; j++)
mp[arr[i] + arr[j]] = {i, j};
{i, j} is a pair consisting of i as the first value and j as the second.
I think you're confused about what happens here:
pair<int, int> p = mp[X - sum];
if (p.first != i && p.first != j &&
p.second != i && p.second != j)
They're pulling a pair out of the map. Notably, the pair that they're matching with to form the X sum. They could do:
if (mp[X - sum].first != i && mp[X - sum].first != j &&
mp[X - sum].second != i && mp[X - sum].second != j)
But that's both ugly and a lot of map lookups. So instead they decide to copy the pair they're concerned with in a local variable, p.
They then make sure that neither of the indexes in p are those they're looking at now, i and j. Does that make sense?

Minimize the number of consecutive equal extractions in a deque of map<string, string>

I hope this place is the best for this kind of question.
I've the following problem (I think is more complex than it appears).
I'm using a double-ended queue (deque) data structure of strings.
deque < string > extractions;
The deque contains only N different strings, every string repeated for M times in random order, so that the lenght of the deque is N*M, for example, suppose M=4, N=2, string1="A", string2="B":
extractions[1] = "A"
extractions[2] = "A"
extractions[3] = "B"
extractions[4] = "B"
extractions[5] = "A"
extractions[6] = "B"
extractions[7] = "B"
extractions[8] = "A"
I'm in search of an algorithm which allows me to find an interesting configuration in which there aren't two consecutive equal elements, in this case there should be only two solutions, the "A","B","A","B","A","B","A","B" and the "B","A","B","A","B","A","B","A".
For "interesting" configuration I mean the configuration not simply given by a number N of nested loops.
A very stupid solution I've implemented is to randomly shuffle the deck with std::random_shuffle until no occurence of consecutive equal elements is found, but this is both stupid and slow, this is more like a bogosort...
Clearly maximizing the edit distance between the strings should be better.
Some hint?
Start with a trivial configuration, e.g for N=4 an M=4, start from
A B C D A B C D A B C D A B C D
and then run a standard shuffling algorithm but observing the constraint that you do not bring two equal elements next to each others, i.e.
for i = 0 .. N*M - 2
let j = random(N*M - 2 - i) + i + 1
if ((i == 0 || array[i - 1] != array[j])
&& (array[i + 1] != array[j])
&& (array[i] != array[j - 1])
&& (j == N*M - 1 || array[i] != array[j + 1]))
swap (array[i], array[j])
This should leave you very quickly with a random configuration that fulfills your requirement of not having two consecutive equal elements.
int total = m * n;
for (int i = 1; i < total - 1; i++)
{
int j = total - 1;
while ((j > i) && (queue[i - 1] == queue[j]))
j--;
if (queue[i - 1] == queue[j])
{
String aux = queue[i - 1];
queue[i - 1] = queue[j];
queue[j] = aux;
}
}
This code is not tested, but you get the idea.
I would do it with recursion:
example is in C#: I find it more "speaking" than the nested loops:
public List<String> GetPermutations(string s, IEnumerable<String> parts, string lastPart, int targetLength)
{
List<String> possibilities = new List<string>();
if (s.Length >= targetLength)
{
possibilities.Add(s);
return possibilities;
}
foreach (String part in parts)
{
if (!part.Equals(lastPart))
{
possibilities.AddRange(
GetPermutations(s + part, parts, part, targetLength));
}
}
return possibilities;
}
usage:
List<String> parts = new List<String>() { "A", "B", "C"};
int numOccurences = 4;
List<String> results =
GetPermutations("", parts, "", numOccurences * parts.Count );
But if you want just a single possible solution (which is way faster to calculate of course):
it will create you a random, non trivial solution like: CACBCBCABABACAB (for A, B, C)
public String GetRandomValidPermutation(
string s,
List<String> parts,
string lastPart,
int targetLength)
{
if (s.Length >= targetLength)
{
return s;
}
String next = String.Empty;
while(
(next = parts[new Random().Next(0, parts.Count)])
.Equals(lastPart)
){}
return GetRandomValidPermutation(s + next, parts, next, targetLength);
}
call:
String validString =
GetRandomValidPermutation("", parts, "", numOccurences * parts.Count);