Replacing duplicates in a randomized 2 dimensional array - c++

I am having some trouble with my class project, essentially what I want to do is spawn objects randomly which so far is working perfectly, they are spawned from an 2d array that stores X and Z which have been randomly generated within reasonable distance. The issue I am having is objects being placed inside each other due to lack of duplicate detection. I need to go through the 2d array, see if any X and Y co-ords match and randomize any matches found. Sorry if this doesn't make a lot of sense, i'm not too good at explaining things but perhaps you could take a look at my current detection method and give me some tips?
for (int k = 0; k <= NumofShrooms - 1; k++)
{
for (int i = 0; i <= NumofShrooms - 1;)
{
if (k == i)
{
i++;
}
if (SpawnArray[k][2] == SpawnArray[i][2])
{
SpawnArray[k][2] = rand() % 16 + 1;
i = 0;
}
else i++;
}
}

Related

Getting from top left to bottom right element of array using dynamic programming

I'm having a hard time thinking of a way to make a solution for a dynamic programming problem. Basically, I have to get from the top left to bottom right element in a NxN array, being able to move only down or right, but I should move to the bigger element and sum it in a variable (get highest score by moving only right and down). F.e., if I have this matrix:
0 1 1
0 4 2
1 1 1
It should move 0-> 1 -> 4 -> 2 -> 1 and print out 8.
I've read about dynamic optimizing for a long time now and still can't get to solve this. Would appreciate if anybody could help me.
Thanks in advance!
Edit: Thanks #sestus ! I've managed to solve the problem, however the solution is slow and I have to optimize it to perform faster. Here's my solution:
#include <iostream>
#include <algorithm>
using namespace std;
const int MAX = 100;
int arr[MAX][MAX];
int move(int row,int col, int n)
{
if(row >= n || col >= n)
{
return 0;
}
return max(arr[row][col] + move(row + 1, col, n),
arr[row][col] + move(row, col + 1, n));
}
int main()
{
int examples, result;
cin>>examples;
int n;
int results[examples];
for(int k =1; k <= examples; k++)
{
cin >> n;
int s = 0;
int i = 0, j = 0;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
cin>> arr[i][j];
}
}
i = 0, j = 0;
s+=move(i,j, n);
results[k] = s;
}
for(int k = 1; k <= examples; k++)
{
cout<<results[k]<<endl;
}
return 0;
}
(The programs actually has to take all the examples and output the answers for all of them at the end). Mind helping me with the optimizing?
I m not going to paste ready-to-go code here, I ll just give you a high level description of the solution.
So what are your possible choices when deciding where to move? You can move either down or right, adding the value of your current block. Your aim is to maximize the sum of the blocks that you have visited till you make it to the bottom-right block. That gives us:
move(row, column):
//handle the cases when you move out of bounds of the array here
return(max{array[row,column] + move(row + 1, column),
array[row,column] + move(row, column + 1)})
For the above to be a complete dynamic programming solution, you ll need to add some memoization e.g get the values of the problems that you 've already solved without having to compute them again. Check this on stackoverflow for more details : Dynamic programming and memoization: bottom-up vs top-down approaches
So for example, take this board:
Notice the two different routes. We 've arrived to the block[1][2] (the one with value 3 that the red and blue lines end) via two different routes. According to the blue route, we moved down-right-right, while we moved right-right-down via the read. The pseudocode I pasted dictates that we are going to take the blue route first, cause we encounter the recursive call move(row + 1, column) prior to the recursive call move(row, column + 1).
So, when we reach the block[1][2] from the red route, we don't actually need to compute this solution again. We 've already done this, back when we were there via the read route! If we kept this solution in an array (or a map / hash table), we 'd be able to just pick the solution without having to compute it again. That's memoization!
Based on the above, you can utilize a map since you 're using c++:
std::map<std::pair<int, int>, int> cache;
And before doing the recursive call, you ll want to check if the pair exist in the map. If it doesn't you add it in the map. So move becomes:
int move(int row,int col, int n)
{
if(row >= n || col >= n)
{
return 0;
}
pair<int, int> rowplus_column = make_pair(row + 1,col);
pair<int, int> row_columnplus = make_pair(row, col + 1);
int solution_right = 0;
int solution_down = 0;
map<char, int>::iterator it;
it = cache.find(rowplus_column);
if (it == cache.end()) {
solution_down = move(row + 1, col);
cache.insert(rowplus_column, solution_down);
}
else {
solution_down = it->second;
}
it = cache.find(row_columnplus);
if (it == cache.end()) {
solution_right = move(row, col + 1);
cache.insert(row_columnplus, solution_right);
}
else {
solution_right = it->second;
}
return max(arr[row][col] + solution_down,
arr[row][col] + solution_right);
}
I am a little rusty in C++, but hopefully you got the idea:
Before actually computing the solution, check the map for the pair. If that pair exists, you 've already solved that part of the problem, so get your solution from the map and avoid the recursive call.

