I've been trying to implement quick sort and have been having a lot of problems. I even copied a lot of implementations and accepted answers from the net and they ALL crash on odd sized array/vector if you run it enough times (each time I run I run quick sort against random numbers to be sorted... rather than pretend my code works just cuz it can sort one particular set of numbers).
Here is my code and also prints to help debug the error.
template <typename T>
void quickSortMidPivot(vector<T>&vec, size_t left, size_t right)
{
mcount++;
if(right - left < 1)
return;
//crash all the time
//if(left >= right)
// return;
size_t l = left;
size_t r = right;
T pivot = vec[left + ((right-left)/2)];
cout << endl << "PivotValue:" << pivot << endl;
while (l <= r)
{
while (vec[l] < pivot)
l++;
while (vec[r] > pivot)
r--;
if (l <= r) {
cout << endl << "swap:" << vec[l] << "&" << vec[r] << endl;
std::swap(vec[l], vec[r]);
l++;
r--;
for (int i =left; i<=right; i++)
cout << vec[i] << " ";
}
}
cout << endl << "left:" << left << " r:" << r << endl;
cout << "l:" << l << " right:" << right << endl;
if(left < r)
quickSortMidPivot(vec, left, r);
if(l < right)
quickSortMidPivot(vec, l, right);
}
//in main
quickSortMidPivot(dsVector, 0, dsVector.size() - 1);
mcount is a global just so that I can count number of recursive calls. Help figure out most effective implementation...
Here is some debug info.
When run on even sized vector.
Test values are (PRE-SORTING):
8 4 6 5 2 4 1 2
PivotValue:5
swap:8&2
2 4 6 5 2 4 1 8
swap:6&1
2 4 1 5 2 4 6 8
swap:5&4
2 4 1 4 2 5 6 8
left:0 r:4
l:5 right:7
PivotValue:1
swap:2&1
1 4 2 4 2
left:0 r:0
l:1 right:4
PivotValue:2
swap:4&2
2 2 4 4
swap:2&2
2 2 4 4
left:1 r:1
l:3 right:4
PivotValue:4
swap:4&4
4 4
left:3 r:3
l:4 right:4
PivotValue:6
swap:6&6
5 6 8
left:5 r:5
l:7 right:7
# Recursions:5 0
Data Sorted.
Sorted test values are (POST-SORTING):
1 2 2 4 4 5 6 8
Here is case with odd sized array (9). Works 90% of time.
Test values are (PRE-SORTING):
7 7 5 6 5 8 9 5 8
PivotValue:5
swap:7&5
5 7 5 6 5 8 9 7 8
swap:7&5
5 5 5 6 7 8 9 7 8
swap:5&5
5 5 5 6 7 8 9 7 8
left:0 r:1
l:3 right:8
PivotValue:5
swap:5&5
5 5
left:0 r:0
l:1 right:1
PivotValue:8
swap:8&8
6 7 8 9 7 8
swap:9&7
6 7 8 7 9 8
left:3 r:6
l:7 right:8
PivotValue:7
swap:7&7
6 7 8 7
left:3 r:4
l:5 right:6
PivotValue:6
swap:6&6
6 7
left:3 r:2
l:4 right:4
PivotValue:8
swap:8&7
7 8
left:5 r:5
l:6 right:6
PivotValue:9
swap:9&8
8 9
left:7 r:7
l:8 right:8
# Recursions:7 0
Data Sorted.
Sorted test values are (POST-SORTING):
5 5 5 6 7 7 8 8 9
Here is print output for when odd sized (9) vector input causes crash.
Test values are (PRE-SORTING):
8 3 2 3 9 3 8 1 5
PivotValue:9
swap:9&5
8 3 2 3 5 3 8 1 9
left:0 r:7
l:8 right:8
PivotValue:3
swap:8&1
1 3 2 3 5 3 8 8
swap:3&3
1 3 2 3 5 3 8 8
swap:3&3
1 3 2 3 5 3 8 8
left:0 r:2
l:4 right:7
PivotValue:3
swap:3&2
1 2 3
left:0 r:1
l:2 right:2
PivotValue:1
swap:1&1
1 2
swap:2&0
1 0
swap:3&0
1 0
swap:3&1
1 0
swap:5&0
1 0
swap:3&1
1 0
swap:8&0
1 0
swap:8&0
1 0
swap:9&0
1 0
swap:7274596&0
1 0
swap:666050571&0
1 0
swap:369110150&0
1 0
swap:1&0
1 0
swap:1&0
1 0
swap:110&0
1 0
swap:649273354&0
1 0
swap:134229126&0
1 0
swap:3764640&0
1 0
swap:2293216&0
1 0
swap:8&0
1 0
swap:2&0
1 0
swap:649273354&0
1 0
swap:134229127&0
1 0
swap:3764672&0
1 0
swap:3764608&0
1 0
swap:3&0
1 0
swap:649273354&0
1 0
swap:134229127&0
1 0
swap:3764704&0
1 0
swap:3764640&0
1 0
swap:2&0
1 0
swap:649273354&0
1 0
swap:134229127&0
1 0
swap:3764736&0
1 0
swap:3764672&0
1 0
swap:3&0
1 0
swap:649273354&0
1 0
swap:134229127&0
1 0
swap:3764768&0
1 0
swap:3764704&0
1 0
swap:9&0
1 0
swap:649273354&0
1 0
swap:134229127&0
1 0
swap:3764800&0
1 0
swap:3764736&0
1 0
swap:3&0
1 0
swap:6619252&0
1 0
swap:649273354&0
1 0
swap:134229127&0
1 0
swap:3764832&0
1 0
swap:3764768&0
1 0
swap:8&0
1 0
swap:666050571&0
1 0
swap:402664583&0
1 0
swap:3765152&0
1 0
swap:3764800&0
1 0
swap:1&0
1 0
swap:900931609&0
1 0
swap:268446854&0
1 0
swap:2046&0
1 0
swap:2046&0
1 0
swap:649273354&0
1 0
swap:134229140&0
1 0
swap:2293216&0
1 0
swap:3764832&0
1 0
swap:5&0
1 0
swap:11399&0
1 0
swap:3735896&0
1 0
swap:3735896&0
1 0
swap:548610060&1
1 0
swap:50342980&0
1 0
swap:6356944&-1
1 0
swap:3735800&-2
1 0
swap:3735648&0
1 0
swap:3735648&-1
1 0
swap:3768320&0
1 0
swap:32768&1
1 0
I am newbie on codechef and i was trying to solve the following question however my code runs fine on my machine, i also tested it with some cases.
Question is as follows :-
In Byteland it is always the military officer's main worry to order his soldiers on parade correctly. Luckily, ordering soldiers is not really such a problem. If a platoon consists of n men, all of them have different rank (from 1 - lowest to n - highest) and on parade they should be lined up from left to right in increasing order of rank.
Sounds simple, doesn't it? Well, Sgt Johnny thought the same, until one day he was faced with a new command. He soon discovered that his elite commandos preferred to do the fighting, and leave the thinking to their superiors. So, when at the first rollcall the soldiers lined up in fairly random order it was not because of their lack of discipline, but simply because they couldn't work out how to form a line in correct order of ranks. Sgt Johnny was not at all amused, particularly as he soon found that none of the soldiers even remembered his own rank. Over the years of service every soldier had only learned which of the other soldiers were his superiors. But Sgt Johnny was not a man to give up easily when faced with a true military challenge. After a moment's thought a solution of brilliant simplicity struck him and he issued the following order: "men, starting from the left, one by one, do: (step forward; go left until there is no superior to the left of you; get back in line).". This did indeed get the men sorted in a few minutes. The problem was solved... for the time being.
The next day, the soldiers came in exactly the same order as the day before, and had to be rearranged using the same method. History repeated. After some weeks, Sgt Johnny managed to force each of his soldiers to remember how many men he passed when going left, and thus make the sorting process even faster.
If you know how many positions each man has to walk to the left, can you try to find out what order of ranks the soldiers initially line up in?
Input
The first line of input contains an integer t<=50, the number of test cases. It is followed by t test cases, each consisting of 2 lines. The first line contains a single integer n (1<=n<=200000). The second line contains n space separated integers wi, denoting how far the i-th soldier in line must walk to the left when applying Sgt Johnny's algorithm.
Output
For each test case, output a single line consisting of n space separated integers - the ranks of the soldiers, given from left to right in their initial arrangement.
Example
Input:
2
3
0 1 0
5
0 1 2 0 1
Output:
2 1 3
3 2 1 5 4
Warning: large Input/Output data, be careful with certain languages
#include <iostream>
#include <string.h>
using namespace std;
int main ()
{
int t,n;
cin >> t;
while(t>0){
cin >> n;
int array[n+1];
int stepsmoved,i;
for(i = 1; i <= n; i++){
array[i] = i;
}
for(i = 1; i <=n; i++){
cin >> stepsmoved;
if(stepsmoved == 0){}
else{
int x;
x = array[i];
for (int j = i; j> i- stepsmoved; j--){
array[j] = array[j-1];
}
array[i-stepsmoved] = x;
}
}
for(i = 1; i <= n; i++){
cout<<array[i]<<" ";
}
cout<<endl;
t--;
}
return 0;
}
So is there something logically or syntactically wrong?
The order of 'unwinding' the sorting is relevant.
Here is the code that demonstrates the statement above (the ranks are 1-based, the 1 - is highest, 10 - is lowest, array indices are 0-based):
#include <stdio.h>
void dump(int *a) {
int i;
for (i = 0; i < 10; i++)
printf("%d ", a[i]);
printf("\n");
}
int main() {
int array[10] = {0}, steps[10] = {0};
int i,j;
srand(0);
// Assign ranks in random order
for (i = 0; i < 10;) {
j = rand() % 10;
if (!array[j])
array[j] = ++i;
}
dump(array);
// Sort according to the Sgt Johnny's initial idea
for (i = 1; i < 10; i++) {
for (j = 0; array[j] < array[i]; j++);
if (j < i) {
int k, temp = array[i];
for (k = i; k > j; k--) {
array[k] = array[k-1];
steps[temp-1]++;
}
array[j] = temp;
dump(array);
}
}
printf("Steps:\n");
dump(steps);
printf("\n");
// reconstruct the origina order
#if 1
for (i = 10-1; i >= 0; i--)
#else
for (i = 0; i < 10; i++)
#endif
{
int s = steps[array[i]-1];
for (j = i; s; s--, j++) {
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
dump(array);
}
}
If the reconstruction is done in reverse order, then we get a sequence that matches original:
8 7 5 1 10 4 2 3 9 6
7 8 5 1 10 4 2 3 9 6
5 7 8 1 10 4 2 3 9 6
1 5 7 8 10 4 2 3 9 6
1 4 5 7 8 10 2 3 9 6
1 2 4 5 7 8 10 3 9 6
1 2 3 4 5 7 8 10 9 6
1 2 3 4 5 7 8 9 10 6
1 2 3 4 5 6 7 8 9 10
Steps:
3 5 5 4 2 4 1 0 1 0
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 10 9
1 2 3 4 5 6 7 8 10 9
1 2 3 4 5 6 8 7 10 9
1 2 3 4 5 8 7 10 9 6
1 2 3 4 8 7 5 10 9 6
1 2 3 8 7 5 10 4 9 6
1 2 8 7 5 10 4 3 9 6
1 8 7 5 10 4 2 3 9 6
8 7 5 1 10 4 2 3 9 6
Otherwise, the reconstructed order does not match the original:
8 7 5 1 10 4 2 3 9 6
7 8 5 1 10 4 2 3 9 6
5 7 8 1 10 4 2 3 9 6
1 5 7 8 10 4 2 3 9 6
1 4 5 7 8 10 2 3 9 6
1 2 4 5 7 8 10 3 9 6
1 2 3 4 5 7 8 10 9 6
1 2 3 4 5 7 8 9 10 6
1 2 3 4 5 6 7 8 9 10
Steps:
3 5 5 4 2 4 1 0 1 0
2 3 4 1 5 6 7 8 9 10
2 4 1 5 6 7 3 8 9 10
2 4 5 6 7 1 3 8 9 10
2 4 5 7 1 3 8 6 9 10
2 4 5 7 3 8 6 1 9 10
2 4 5 7 3 8 6 1 9 10
2 4 5 7 3 8 1 9 10 0
2 4 5 7 3 8 1 10 9 0
2 4 5 7 3 8 1 10 0 9
2 4 5 7 3 8 1 10 0 6
I'm trying to read an array in c++, filled with values from 0 to 5, For an unimportant reason, I need to count how many numbers 1, numbers 2, numbers 3, numbers 4 and numbers 5 do stand on the 'iii*DAYS'th position, so when iii = 0 and DAYS is 5, I need to know how many numbers 1, numbers 2, numbers 3, numbers 4 and numbers 5 are located on the 0th, 4th, 9th, 14th position. The code I posted does this quite well, but sometimes, gives a very big unlogical value, -36589245 or 99653256, can somebody tell me why this happens ( it does happen +- one in a hunderd times )
DAYS = 28
NURSES = 33
SHIFTS =5
int calculate_penalty_coverage_offspring(int offspring[NURSES*DAYS])
{
int temporary[DAYS];
int count[DAYS][SHIFTS];
penalty_score_offspring_coverage =0;
for (int ii = 0; ii<DAYS; ii++)
{
int een = 0;
int twee = 0;
int drie = 0;
int vier = 0;
int vijf = 0;
for (int iii = 0; iii<NURSES; iii++)
{
temporary[iii] = offspring[(ii+(iii*DAYS))];
}
for(int a = 0 ; a<DAYS ; a++)
{
if(temporary[a]== 1)
{
een++;
count[ii][0] = een;
}
else if(temporary[a] == 2)
{
twee++;
count[ii][1] = twee;
}
else if(temporary[a]== 3)
{
drie++;
count[ii][2] = drie;
}
else if(temporary[a]== 4)
{
vier++;
count[ii][3] = vier;
}
else if(temporary[a] == 5)
{
vijf++;
count[ii][4] = vijf;
}
}
}
for(int ii = 0; ii<DAYS ; ii++)
{
for (int iii =0 ; iii<SHIFTS ; iii++)
{
cout << count[ii][iii] << '\t';
}
cout << '\n';
}
this is the exeptional output where I talked about, as you can see, there is an onlogical value in the output of -31427696 ... I can't see why the function is working good, except for this one time.
1 2 2 4 4
5 2 2 9 5
9 6 3 5 2
8 3 4 3 8
9 3 3 4 6
5 5 6 8 1
6 8 2 2 5
3 5 8 -31427696 7
5 5 2 5 8
5 7 8 2 3
2 7 1 2 10
5 6 3 5 5
4 4 4 6 7
7 4 6 4 6
6 5 6 4 3
5 3 7 4 6
5 5 6 1 7
5 5 1 6 2
4 6 6 4 5
3 3 4 5 9
6 6 5 4 4
5 5 4 4 5
8 4 4 5 3
5 5 4 7 5
4 8 6 3 3
9 1 5 7 3
3 7 5 2 5
2 6 5 7 5
First you say
int temporary[DAYS];
Where
DAYS = 28
Then you do:
for (int iii = 0; iii<NURSES; iii++)
{
temporary[iii] = offspring[(ii+(iii*DAYS))];
}
Where
NURSES = 33
You're trying to access indices that are out of bounds in temporary.
EDIT: Following our discussion in the comments,
You're additionally not initializing your arrays, specifically count:
int count[DAYS][SHIFTS];
Which you then conditionally fill in (partially) later:
if(temporary[a]== 1)
{
een++;
count[ii][0] = een;
}
// ...
Accesses to count afterwards to indices that were not assigned to will result in the garbage numbers you're seeing. You should probably just default the matrix to all zeros like so:
int count[DAYS][SHIFTS] = {0};
I am handling parquet file format. For example:
a group of data:
1 2 null 3 4 5 6 null 7 8 null null 9 10 11 12 13 14
I got a bit vector to indicate null element:
1 1 0 1 1 1 1 0 1 1 0 0 1 1 1 1 1 1
and only store the non-null element:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
I want to evaluate a predicate: big then 5
I compared non-null element to 5 and got a bit vector:
0 0 0 0 0 1 1 1 1 1 1 1 1 1
I want to got a bit vector for all elements:
0 0 0 0 0 0 1 0 1 1 0 0 1 1 1 1 1 1
the 0 in bold is null elements, should be false.
void IntersectBitVec(vector<int64_t>& bit_vec, vector<int64_t>& sub_bit_vec) {
int data_idx = 0,
int bit_idx = 63;
for (int i = 0; i < bit_vec.size(); ++i) {
for (int j = 63; j >=0; --j) {
if (bit_vec[i] & 0x01 << j) {
if (!(sub_bit_vec[data_idx] & 0x01 << bit_idx)) {
bit_vec[i] &= ~(0x01 << j);
}
if (--bit_idx < 0) {
--data_idx;
bit_idx = 63;
}
}
}
}}
My code is quite ugly, is there anyway to make it fast? Great thanks!
Hi I have a question on an existing algo problem.
Existing problem description: Generate 10-digit number using a phone keypad
1 2 3
4 5 6
7 8 9
0
Though this question has a tag of C++, consider this pseudo-code to express the algorithm (which conveniently happens to be written in ruby.)
# Where the knight can jump to
$m = {
0 => [4,6], 1 => [6,8], 2 => [7,9], 3 => [4,8], 4 => [0,3,9],
5 => [], 6 => [0,1,7], 7 => [2,6], 8 => [1,3], 9 => [2,4]
}
$cache = Hash.new
# return count
def nseq( k, n, e=0 )
e += 1 if k.even?
return 0 if 3 < e
return 1 if n == 1
key = "#{k}:#{n}:#{e}" # for the memoization
return $cache[key] if $cache.has_key? key
# Sum nseq(j,n-1,e) for j in $m[k]
return $cache[key] = $m[k].inject(0) { |sum,j| sum + nseq( j, n-1, e ) }
end
0.upto(9) do |k|
2.upto(8) do |n|
count = nseq(k,n)
puts "k=#{k},n=#{n}: #{count}"
break if count.zero?
end
end
This outputs
k=0,n=2: 2
k=0,n=3: 6
k=0,n=4: 8
k=0,n=5: 16
k=0,n=6: 0
k=1,n=2: 2
k=1,n=3: 5
k=1,n=4: 10
k=1,n=5: 24
k=1,n=6: 32
k=1,n=7: 64
k=1,n=8: 0
k=2,n=2: 2
k=2,n=3: 4
k=2,n=4: 10
k=2,n=5: 16
k=2,n=6: 32
k=2,n=7: 0
k=3,n=2: 2
k=3,n=3: 5
k=3,n=4: 10
k=3,n=5: 24
k=3,n=6: 32
k=3,n=7: 64
k=3,n=8: 0
k=4,n=2: 3
k=4,n=3: 6
k=4,n=4: 14
k=4,n=5: 16
k=4,n=6: 32
k=4,n=7: 0
k=5,n=2: 0
k=6,n=2: 3
k=6,n=3: 6
k=6,n=4: 14
k=6,n=5: 16
k=6,n=6: 32
k=6,n=7: 0
k=7,n=2: 2
k=7,n=3: 5
k=7,n=4: 10
k=7,n=5: 24
k=7,n=6: 32
k=7,n=7: 64
k=7,n=8: 0
k=8,n=2: 2
k=8,n=3: 4
k=8,n=4: 10
k=8,n=5: 16
k=8,n=6: 32
k=8,n=7: 0
k=9,n=2: 2
k=9,n=3: 5
k=9,n=4: 10
k=9,n=5: 24
k=9,n=6: 32
k=9,n=7: 64
k=9,n=8: 0
The result is the number of all n-length sequences starting on key k, which have no more than 3 even digits in them. For example, the last entry is k=9,n=8: 0. This means that all sequences of length 8 starting on key 9 include more than 3 even digits.
EDIT: Here it is translated into C++. It produces identical output as above.
#include<iostream>
#include<map>
using namespace std;
const int MAX_EVENS = 3; // Assume < 8
// Where the knight can jump to
const int jumpto[][3] = { {4,6}, // 0
{6,8}, {7,9}, {4,8}, // 1 2 3
{0,3,9}, {}, {0,1,7}, // 4 5 6
{2,6}, {1,3}, {2,4} }; // 7 8 9
const int jumpto_size[] = { 2, // 0
2, 2, 2, // 1 2 3
3, 0, 3, // 4 5 6
2, 2, 2 }; // 7 8 9
typedef map<unsigned,int> cachetype;
cachetype cache;
int nseq( int k, int n, int e=0 )
{
e += k&1^1; // increment e if k is even.
if( MAX_EVENS < e ) return 0;
if( n <= 1 ) return 1;
unsigned key = (n << 4 | k) << 3 | e; // n is left with 32-7=25 bits
cachetype::const_iterator it = cache.find(key);
if( it != cache.end() ) return it->second;
int sum = 0;
for( int i=0 ; i<jumpto_size[k] ; ++i ) sum += nseq( jumpto[k][i], n-1, e );
return cache[key] = sum;
}
int main()
{
for( int k=0 ; k<=9 ; ++k )
for( int n=2 ; n<=8 ; ++n )
{
int count = nseq(k,n);
cout << "k="<<k<<",n="<<n<<": "<<count<<endl;
if( count == 0 ) break;
}
return 0;
}