Failing for specific case - c++

This is for finding the top view of a binary tree. My logic has been line by line traversal of the tree. I have used two maps here, m2 for storing node and horizontal distance, the other(m1) with horizontal distance and node data. It seems to fail for a specific case(I cannot copy the test case here because the test case is too large and is not shown completely) in GFG : Link to question
Here is the partial test case I can get :
1
338
5 4 L 5 4 R 4 8 L 4 -1 N 4 2 L 4 2 R 8 8 L 8 -1 N 2 4 L 2 7 R 2 5 L 2 -1 N 8 9 L 8 3 R 4 9 L 4 -1 N 7 5 L 7 3 R 5 8 L 5 -1 N 9 1 L 9 8 R 3 1 L 3 -1 N 9 10 L 9 10 R 5 5 L 5 -1 N 3 7 L 3 6 R 8 9 L 8 -1 N 1 3 L 1 10 R 8 6 L 8 -1 N 1 7 L 1 10 R 10 4 L 10 -1 N 10 7 L 10 10 R 5 8 L 5 -1 N 7 1 L 7 9 R 6 10 L 6 -1 N 9 3 L 9 10 R 3 10 L 3 -1 N 10 2 L 10 4 R 6 2 L 6 -1 N 7 7 L 7 7 R 10 3 L 10 -1 N 4 5 L 4 3 R 7 1 L 7 -1 N 10 3 L 10 2 R 8 10 L 8 -1 N 1 2 L 1 1 R 9 10 L 9 -1 N 10 1 L 10 4 R 3 8 L 3 -1 N 10 8 L 10 7 R 10 9 L 10 -1 N 2 4 L 2 7 R 4 2 L 4 -1 N 2 6 L 2 1 R 7 10 L 7 -1 N 7 6 L 7 10 R 3 3 L 3 -1 N 5 8 L 5 5 R 3 9 L 3 -1 N 1 9 L 1 4 R 3 6 L 3 -1 N 2 3 L 2 3 R 10 7 L 10 -1 N 2 4 L 2 7 R 1 7 L 1 -1 N 10 6 L 10 6 R 1 8 L 1 -1 N 4 6 L 4 8 R 8 7 L 8 -1 N 8 9 L 8 1 R 7 4 L 7 -1 N 9 10 L 9 2 R 4 6 L 4 -1 N 7 1 L 7 1 R 2 9 L 2 -1 N 6 4 L 6 2 R 1 6 L 1 -1 N 10 9 L 10 4 R 6 9 L 6 -1 N 10 2 L 10 6 R 3 1 L 3 -1 N 8 2 L 8 8 R 5 1 L 5 -1 N 9 3 L 9 6 R 9 7 L 9 -1 N 4 3 L 4 2 R 6 2 L 6 -1 N 3 10 L 3 .................
Expected Output :
5 3 10 9 10 3 1 9 8 8 4 5 4 2 6 8 3
My Output:
5 3 10 9 10 3 1 9 8 8 4 5 4 2
My Code :
// { Driver Code Starts
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int data;
struct Node *left;
struct Node *right;
Node(int x){
data = x;
left = NULL;
right = NULL;
}
};
void topView(struct Node *root);
int main()
{
int t;cin>>t;
while(t--)
{
int n,i,k;
cin>>n;
i=n;
Node* root=NULL;
queue <Node*> q;
while(i>0)
{
int a,b;
char c;
cin>> a >> b >> c;
if(!root){
root = new Node(a);
q.push(root);
}
Node* pick = q.front();
q.pop();
if(c == 'L'){
pick->left = new Node(b);
q.push( pick->left );
}
cin>> a >> b >> c;
if(c == 'R'){
pick->right = new Node(b);
q.push( pick->right );
}
i-=2;
}
// inorder(root);
// cout<<endl;
topView(root);
cout << endl;
}
return 0;
}
// } Driver Code Ends
//Structure of binary tree
/*struct Node
struct Node
{
int data;
struct Node* left;
struct Node* right;
Node(int x){
data = x;
left = right = NULL;
}
};*/
// function should print the topView of the binary tree
void topView(struct Node *root)
{
if(root==NULL)
return;
queue<Node *> q;
map<Node *,int> m2;
map<int,int> m1;
m1[0]=root->data;
m2[root]=0;
q.push(root);
while(!q.empty())
{
if(q.front()->left)
{
q.push(root->left);
if(m1.find(m2[root]-1)==m1.end())
{
m2[root->left]=m2[root]-1;
m1[m2[root]-1]=root->left->data;
}
}
if(q.front()->right)
{
q.push(root->right);
if(m1.find(m2[root]+1)==m1.end())
{
m2[root->right]=m2[root]+1;
m1[m2[root]+1]=root->right->data;
}
}
q.pop();
root=q.front();
}
for(auto i:m1)
cout<<i.second<<" ";
}