Cout Vector in Random Coordinates n times

I am trying to cout a vector 12 times in a loop at random coordinates. I have created my vector here:
vector<Item> sV(MAXPILLS, pill);
Currently it only prints one of the vector out. This is my code for the random coordinates of the vector and the attempt at printing 12 of them out. I'd appreaciate it if you could help!
void generatePowerPills(char gr[][SIZEX], Item pill){
for (int i = 0; i < 12; i++)
{
gr[pill.y][pill.x] = pill.symbol;
}
}
void initialiseRandomPillsCoordinates(vector<Item>& sV) {
//pass the vector to the function to give each pill random coordinates
Seed();
for (size_t i(0); i < sV.size(); ++i)
{
sV.at(i).y = Random(SIZEY - 2); //vertical coordinate in range [1..(SIZEY - 2)]
sV.at(i).x = Random(SIZEX - 2); //horizontal coordinate in range [1..(SIZEX - 2)]
}
}
I'd just comment but sadly I can only answer. Anyway, you're iterating here:
for (int i = 0; i < 12; i++)
{
gr[pill.y][pill.x] = pill.symbol;
}
But where are you using "i" inside this loop? It seems it will do the same, 12 times. Unless there's some hidden functionality somewhere inside, if so, shame on me.

How do I express a range of array positions in c++?

How could I express:
From Array[0-9][0-9] print Player
From Array[0-9][10-79] print blankSpace
From Array[10-19[0-29] print blankSpace
From Array[10-19][30-39] print tree1
Etc.
If it's not obvious I'm trying to print a game map where you can control the Player by moving it over "tiles" (Each one is equal to 10x10 of array positions or char spaces if you prefer) but I can't seem to find any way to "select" a range of positions in arrays instead of just two positions.
If I said [0][9] for player example it would print the player character on that one position but seeing as I'm printing in type char. it would only be equal to '!' for example. I'm meant to print a square of '!'s for example which would take up 10x10 chars.
Then using my logic, if I could "select" a range of array positions I could print out a pre-defined array of characters making up my overall character's look using the Player() function. Same for the blankSpaces and tree1 etc.
Any help/criticism/sarcastic banter on my fail logic would be appreciated.
Well, there's no built-in way to work with ranges quite the way you've described it, but there are loops, which come pretty close :-)
for (int j = 0; j != 10; ++j) {
for (int i = 0; i != 10; ++i) {
PrintPlayerAt(j, i);
}
}
It looks like you're going to end up "repainting" a whole rectangular region, though, and making the cursor jump around in (what I'm assuming is a console/command line) window is non-trivial. So I suggest changing your logic away from the object-oriented "print this *here*" to a locality-oriented "when we're here, print this. Some pseudo-code to clarify:
for (int j = 0; j != 20; ++j) {
for (int i = 0; i != 80; ++i) {
if ((0 <= j && j < 10) && (0 <= i && i < 10)) {
PrintPlayer();
}
else if ((10 <= j && j < 20) && (30 <= i && i < 40)) {
PrintTree();
}
// ...
else {
PrintBlankSpace();
}
}
}
Unfortunately there's no built-in way to do this in C++. You can use a nested loop to iterate across the array though.

Alternative to backtracking and to speed up program

