I having a problem using push_back(), I can't figure out why only the first cols vector is just pushed over and over again.
Input
10 9 10 3 100 8 7 10 73 9 10 5 9 87 -1 8 3 7 10 92 6 10 6 83 9 11 8 8 77 -1 10 10 10 10 100 10 10 10 100 10 10 10 10 100 -1 DONE
C++
(...)
size = numbers.size();
counter = 0;
square = ceil(sqrt(size));
vector < vector <int> > rows;
vector<int> cols;
do {
for (int i = 0; i < square; ++i) {
cols.push_back(numbers[counter]);
cout << cols[i] << " ";
++counter;
}
rows.push_back(cols);
cout << endl;
} while (counter <= size);
(...)
Undesirable Output
0: 10 9 10 3 100 8 7
1: 10 9 10 3 100 8 7
2: 10 9 10 3 100 8 7
3: 10 9 10 3 100 8 7
4: 10 9 10 3 100 8 7
5: 10 9 10 3 100 8 7
6: 10 9 10 3 100 8 7
rows[1][2] should be 73, not 9. Where have I gone wrong?
You never reset cols. Instead you just keep adding on to it. I think you are printing rows out with magic number indices, which is why you do not spot the added portion. Either declare a temporary cols inside the loop or call clear after each push_back().
awesomeyi found your main problem. But your code has other issues too.
There is a buffer overflow. For example if size == 4 then square == 2
and we get:
after iter #1: counter == 2; continue since 2 <= 4
after iter #2: counter == 4; continue since 4 <= 4
iter #3: reads numbers[4] and numbers[5] - oops!
The loop condition should be:
while (counter + square <= size);
we need to make sure that the next iteration will complete without overflowing the vector. It would be smart to use .at() for vector access so that if you did make a miscalculation, then the error will behave nicely instead of going screwball.
The loop (minus the output) could actually be written as:
for (size_t counter = 0; counter + square <= size; counter += square )
{
std::vector<int> cols( numbers.begin() + counter, numbers.begin() + counter + square );
rows.push_back(cols);
}
Related
I've often heard that you should never mod the result of your random number generator if you want a uniform distribution. However, I've seen that using a std::uniform_int_distribution makes no difference for significantly small ranges.
Below is an example using both mod and uniform_int_distribution for values 0 - 15:
std::mt19937 gen;
gen.seed(0);
int ROWS = 6;
int COLS = 10;
std::cout << "mod: \n";
for (size_t i = 0; i < ROWS; ++i){
for (size_t j = 0; j < COLS; ++j){
std::cout << std::setw(2) << gen() % 16 << " ";
}
std::cout << "\n";
}
std::cout << "\n";
gen.seed(0);
std::uniform_int_distribution<> distrib(0, 15);
std::cout << "dist: \n";
for (size_t i = 0; i < ROWS; ++i){
for (size_t j = 0; j < COLS; ++j){
std::cout << std::setw(2) << distrib(gen) << " ";
}
std::cout << "\n";
}
results:
mod:
12 15 5 0 3 11 3 7 9 3
5 2 4 7 6 8 8 12 10 1
6 7 7 14 8 1 5 9 13 8
9 4 3 0 3 5 14 15 15 0
2 3 8 1 3 13 3 3 14 7
0 1 9 9 15 0 15 10 4 7
dist:
12 15 5 0 3 11 3 7 9 3
5 2 4 7 6 8 8 12 10 1
6 7 7 14 8 1 5 9 13 8
9 4 3 0 3 5 14 15 15 0
2 3 8 1 3 13 3 3 14 7
0 1 9 9 15 0 15 10 4 7
I guess it has something to do with 2 bytes? I'm just wondering how this is valid mathematically since its stepping through the random number generator and modding results. Does this mean mod creates a uniform distribution if the range is small enough? And why a 2 byte range and not more?
Using the modulo operator will frequently introduce a bias into the returned results when the number of unique values returned by your source of random bits is not a multiple of the divisor.
As a simple example, if your random source returns 4 bits (0-15) and you want values in the range 0-2, using gen() % N you'll get 6 0s, 5 1s, and 5 2s. This biases your results to the low side.
Using multiply-then-divide (gen() * N / RANGE) can still leave an imbalance in the specific number of each result returned, but the imbalance will be spread out evenly among the results which reduces or eliminates the low bias. It also has to contend with overflow in the multiplication. With the previous example, you'll get 5 0s, 6 1s, and 5 0s.
A third alternative would be to check the returned bits to see if the value is among the highest result (that would result in the bias) and regenerate the random bits if this is the case. This introduces a conditional in the code and the time to generate a random number is open ended (rather than fixed).
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 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.
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'm having trouble figuring out the thought process behind grabbing adjacent vertical elements in a grid. Say I have a 5x5 grid:
0 1 2 3 4
5 6 7 8 9
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
I want to find all adjacent horizontal and vertical adjacent elements and place them into an array. The size of the array is given by the possible number of walls between each element (not counting the outside) e.g.
1 | 2 | 3
--- --- ---
4 | 5 | 6
A graph of 2x3 has 7 walls so the array would look like
1 2
2 3
4 5
5 6 //end of horizontal walls
1 4 //beginning of vertical walls
2 5
3 6
now I've figured out how to find all horizontal walls given rows and cols, where walls is the array I will be storing the result in:
//find all horizontal walls in grid
//2-d array to store the element between the wall (0 1) (1 2)
for(int r = 0; r < rows; r++){
for(int c = 0; c < cols-1; c++){
int s = r > 0 ? -1*r : 0; //after first row always write over last space
walls[r*rows+c+s][0] = r*rows+c;
walls[r*rows+c+s][1] = r*rows+c+1;
}
}
but I'm just getting lost on figuring out how to determine all vertical walls, in a grid of 5x5 for example the vertical walls would be
0 5
5 10
10 15
15 20
1 6
6 11
etc...
here's what I'm currently trying:
for(int r = 0; r < rows; r++){
for(int c = 0; c < cols; c++){
//just print the values at the moment, setting walls properly is easy
std::cout << r*rows+c*cols << " " << r*rows+c*cols+5 << std::endl;
}
}
only problem is this does not reset after the first column to 1, instead it continues on like:
0 5
5 10
10 15
15 20
20 25 //nope, should be 1 6
and suggestions? pseudo-code is much appreciated I would prefer an explanation over code
Ok, just figured out the solution so I'll post all I did:
the problem I had was rows did not recent back to 1 when the inner for loop left and started again, this was because I was still multiplying r by rows, this was actually a really simple fix:
r*rows+c*cols << " " << r*rows+c*cols+5 <<
becomes
r+c*cols << " " << r+c*cols+5 <<
I also was running the inner for loop one too many times so, changing
c < cols should become c < cols-1 and now my output is:
0 5
5 10
10 15
15 20
1 6
6 11
11 17
etc...