The problem is that you add new members to m2 when the root is seen from the top of the tree:
if(m1.find(m2[root]+1)==m1.end())
{
m2[root->right]=m2[root]+1;
This will not work for a test case like this
1
10
1 2 L 1 5 R 2 -1 N 2 3 R 5 -1 N 5 -1 N 3 -1 N 3 4 R 4 -1 N 4 6 R
which has the following tree:
1
/ \
2 5
\
3
\
4
\
6
The expected output would be
2 1 5 6
but your code will result in
2 1 5
Here, when the root is node 2, node 3 will be added to m2. But when the root node 3, it will not add node 4 to m2 as node 3 cannot be seen from the top and thus not initialize it correctly to position 1.
Afterwards when root is set to node 4 it will look for it in m2. But as that key doesn't exist yet, it will create a new value with the standard constructor of int (0). Because of that your code suggests that node 6 is at position 1 which is overshadowed by node 5 already.
The fix is simple though. Just move the assignments of m2 out of the if-clauses:
m2[root->left]=m2[root]-1;
if(m1.find(m2[root]-1)==m1.end())
{
m1[m2[root]-1]=root->left->data;
}
Same for the right case.

Related

Inaccurate C++ factorial program

I wrote an implementation of the following tutorial: LINK
Basically, since C/C++ does not have BIG Integer we are storing the factorial decimal values in an array. This is equivalent to writing a multiplication that performs the multiplication kids are taught at schools.
Problem: It works fine for values up to 17! after that (18!, 19!,... ) it does not output correct values.
#include <iostream>
using namespace std;
int main(){
int fact[1000]={1};
int n; scanf("%d", &n); //n are the number of factorials we will calculate
while(n--){
int number; scanf("%d", &number); //scan the number
if(number == 0) printf("%d", 1);
int flag = number;
int index = 0, length = 0;
//following lines we find the length of the entered number
while(flag!=0){
fact[index] = flag%10;
flag /= 10;
index++; length++;
}
//following lines are the multiplication code
while(number>1){
index = 0;
int temp = 0;
number--;
for(index = 0; index<length; index++){
int x = (fact[index] * number) + temp;
fact[index] = x%10;
temp = x/10;
}
//here we append the carry over left from multiplication
while(temp){
fact[index] = temp%10;
temp /= 10;
length++;
}
}
//print the array from most to least significant digit
for(int i = length-1; i>=0; i--){
printf("%d", fact[i]);
}
printf("\n");
}
return 0;
}
For a start, you need to be very careful with:
long long int x = (fact[index] * number) + temp;
Since fact[], number and temp are all int types, the calculation will be done as an int and only widened to a long long when placing the value into x.
You would be better off with:
long long x = fact[index];
x *= number;
x += temp;
That way, it becomes a long long early enough that the calculations will be done with that type.
However, that doesn't actually fix your problem, so let's modify your code a little to see where the problem lies:
#include <iostream>
using namespace std;
int main(){
int fact[1000]={1};
int n = 18, numberx = 0;
while(n-- > 0){
int number = ++numberx;
if(number == 0) { printf("%d", 1); continue; }
int flag = number;
int index = 0, length = 0;
//following lines we find the length of the entered number
while(flag!=0){
fact[index] = flag%10;
flag /= 10;
index++; length++;
}
//following lines are the multiplication code
while(number>1){
index = 0;
int temp = 0;
number--;
for(index = 0; index<length; index++){
long long int x = fact[index];
x *= number;
x += temp;
fact[index] = x%10;
temp = x/10;
}
//here we append the carry over left from multiplication
while(temp){
fact[index] = temp%10;
temp /= 10;
length++;
}
}
//print the array from most to least significant digit
printf("%d! = ", number);
for(int i = length-1; i>=0; i--){
printf("%d ", fact[i]);
}
printf("\n");
}
return 0;
}
Running this gives you:
1! = 1
2! = 2
3! = 6
4! = 2 4
5! = 1 2 0
6! = 7 2 0
7! = 5 0 4 0
8! = 4 0 3 2 0
9! = 3 6 2 8 8 0
10! = 3 6 2 8 8 0 0
11! = 3 9 9 1 6 8 0 0
12! = 4 7 9 0 0 1 6 0 0
13! = 6 2 2 7 0 2 0 8 0 0
14! = 8 7 1 7 8 2 9 1 2 0 0
15! = 1 3 0 7 6 7 4 3 6 8 0 0 0
16! = 2 0 9 2 2 7 8 9 8 8 8 0 0 0
17! = 3 5 5 6 8 7 4 2 8 0 9 6 0 0 0
18! = 1 9 9 1 0 4 7 1 7 3 8 5 7 2 8 0 0 0
which is, as you state okay up until 18!, where if fails. And, in fact, you can see the ratio between 17! and 18! is about 500 rather than 18 so that's where we should look.
Let's first strip out the extraneous stuff by starting at 17!. That can be done simply by changing a couple of starting values:
int n = 2, numberx = 16;
and that gives:
17! = 3 5 5 6 8 7 4 2 8 0 9 6 0 0 0
18! = 1 9 9 1 0 4 7 1 7 3 8 5 7 2 8 0 0 0
Then we can add debug code to see what's happening, outputting temporary results along the way. The main loop can become:
while(number>1){
index = 0;
int temp = 0;
number--;
if (numberx > 17) printf("\n");
for(index = 0; index<length; index++){
if (numberx > 17) printf("index %d fact[] %d number %d temp %d", index, fact[index], number, temp);
long long int x = fact[index];
x *= number;
x += temp;
fact[index] = x%10;
temp = x/10;
if (numberx > 17) printf(" -> fact[] %d temp %d\n", fact[index], temp);
}
//here we append the carry over left from multiplication
while(temp){
fact[index] = temp%10;
temp /= 10;
length++;
}
if (numberx > 17) {
printf("temp: ");
for(int i = length-1; i>=0; i--){
printf("%d ", fact[i]);
}
printf("\n");
}
}
This shows you *exactly where things start to go wrong (// bits are added by me):
17! = 3 5 5 6 8 7 4 2 8 0 9 6 0 0 0
index 0 fact[] 8 number 17 temp 0 -> fact[] 6 temp 13
index 1 fact[] 1 number 17 temp 13 -> fact[] 0 temp 3
temp: 3 0 6 // okay: 18 * 17 = 306
index 0 fact[] 6 number 16 temp 0 -> fact[] 6 temp 9
index 1 fact[] 0 number 16 temp 9 -> fact[] 9 temp 0
index 2 fact[] 3 number 16 temp 0 -> fact[] 8 temp 4
temp: 4 8 9 6 // okay 306 * 16 = 4896
index 0 fact[] 6 number 15 temp 0 -> fact[] 0 temp 9
index 1 fact[] 9 number 15 temp 9 -> fact[] 4 temp 14
index 2 fact[] 8 number 15 temp 14 -> fact[] 4 temp 13
index 3 fact[] 4 number 15 temp 13 -> fact[] 3 temp 7
temp: 7 3 4 4 0 // okay 4896 * 15 = 73440
index 0 fact[] 0 number 14 temp 0 -> fact[] 0 temp 0
index 1 fact[] 4 number 14 temp 0 -> fact[] 6 temp 5
index 2 fact[] 4 number 14 temp 5 -> fact[] 1 temp 6
index 3 fact[] 3 number 14 temp 6 -> fact[] 8 temp 4
index 4 fact[] 7 number 14 temp 4 -> fact[] 2 temp 10
temp: 8 1 2 8 1 6 0 // no good: 73440 * 14 = 10128160 !!!
1 0 2 8 1 6 0 // is what it should be
With a bit of thought, it appears to be the point where the final "carry" from the multiplication is greater than nine, meaning it's almost certainly in the code for handling that:
while(temp){
fact[index] = temp%10;
temp /= 10;
length++;
}
Thinking about that (and comparing it to other code that changes index and length together), it becomes obvious - even though you increase the length of the array, you're not increasing the index. That means, for a final carry of ten or more, the subsequent carry will not populate the correct index, it will simply overwrite the same index each time.
This can be seen here:
temp: 8 1 2 8 1 6 0 // no good: 73440 * 14 = 10128160 !!!
1 0 2 8 1 6 0 // is what it should be
where it will have placed the zero (10 % 10) at that second location (increasing the length) but then placed the one (10 / 10) at the same index, leaving the 8 at whatever value it had before.
So, if we increment index as well, what do we see (going back to the less verbose code)?
1! = 1
2! = 2
3! = 6
4! = 2 4
5! = 1 2 0
6! = 7 2 0
7! = 5 0 4 0
8! = 4 0 3 2 0
9! = 3 6 2 8 8 0
10! = 3 6 2 8 8 0 0
11! = 3 9 9 1 6 8 0 0
12! = 4 7 9 0 0 1 6 0 0
13! = 6 2 2 7 0 2 0 8 0 0
14! = 8 7 1 7 8 2 9 1 2 0 0
15! = 1 3 0 7 6 7 4 3 6 8 0 0 0
16! = 2 0 9 2 2 7 8 9 8 8 8 0 0 0
17! = 3 5 5 6 8 7 4 2 8 0 9 6 0 0 0
18! = 6 4 0 2 3 7 3 7 0 5 7 2 8 0 0 0
19! = 1 2 1 6 4 5 1 0 0 4 0 8 8 3 2 0 0 0
20! = 2 4 3 2 9 0 2 0 0 8 1 7 6 6 4 0 0 0 0
That solves your specific problem and hopefully provides some education on debugging as well :-)

Codechef is rejecting my solution

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

Hexagon grid - paths incorrect

I am writing a program that uses a hexagon map (obviously in the output seen below it appears as a square, but the numbers will make sense for a hexagon shape) to generate a path from a certain point. 0 indicates the goal, -2 indicates an off limits section, and any other number indicates a distance from that spot to the goal (0). I've written 6 functions to populate surrounding neighbors. These functions feed into another function that populates the map.. or is supposed to. I find with certain inputs, the map population goes awry on the left portion. I've done a desk check and can't figure out why. Any fresh eyes would help greatly, I've been looking at this for some time:
struct Point {
int r;
int c;
};
Queue <Point> q;
Point getNeighbors1(int r, int c) {
int n1r, n1c;
if (r < (ROW-1) ) {
n1r = r+1;
n1c = c;
Point neighborLoc1;
neighborLoc1.r = n1r;
neighborLoc1.c = n1c;
return neighborLoc1;
}
}
Point getNeighbors2(int r, int c) {
int n2r, n2c;
if (r > 0) {
n2r = r-1;
n2c = c;
Point neighborLoc2;
neighborLoc2.r = n2r;
neighborLoc2.c = n2c;
return neighborLoc2;
}
}
Point g
etNeighbors3(int r, int c) {
int n3r, n3c;
if (c < (COL-1) ) {
n3r = r;
n3c = c+1;
Point neighborLoc3;
neighborLoc3.r = n3r;
neighborLoc3.c = n3c;
return neighborLoc3;
}
}
Point getNeighbors4(int r, int c) {
int n4r, n4c;
if (c > 0) {
n4r = r;
n4c = c-1;
Point neighborLoc4;
neighborLoc4.r = n4r;
neighborLoc4.c = n4c;
return neighborLoc4;
}
}
Point getNeighbors5(int r, int c) {
int n5r, n5c;
if (c % 2 == 0) {
if (r > 0 && c < COL-1 ) {
n5r = r-1;
n5c = c+1;
Point neighborLoc5;
neighborLoc5.r = n5r;
neighborLoc5.c = n5c;
return neighborLoc5;
}
}
else {
if (r < (ROW-1) && c < (COL-1) ) {
n5r = r+1;
n5c = c+1;
Point neighborLoc5;
neighborLoc5.r = n5r;
neighborLoc5.c = n5c;
return neighborLoc5;
}
}
}
Point getNeighbors6(int r, int c) {
int n6r, n6c;
if (c % 2 == 0) {
if (r > 0 && c > 0) {
n6r = r-1;
n6c = c-1;
Point neighborLoc6;
neighborLoc6.r = n6r;
neighborLoc6.c = n6c;
return neighborLoc6;
}
}
else {
if (r < (ROW-1) && c > 0) {
n6r = r+1;
n6c = c-1;
Point neighborLoc6;
neighborLoc6.r = n6r;
neighborLoc6.c = n6c;
return neighborLoc6;
}
}
}
//populate grid
void numberScheme (Queue<Point> pQ, int map[ROW][COL]) {
while (!pQ.isEmpty()) {
Point p = pQ.dequeue();
Point n1 = getNeighbors1(p.r, p.c);
if (map[n1.r][n1.c] == -1) {
map[n1.r][n1.c] = map[p.r][p.c] + 1;
pQ.enqueue(n1);
}
Point n2 = getNeighbors2(p.r, p.c);
if (map[n2.r][n2.c] == -1) {
map[n2.r][n2.c] = map[p.r][p.c] + 1;
pQ.enqueue(n2);
}
Point n3 = getNeighbors3(p.r, p.c);
if (map[n3.r][n3.c] == -1) {
map[n3.r][n3.c] = map[p.r][p.c] + 1;
pQ.enqueue(n3);
}
Point n4 = getNeighbors4(p.r, p.c);
if (map[n4.r][n4.c] == -1) {
map[n4.r][n4.c] = map[p.r][p.c] + 1;
pQ.enqueue(n4);
}
Point n5 = getNeighbors5(p.r, p.c);
if (map[n5.r][n5.c] == -1) {
map[n5.r][n5.c] = map[p.r][p.c] + 1;
pQ.enqueue(n5);
}
Point n6 = getNeighbors6(p.r, p.c);
if (map[n6.r][n6.c] == -1) {
map[n6.r][n6.c] = map[p.r][p.c] + 1;
pQ.enqueue(n6);
}
}
}
some example input: goal is at (12, 12), off limits cell: (1, 19). And I get this mess:
9 9 10 11 12 13 14 14 14 13 13 12 12 12 13 13 14 14 15 15
8 9 10 11 12 13 14 13 13 12 12 11 11 11 12 12 13 13 14 -2
9 10 10 11 12 13 13 12 12 11 11 10 10 10 11 11 12 12 13 13
10 11 11 12 12 12 12 11 11 10 10 9 9 9 10 10 11 11 12 12
11 12 12 12 12 11 11 10 10 9 9 8 8 8 9 9 10 10 11 11
11 11 12 11 11 10 10 9 9 8 8 7 7 7 8 8 9 9 10 10
10 10 11 10 10 9 9 8 8 7 7 6 6 6 7 7 8 8 9 9
9 9 10 9 9 8 8 7 7 6 6 5 5 5 6 6 7 7 8 8
8 9 10 9 8 7 7 6 6 5 5 4 4 4 5 5 6 6 7 7
8 9 10 9 8 7 6 5 5 4 4 3 3 3 4 4 5 5 6 7
8 9 10 9 8 7 6 5 4 3 3 2 2 2 3 3 4 5 6 7
8 9 10 9 8 7 6 5 4 3 2 1 1 1 2 3 4 5 6 7
8 9 10 9 8 7 6 5 4 3 2 1 0 1 2 3 4 5 6 7
8 9 10 9 8 7 6 5 4 3 2 2 1 2 2 3 4 5 6 7
8 9 10 9 8 7 6 5 4 4 3 3 2 3 3 4 4 5 6 7
8 9 10 9 8 7 6 6 5 5 4 4 3 4 4 5 5 6 6 7
9 10 10 9 8 8 7 7 6 6 5 5 4 5 5 6 6 7 7 8
10 10 10 10 9 9 8 8 7 7 6 6 5 6 6 7 7 8 8 9
9 9 10 11 10 10 9 9 8 8 7 7 6 7 7 8 8 9 9 10
8 9 10 11 11 11 10 10 9 9 8 8 7 8 8 9 9 10 10 11
It looks like the way you're calculating directions is off. You would probably do well to name them, instead of getNeighborsx, to getNorthNeighbor, getSouthNeighbor, getNortheastNeighbor, getSouthwestNeighbor, getNorthwestNeighbor, getSoutheastNeighbor, as that would make it easy to identify which functions are doing what and why they might not be behaving as expected.
When I made a hexagonal grid, I defined directions like this:
enum direction {
north, south, northeast, southwest, northwest, southeast
};
And I got relative points from a direction like this:
point point::getRelativePoint(const direction & d) const {
switch (d) {
case north: return point(x + 1, y); //North and south are defined along the X axis, for our purposes
case south: return point(x - 1, y);
case northeast: return point(x, y + 1); //Northeast and Southwest are defined along the Y axis
case southwest: return point(x, y - 1);
case southeast: return point(x - 1, y + 1); //Northwest and Southeast can be defined by adding together other directions: Northwest is North + Southwest, and Southeast is South + Northeast.
case northwest: return point(x + 1, y - 1);
}
}
Your getNeighbors5 and getNeighbors6 functions are what I believe are at fault, because they change direction based on suspect criteria:
Point getNeighbors5(int r, int c) {
int n5r, n5c;
if (c % 2 == 0) {
if (r > 0 && c < COL-1 ) {
n5r = r-1;
n5c = c+1;
Point neighborLoc5;
neighborLoc5.r = n5r;
neighborLoc5.c = n5c;
return neighborLoc5;
}
}
else {
if (r < (ROW-1) && c < (COL-1) ) {
n5r = r+1;
n5c = c+1;
Point neighborLoc5;
neighborLoc5.r = n5r;
neighborLoc5.c = n5c;
return neighborLoc5;
}
}
}
It doesn't make sense that you're changing which direction this is based on which column it's in. SouthEast of a cell (if it's defined as a composite of South and NorthEast) is always going to be -1, +1 of that cell.
I've attached an image of a hexagonal grid, I suggest you use it to work out the positions of these cells. Depending on how you've defined North/NorthEast, you may need to rotate the directions of the Axis' I provided, but it should illuminate where you might have gone wrong.

