Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
#include<iostream>
#include<ctime>
#include<cstdlib>
using namespace std;
int main() {
int arr[5][5] = { 0 };
int x =0, y = 0;
int mx,my;
int cnt = 0;
srand(time(NULL));
while(1) {
bool a = true;
int i = rand() % 8;
if (i == 0) {
mx = -1, my = 0;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 1) {
mx = 1, my = -1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my]++;
x += mx;
y += my;
cnt++;
}
if (i == 2) {
mx = 0, my = -1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 3) {
mx = 1, my = 1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 4) {
mx = 1, my = 0;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 5) {
mx = 1, my = -1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 6) {
mx = 0, my = -1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my] ++;
x += mx;
y += my;
cnt++;
}
if (i == 7) {
mx = -1, my = -1;
if ((x + mx) > 4 || (x + mx) < 0 || (y + my) > 4 || (y + my) < 0) continue;
arr[x + mx][y + my]++;
x += mx;
y += my;
cnt++;
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (arr[i][j] == 0) a = false;
}
}
if (a == true)break;
}
cout << cnt;
return 0;
}
I'm solving a random walk algorithm problem, but I don't know where it is wrong.
When I compile, nothing is displayed on the black screen.
It was lengthened by not using functions, but I think there is nothing wrong with it.
If there are any parts that can cause errors, please explain
thanks for reading this post i'm waiting your answer
The problem lies in the fact that your various if do not explore all the possible movements you can do given you are in a position x, y. For example, if you see what you do at i == 2
if (i == 2) {
mx = 0, my = -1;
or, at i == 6
if (i == 6) {
mx = 0, my = -1;
you do the same thing. In particular: look at this:
- - V
V X V
V V V
You miss the two movements going up and up-left.
I would review the various if movements (that you save in those two variables, mx and my)
As an improvement to your code, I'd choose a random move only between the ones you can really do.. it would be more clean.
Related
I have a square matrix, 40 x 40, and a draw circle function that uses this formula.
I have another function that reads input from a file, the point itself (x0, y0) and the type of circle (0 or 1) and the radius.
void cerc(int x0, int y0, int r, int** matriceHarta, int tip, int n, int m)
{
if (r == 0)
return;
int x, y, xx, rr;
for (rr = r * r, x = -r; x <= r; x++)
for (xx = x * x, y = -r; y <= r; y++)
if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0)
{
if (tip == 0)
matriceHarta[x0 + x][y0 + y] = -5;
else if (tip == 1)
matriceHarta[x0 + x][y0 + y] = -6;
}
}
N and M are the rows and columns, but right now they are both equal.
The matrix is allocated dynamically and is transmitted via the int** matriceHarta parameter.
If I put the point on (39, 39) and I give it the radius 5, the program returns a negative exit code, which I found out is an out of bounds related error. I looked over the for loops and it makes sense that that'd be the error and tried to create the condition if((x0 + x) < n && (y0 + y) < m) to check the bounds, but it still gives the error.
Question is, what am I doing wrong? For contrast, point(37, 4) with radius = 2 is OK, but point(38, 4) with radius = 2 is not OK
This is the attempted fix:
for (rr = r * r, x = -r; x <= r; x++)
for (xx = x * x, y = -r; y <= r; y++)
if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0
&& (((x0+x) < n) && ((y0+y) < m)) )
//^^^^^ this is the condition i was talking about
{
if (tip == 0)
matriceHarta[x0 + x][y0 + y] = -5;
else if (tip == 1)
matriceHarta[x0 + x][y0 + y] = -6;
}
The issue is that you are testing for the out-of-bounds condition after you have already accessed potential out-of-bounds elements.
Let's break it down into separate lines:
if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0
&& // <-- This binds the conditions
(((x0+x) < n) && ((y0+y) < m)))
The line above the && marked with <-- is evaluated before the line below the <--.
In summary, the logical && is always evaluated from left-to-right, where the right side will not be evaluated if the left side evaluates to false (short-circuit boolean evaluation).
Thus the fix is to test the bounds condition first (swap the lines in the code above).
However, to make this a little more clear, you could break up the statement into two if statements:
if (x0+x < n && y0+y < m)
{
if (xx + (y * y) <= rr && matriceHarta[x0 + x][y0 + y] == 0)
{
...
}
}
Given the following code pattern, wherein I am trying to state a vector direction in increments of 45 degrees over the integers int x and int y, inside of a circle positioned at the origin
// x == 0 && y == 0 case is already taken cared of
if(x > 1) {
if(y == 0) {
// horizontal right
m_rotation = 0;
}else if(y < 1) {
// diagonal down right
m_rotation = 315;
} else if(y > 1) {
// diagonal up right
m_rotation = 45;
}
} else if(x == 0) {
if(y < 1) {
// vertical down
m_rotation = 270;
} else if(y > 1) {
// vertical up
m_rotation = 90;
}
} else if(x < 1){
if(y == 0) {
// horizontal left
m_rotation = 180;
}else if(y < 1) {
// diagonal down left
m_rotation = 225;
} else if(y > 1) {
// diagonal up left
m_rotation = 135;
}
}
I am looking for an elegant way to make this compact. I know there's the spaceship operator <=>, but I need to restrict myself to C++17.
Things I have tried
Nesting ternary operators with m_rotation = x > 1? (y < 1? (y == 0? 0: 315): 45): (x == 0? (y < 1? 270: 90): (y < 1? (y == 0? 180: 225): 135));, but this looks weird
I tried putting the x == 0 case inside x < 1 case and transform the later into else, but that does not simplify enough the code
Using absolute values to compare x and y, but I quickly get lost
Nothing else really, I don't know what else to try
Something like
constexpr int rotation[3][3] = {
{225, 180, 135},
{270, 0, 90},
{315, 0, 45},
};
if (x != 0 || y != 0) // if (!(x == 0 && y == 0))
m_rotation = rotation[1 + sign(x)][1 + sign(y)];
There is a closed form:
// standard sign functions
int xs = x < 0 ? -1 : x > 0;
int ys = y < 0 ? -1 : y > 0;
return 180 - 45 * (xs + 2) * ys + 90 * (xs * xs + xs) * (ys * ys - 1);
or shorter
return 180 * (x < 0 || y) - 45 * (xs + 2) * ys;
I have encountered the minimum coin change problem on CodeChef and CodeForces. On both sites I have submitted my implementation using DP. This implementation given TLE error on both sites.
Unfortunately, I cannot find any other implementation of this problem.
I am linking the problems -
CodeChef - https://www.codechef.com/problems/FLOW005
CodeForces - https://codeforces.com/problemset/problem/996/A
Here is my code(CodeChef implementation) -
int main() {
int T{};
std::cin >> T;
for (int i = 1; i <= T; ++i) {
int N{};
std::cin >> N;
std::vector <int> arr(N + 1);
for (int i = 0; i < N + 1; ++i) {
arr[i] = minCoins(i, arr);
}
std::cout << arr[N] << std::endl;
}
return 0;
}
The minCoins Function -
int minCoins(int x, std::vector <int> arr) {
if (x == 0)
return 0;
else if (x == 1 || x == 2 || x == 5 || x == 10 || x == 50 || x == 100)
return 1;
int min{ 1 + arr[x - 1]};
if (x > 100)
min = std::min(min, l + arr[x - 100]);
if (x > 50)
min = std::min(min, 1 + arr[x - 50]);
if (x > 10)
min = std::min(min, 1 + arr[x - 10]);
if (x > 5)
min = std::min(min, 1 + arr[x - 5]);
if (x > 2)
min = std::min(min, 1 + arr[x - 2]);
if (x > 1)
min = std::min(min, 1 + arr[x - 1]);
return min;
}
There is no problem of integer overflow as I chose int data type after reading the constraints.
Also, if anyone would like to suggest how I can remove the if ladder and replace it with something simpler, I would appreciate the help. Also, thank you for taking the time to read my question :)
#include <iostream>
int main() {
int tests;
std::cin >> tests;
int value;
while (tests--) {
int coinCount = 0;
std::cin >> value;
while (value > 0) {
if (value >= 100) {
coinCount += (value / 100);
value %= 100;
} else if (value >= 50) {
coinCount += (value / 50);
value %= 50;
} else if (value >= 10) {
coinCount += (value / 10);
value %= 10;
} else if (value >= 5) {
coinCount += (value / 5);
value %= 5;
} else if (value >= 2) {
coinCount += (value / 2);
value %= 2;
} else if (value >= 1) {
coinCount += (value / 1);
value = 0;
}
}
std::cout << coinCount << '\n';
}
}
Tested on CodeChef and passed with execution time of 0.00. The currency systems shown in the problems are designed in such a way that the greedy choice is the correct choice. This holds true for very nearly if not all existing currency systems.
If you require proof, http://www.cs.toronto.edu/~denisp/csc373/docs/greedy-coin-change.pdf
I am trying to create a maze generator using recursive backtracking and have come across a problem that I just can't get my head around. For some reason my move function is returning the value "18446744073709551615". This is (of course) leading to a segmentation fault. Why is my move function returning such a large value when my move function can only increase or decrease the value by 2?
bool maze::generate(size_t x, size_t y) {
//mark the position as visited
labyrinth.s[y][x] = true;
//print to see progress
//this->print();
//if the position is not out of bounds
if (x < 0 || x > labyrinth.MAXWIDTH - 1 || y < 0 || y > labyrinth.MAXHIGHT - 1) {
//if the position is the endpoint return true
if (labyrinth.v[y][x - 1] == 'W' || labyrinth.v[y][x + 1] == 'W' || labyrinth.v[y - 1][x] == 'W' || labyrinth.v[y + 1][x] == 'W') {
return true;
}
}
//pick a random direction
do {
d = size_t(rand() % 4);
} while(!this->pos_test(x, y, d));
std::cout << x << ' ' << y << std::endl;
if (d == UP) {
y = move(x, y, UP);
}
else if (d == DOWN) {
y = move(x, y, DOWN);
}
else if (d == RIGHT) {
x = move(x, y, RIGHT);
}
else if (d == LEFT) {
x = move(x, y, LEFT);
}
else{
}
std::cout << x << ' ' << y << std::endl;
//recursively generate the maze
if (this->generate(x, y)) {
return true;
}
}
void maze::initialize(size_t x, size_t y) {
//set the maxhight and the maxwidth to y and x
labyrinth.MAXHIGHT = y;
labyrinth.MAXWIDTH = x;
//set all elements in the vector to #
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<char> temp;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp.push_back(labyrinth.wall);
}
labyrinth.v.push_back(temp);
}
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
if (j % 2 == 1 && i % 2 == 1 && j != labyrinth.MAXWIDTH - 1 && j != 0 && i != labyrinth.MAXHIGHT - 1 && i != 0) {
labyrinth.v[j][i] = labyrinth.path;
}
}
}
//set all posistions to unvisited
for (size_t i = 0; i < labyrinth.MAXHIGHT; i++) {
std::vector<bool> temp2;
for (size_t j = 0; j < labyrinth.MAXWIDTH; j++) {
temp2.push_back(false);
}
labyrinth.s.push_back(temp2);
}
//setup the start point
labyrinth.v[0][1] = 'S';
//setup the endpoint
labyrinth.v[labyrinth.MAXHIGHT - 2][labyrinth.MAXWIDTH - 1] = 'W';
}
//if a position has been visited or if not possible to go to return true
bool maze::pos_test(size_t x, size_t y, size_t d) const {
//if the position is out of bounds return false
if (x < 0 || y < 0 || x > labyrinth.MAXWIDTH - 1 || y > labyrinth.MAXHIGHT - 1) {
return true;
}
else if (x == 1 && d == LEFT) {
return true;
}
else if (y == 1 && d == UP) {
return true;
}
else if (x == labyrinth.MAXWIDTH - 1 && d == RIGHT) {
return true;
}
else if (y == labyrinth.MAXHIGHT - 1 && d == DOWN) {
return true;
}
else if (d == UP) {
return labyrinth.s[y - 2][x];
}
else if (d == DOWN) {
return labyrinth.s[y + 2][x];
}
else if (d == RIGHT) {
return labyrinth.s[y][x + 2];
}
else if (d == LEFT) {
return labyrinth.s[y][x - 2];
}
else {
return true;
}
}
size_t maze::move(size_t x, size_t y, size_t d) {
//if the position is out of bounds return without modifying
if (x < 0 || x > labyrinth.MAXWIDTH - 1) {
return x;
}
else if (y < 0 || y > labyrinth.MAXHIGHT - 1) {
return y;
}
else if (d == UP) {
labyrinth.v[y - 1][x] = labyrinth.path;
return y = y - 2;
}
else if (d == DOWN) {
labyrinth.v[y + 1][x] = labyrinth.path;
return y = y + 2;
}
else if (d == RIGHT) {
labyrinth.v[y][x + 1] = labyrinth.path;
return x = x + 2;
}
else if (d == LEFT) {
labyrinth.v[y][x - 1] = labyrinth.path;
return x = x - 2;
}
else {
}
}
You are underflowing your unsigned 64-bit return type size_t.
You are checking whether x and y are below zero, but that's not enough, because 0 and 1 will still be too low because you are subtracting 2!
The number you get is 0xFFFFFFFFFFFFFFFF in hexadecimal. This is the highest possible value for an unsigned 64-bit integer.
It comes from calculating 1 - 2. Yes, this is supposed to be -1, but because your move function doesn't return a signed number but an unsigned one (check the docs on size_t), it can't be negative! Instead, it wraps around to the highest possible number.
You can imagine this in the same way you would get ...99999999999 when you try to calculate 1 - 2 on paper ignoring the "you can't subtract a higher number from a smaller one on paper" rule.
As a side note: I guess the negative result is undesired anyway, because actually your huge number, once added to a pointer, will in turn overflow back into positive, so basically it will work the same is a real -1 in your case and the segmentation fault comes from accessing something right before the beginning of your buffer, not far beyond it, but it comes down to the same thing.
Apart from that, there is no need to do return y = y - 2 and such. Just return y - 2.
I'm very new to C++ and was wondering if if there is a better way of doing this. It's going to run on an Arduino so I can't use ArrayLists or anything.
byte GetFreeCell(short x, short y)
{
byte possibleMoves[4] = {0,0,0,0};
if (y - 2 >= 0 && _grid[y - 2][x] == 0)
possibleMoves[0] = 1;
if (x + 2 < WIDTH && _grid[y][x + 2] == 0)
possibleMoves[1] = 2;
if (y + 2 < HEIGHT && _grid[y + 2][x] == 0)
possibleMoves[2] = 3;
if (x - 2 >= 0 && _grid[y][x - 2] == 0)
possibleMoves[3] = 4;
if (possibleMoves[0] == 0 && possibleMoves[1] == 0 && possibleMoves[2] == 0 && possibleMoves[3] == 0) {
return 0;
}
byte move = 0;
while(move == 0){
move = possibleMoves[random(4)];
}
return move;
}
Thanks,
Joe
byte GetFreeCell(short x, short y)
{
byte possibleMoves[4];
byte index = 0;
if (y - 2 >= 0 && _grid[y - 2][x] == 0)
possibleMoves[index++] = 1;
if (x + 2 < WIDTH && _grid[y][x + 2] == 0)
possibleMoves[index++] = 2;
if (y + 2 < HEIGHT && _grid[y + 2][x] == 0)
possibleMoves[index++] = 3;
if (x - 2 >= 0 && _grid[y][x - 2] == 0)
possibleMoves[index++] = 4;
return index ? possibleMoves[random(index)] : 0;
}
You can do yourself a favor and use this:
https://github.com/maniacbug/StandardCplusplus/#readme
Then you can sanitize your code by using standard containers.
Also, there's no ArrayList in C++. That's Java. With the above library, you can use std::vector instead.