I was trying to make a knights tour problem solution and i have just made it. Now i want to improve it.It takes the starting value and then outputs the step by step instructions to move (in command line output).
Now the technique which i have used is that firstly i have divided the board into 4 blocks according to the solution given in a video
(here www.youtube.com%2Fwatch%3Fv%3DdWM5pKYZCHw&b=28) and also divided the whole board into 4 systems of boxes.
In the solution i have to do do lots of backtracking to decide between two different possibilities which greatly reduces the speed.Is there any way to do less or no backtracking to decide between two possibilities. And any other suggestion to improve the technique.
Here is a part of the code (a function which moves the knight across the board)
void move(int l[8][8][2],int g, int e) // g and e are the required systems and blocks respectively
{
backtracking(backtrackarray, l); // calling function to backtrack the array
backtracking(secondbacktrackarray,l); againcalling function to backtrack array in different array
int system = currentsystem(l, currentposition[0], currentposition[1]); //storing the current system
for (int i = 0; i < 3; i++)
{
nextmove(l, currentposition[0], currentposition[1]); //moving knight
}
if (blockshiftpossible(l, system, currentposition[0], currentposition[1])!= 1) // checks if next block shift possible
{
backimage(l, backtrackarray); getting back the stored image
for (int i = 0; i < 3; i++)
{
reversenextmove(l, currentposition[0], currentposition[1]); // moving in the opposite way
}
}
if ((systemshiftpossible(l, currentposition[0], currentposition[1])!= 1) && (g==4) && (e==4)) // checking if system shift is possible
{
backimage(l,secondbacktrackarray); // getting again image from second backtrack array
for (int i = 0; i < 3; i++)
{
reversenextmove(l, currentposition[0], currentposition[1]); // moving in opposite direction
}
if (systemshiftpossible(l, currentposition[0], currentposition[1])!= 1)
{
for (int i = 0; i < 3; i++)
{
nextmove(l, currentposition[0], currentposition[1]);
}
}
}
if ((blockshiftpossible(l, system, currentposition[0], currentposition[1])
== 1) && (g!=4))
{
blockshift(l, currentposition[0], currentposition[1]);
}
else
{
cout << "logical error"<<endl;
}
}
To see the details of this technique check my previous question
Solving knight tour with c++
Also how i can change it to get solutions for n*n puzzles if possible.

Algorithm for smoothing