abnormality in the output of my code

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};

Difference of the two versions of partition used in quicksort

The first one is straightforward, just walk from both sides until finding a reversion.
/*C++ version, [first, last), last needs --first to fetch the last element*/
/*returns the middle of partitioning result*/
int* partition( int *first, int *last, int pivot ) {
while (true) {
while (*first < pivot) ++first;
--last;//Don't edit this, it's true.
while (pivot < *last) --last;
if (!(first < last)) return first;
swap(*first, *last);
++first;
}
}
The second one (shown in "Introduction to algorithms") is:
int* partition( int a[], int n, int pivot ) {
bound = 0;
for ( i = 1; i != n; ++i )
if ( a[i] < pivot )
swap( &a[i], &a[++bound]);
swap(a, a + bound);
return a + bound;
}
The invariant of the second one is " All elements before bound is less than pivot " .
Q: And what is the advantages and disadvantages of the two versions?
I'll give one first, the second one require ++ operation on the iterator( pointer ), so it can be applied to some ForwardIterator like the iterator of a linked list. Other tips?
As far as the basic idea of the two algorithms go, both are correct. They will do the same number of comparisons but the second one will do more swaps than the first.
You can see this by stepping through the algorithms as they partition the array 1 9 2 8 3 7 4 6 5 using 5 as the pivot. When the first algorithm swaps two numbers it never touches either of then again. The second algorithm first swaps 9 and 2, then 9 and 3, and so on, taking multiple swaps to move 9 to its final position.
There are other differences too. If I haven't made any mistakes, this is how the first algorithm partitions the array:
1 9 2 8 3 7 4 6 5
f l
1 9 2 8 3 7 4 6 5 # swap 9,5
f l
1 5 2 8 3 7 4 6 9 # swap 8,4
f l
1 5 2 4 3 7 8 6 9 # return f = 5
l f
This is how the second algorithm partitions the array:
1 9 2 8 3 7 4 6 5 # 1<5, swap 1,1
bi
1 9 2 8 3 7 4 6 5 # 9>5, no swap
bi
1 9 2 8 3 7 4 6 5 # 2<5, swap 9,2
b i
1 2 9 8 3 7 4 6 5 # 8>5, no swap
b i
1 2 9 8 3 7 4 6 5 # 3<5, swap 9,3
b i
1 2 3 8 9 7 4 6 5 # 7>5, no swap
b i
1 2 3 8 9 7 4 6 5 # 4<5, swap 8,4
b i
1 2 3 4 9 7 8 6 5 # 6>5, no swap
b i
1 2 3 4 9 7 8 6 5 # 5=5, exit loop, swap 9,5
b i
1 2 3 4 5 7 8 6 9 # return b = 4
b i
Notice how it makes 5 swaps, compared to just 2 of the other algorithm. It also moves the last item in the array to the middle array. In this case the last item happens to be the pivot so it's the pivot that's moved to the middle, but that's not the general case.