I wrote this code for smoothing of a curve .
It takes 5 points next to a point and adds them and averages it .
/* Smoothing */
void smoothing(vector<Point2D> &a)
{
//How many neighbours to smooth
int NO_OF_NEIGHBOURS=10;
vector<Point2D> tmp=a;
for(int i=0;i<a.size();i++)
{
if(i+NO_OF_NEIGHBOURS+1<a.size())
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x+=a.at(i+j).x;
a.at(i).y+=a.at(i+j).y;
}
a.at(i).x/=NO_OF_NEIGHBOURS;
a.at(i).y/=NO_OF_NEIGHBOURS;
}
else
{
for(int j=1;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x+=tmp.at(i-j).x;
a.at(i).y+=tmp.at(i-j).y;
}
a.at(i).x/=NO_OF_NEIGHBOURS;
a.at(i).y/=NO_OF_NEIGHBOURS;
}
}
}
But i get very high values for each point, instead of the similar values to the previous point . The shape is maximized a lot , what is going wrong in this algorithm ?
What it looks like you have here is a bass-ackwards implementation of a finite impulse response (FIR) filter that implements a boxcar window function. Thinking about the problem in terms of DSP, you need to filter your incoming vector with NO_OF_NEIGHBOURS equal FIR coefficients that each have a value of 1/NO_OF_NEIGHBOURS. It is normally best to use an established algorithm rather than reinvent the wheel.
Here is a pretty scruffy implementation that I hammered out quickly that filters doubles. You can easily modify this to filter your data type. The demo shows filtering of a few cycles of a rising saw function (0,.25,.5,1) just for demonstration purposes. It compiles, so you can play with it.
#include <iostream>
#include <vector>
using namespace std;
class boxFIR
{
int numCoeffs; //MUST be > 0
vector<double> b; //Filter coefficients
vector<double> m; //Filter memories
public:
boxFIR(int _numCoeffs) :
numCoeffs(_numCoeffs)
{
if (numCoeffs<1)
numCoeffs = 1; //Must be > 0 or bad stuff happens
double val = 1./numCoeffs;
for (int ii=0; ii<numCoeffs; ++ii) {
b.push_back(val);
m.push_back(0.);
}
}
void filter(vector<double> &a)
{
double output;
for (int nn=0; nn<a.size(); ++nn)
{
//Apply smoothing filter to signal
output = 0;
m[0] = a[nn];
for (int ii=0; ii<numCoeffs; ++ii) {
output+=b[ii]*m[ii];
}
//Reshuffle memories
for (int ii = numCoeffs-1; ii!=0; --ii) {
m[ii] = m[ii-1];
}
a[nn] = output;
}
}
};
int main(int argc, const char * argv[])
{
boxFIR box(1); //If this is 1, then no filtering happens, use bigger ints for more smoothing
//Make a rising saw function for demo
vector<double> a;
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
a.push_back(0.); a.push_back(0.25); a.push_back(0.5); a.push_back(0.75); a.push_back(1.);
box.filter(a);
for (int nn=0; nn<a.size(); ++nn)
{
cout << a[nn] << endl;
}
}
Up the number of filter coefficients using this line to see a progressively more smoothed output. With just 1 filter coefficient, there is no smoothing.
boxFIR box(1);
The code is flexible enough that you can even change the window shape if you like. Do this by modifying the coefficients defined in the constructor.
Note: This will give a slightly different output to your implementation as this is a causal filter (only depends on current sample and previous samples). Your implementation is not causal as it looks ahead in time at future samples to make the average, and that is why you need the conditional statements for the situation where you are near the end of your vector. If you want output like what you are attempting to do with your filter using this algorithm, run the your vector through this algorithm in reverse (This works fine so long as the window function is symmetrical). That way you can get similar output without the nasty conditional part of algorithm.
in following block:
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x=a.at(i).x+a.at(i+j).x;
a.at(i).y=a.at(i).y+a.at(i+j).y;
}
for each neighbour you add a.at(i)'s x and y respectively to neighbour values.
i understand correctly, it should be something like this.
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x += a.at(i+j+1).x
a.at(i).y += a.at(i+j+1).y
}
Filtering is good for 'memory' smoothing. This is the reverse pass for the learnvst's answer, to prevent phase distortion:
for (int i = a.size(); i > 0; --i)
{
// Apply smoothing filter to signal
output = 0;
m[m.size() - 1] = a[i - 1];
for (int j = numCoeffs; j > 0; --j)
output += b[j - 1] * m[j - 1];
// Reshuffle memories
for (int j = 0; j != numCoeffs; ++j)
m[j] = m[j + 1];
a[i - 1] = output;
}
More about zero-phase distortion FIR filter in MATLAB: http://www.mathworks.com/help/signal/ref/filtfilt.html
The current-value of the point is used twice: once because you use += and once if y==0. So you are building the sum of eg 6 points but only dividing by 5. This problem is in both the IF and ELSE case. Also: you should check that the vector is long enough otherwise your ELSE-case will read at negative indices.
Following is not a problem in itself but just a thought: Have you considered to use an algorithm that only touches every point twice?: You can store a temporary x-y-value (initialized to be identical to the first point), then as you visit each point you just add the new point in and subtract the very-oldest point if it is further than your NEIGHBOURS back. You keep this "running sum" updated for every point and store this value divided by the NEIGHBOURS-number into the new point.
You make addition with point itself when you need to take neighbor points - just offset index by 1:
for(int j=0;j<NO_OF_NEIGHBOURS;j++)
{
a.at(i).x += a.at(i+j+1).x
a.at(i).y += a.at(i+j+1).y
}
This works fine for me:
for (i = 0; i < lenInput; i++)
{
float x = 0;
for (int j = -neighbours; j <= neighbours; j++)
{
x += input[(i + j <= 0) || (i + j >= lenInput) ? i : i + j];
}
output[i] = x / (neighbours * 2 + 1);
}