I have some code for the game of life that takes the users input and displays that input as to which cells they entered as alive, but it always prints a row of four * no matter what. I've messed around with changing things a lot of different ways, but it either still prints the same thing, or doesn't display anything at all. I've done searching around multiple forums and websites, but every code i find is done completely different, which is something i would expect (including code from stackoverflow).
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
using namespace std;
#include <memory.h>
int main ()
{
const long MaxCols (10);
const long MaxRows (10);
const time_t WaitTime (3);
bool Board [MaxRows + 2] [MaxCols + 2];
long CurrCol;
long CurrRow;
time_t StopTime;
long Generation;
long OriginalArray[MaxRows][MaxCols];
long NewArray[MaxRows][MaxCols];
long Neighbors;
do
{
cout << "Enter a row and col for the living cell: ";
cin >> CurrRow >> CurrCol;
} while (CurrRow != 0 && CurrCol != 0);
for (Generation = 1; ; Generation++)
{
//Display the current generation on the board
system("cls");
cout << "\tCurrent Generation: " << Generation << endl;
for (CurrRow = 1; CurrRow <= MaxRows; CurrRow++)
{
for (CurrCol = 1; CurrCol <= MaxCols; CurrCol++)
cout << (Board [CurrRow + 2] [CurrCol + 2] ? ' ' : '*');
cout << endl;
}
//Loop to determine nieghbors
for(CurrRow=1; CurrRow <= MaxRows + 2; CurrRow++)
{
cout << endl;
for (CurrCol = 1; CurrCol <= MaxCols + 2; CurrCol++)
{
if (OriginalArray[CurrRow][CurrCol] == '*')
{
Neighbors = (OriginalArray, CurrRow, CurrCol);
if (Neighbors != 3 || Neighbors != 4 )
NewArray[CurrRow][CurrCol] = ' ';
else
NewArray[CurrRow][CurrCol] = '*';
}
else
{
Neighbors = (OriginalArray, CurrRow, CurrCol);
if (Neighbors != 2 || Neighbors != 3 )
NewArray[CurrRow][CurrCol] = ' ';
else
NewArray[CurrRow][CurrCol] = '*';
}
cout << "Touch any key to halt the program";
StopTime = time(0) + WaitTime; // time(0) gives the number of seconds since Jan 1, 1970
while (time (0) < StopTime) // keep looping until the current time catches the stop time
if (_kbhit()) //true if the user has hit a key, false if not hit a key
{
cout << "\nBye" << endl;
exit(0);
}
else;
}
}
}
}
Messing around is no way to debug a program. When it doesn't behave as you expect your first step should be to try to understand why. By making what, at your level of experience, will basically be random changes to your code you will just make things worse. As Oli mentioned a debugger is the best tool for this. You should learn how to use yours.
Looking at the code there are probably lots of errors but one error jumps out at me which is this
Neighbors = (OriginalArray, CurrRow, CurrCol);
I've no idea why you think this will count the number of neighbours but trust me it doesn't. I suppose you took a guess and then when the compiler didn't complain you assumed the guess was right. I'm afraid not.
So that's the bit to concentrate on first. You need some new code to count the number of live neighbours. Have a think about that.
There's no code above to enter values into Board. Here some code to do that. It's correct as far as it goes, but that doesn't mean it will work with the rest of your code which needs a lot of work.
// baord uses false for dead cells and true for living cells
bool Board [MaxRows + 2] [MaxCols + 2];
// initially make the whole board dead
for (int i = 0; i < MaxRows + 2; ++i)
for (int j = 0; j < MaxCols + 2; ++j)
Baord[i][j] = false;
// now ask the user for some live cells
for (;;)
{
cout << "Enter a row and col for the living cell (0 0 to quit): ";
int i, j;
cin >> i >> j;
if (i == 0 && j == 0)
break; // user entered 0 0 so quit loop
Board[i][j] = true; // set position i,j to live
}
The two parts that were missing from your code were initially setting the whole Board to dead, and secondly once you have got the coordinates for a live cell from the user you did nothing to set that cell to live.
One other thing that's confusing me about your code is that you have different size boards
bool Board [MaxRows + 2] [MaxCols + 2];
long OriginalArray[MaxRows][MaxCols];
long NewArray[MaxRows][MaxCols];
Why does Board have + 2 and the others don't. That makes no sense to me.
Related
Could anyone point the flaw in the code?
The idea that I used is backtracking with recurrence and I would like to stick to this way of sloving the given problem. When the variable moves is <= 60 couple of answers are printed instantly though the program is still running. If moves = 61,62 it takes couple of minutes to print some solutions and if moves = 63 no solution is printed within 15 mins in both cases the program is still running.
Here is the code:
//checking on which move was the square visited
int board[8][8] = {{1,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0}};
int x = 0;//x and y coordinate of the knight's placement
int y = 0;
//move knight by
int move_to[8][8] = {{1,2},{-1,-2},{-1,2},{1,-2},{2,1},{-2,-1},{-2,1},{2,-1}};
//how many moves have been done
int moves = 0;
void solve()
{
//printing one solution
if(moves==63)
{
for(int k = 0; k < 8; k++)
{
for(int n = 0; n < 8; n++)
cout << setw(2) << board[k][n] << " ";
cout << "\n";
}
cout << "--------------------\n";
return;
}
else
{
for(int i = 0; i < 8; i++)
{
//checking if knight is not leaving the board
if(x+move_to[i][0]<0 || x+move_to[i][0]>7 || y+move_to[i][1]<0 ||
y+move_to[i][1]>7 || board[x+move_to[i][0]][y+move_to[i][1]]>0)
continue;
//moving theknight
x+=move_to[i][0];
y+=move_to[i][1];
//increasing the moves count
moves++;
//marking the square to be visited
board[x][y] = moves+1;
//backtracking
solve();
board[x][y] = 0;
x-=move_to[i][0];
y-=move_to[i][1];
moves--;
}
}
}
int main()
{
solve();
return 0;
}
I remember this problem from study. I do not fix them but I change initial position then the first path is found faster (that is how I passed this lab ;P). It is normal because
the number of path is too big.
But you can:
choose from move_to in random order
use multiple threads
Other hand you can read about "Constraint Programming"
So I am currently working on a project to place N queens on an NxN board and prevent them from attacking each other. This project is for an intro level AI course. It has a few specific criteria to get full points which are, finding up to 3 solutions for any board size up to N = 100 in 5 seconds or less. I'm currently trying to make this a constraint satisfaction problem by choosing the most constrained row which if I understand it correctly will prevent rows that are closer to fully attacked from getting there.
Initially the user will input a column number and a queen will be placed in that column on the first row of the board. From there the attack board will be updated using that row column combination by increasing the value of all diagonals and the row and column a small example of the former and the latter below
void main()
{
int size, row, col;
row = 1;
cout << "Enter the board size: ";
cin >> size;
cout << "Enter column of first queen: ";
cin >> col;
cols[row] = col; // cols store the column value of each queen in that particular row.
updateAttack(row, col, +1, size);
findNextQueen(size);
// return here if we found all the solution
//cout << solutionCount << " solutions found. see NQueen.out.\n";
cout << solutionCount << " solutions found. see NQueen.out.\n";
fout.close();
system("pause");
}
void updateAttack(int r, int c, int change, int size) // Updates the attack board given the location a queen being placed
{
int r1, c1;
// update diagnals
for (r1 = r - 1, c1 = c - 1; r1 >= 1 && c1 >= 1; r1--, c1--)
attack[r1][c1] += change;
for (r1 = r + 1, c1 = c + 1; r1 <= size && c1 <= size; r1++, c1++)
attack[r1][c1] += change;
for (r1 = r - 1, c1 = c + 1; r1 >= 1 && c1 <= size; r1--, c1++)
attack[r1][c1] += change;
for (r1 = r + 1, c1 = c - 1; r1 <= size && c1 >= 1; r1++, c1--)
attack[r1][c1] += change;
// update columns
for (r1 = 1, c1 = c; r1 <= size; r1++) // k goes to each row
attack[r1][c1] += change;
}
The main issue with this program is choosing which row to place the queen in. In a simple backtracking method with recursive calls of the queen placing you increment down the rows and place the queen in the first space in that row that isn't currently under attack and then doing the same for the next row and the next queen until the queen cannot be placed, in which case you backtrack and attempt to fix the previous queen by moving it to the next spot. An example of this being done with backtracking and no CSP implemented below.
void findNextQueen(int r, int size)
{
for (int c=1;c<=size;c++)
{
if (attack[r][c]==0) // not under attack
{
cols[r]=c; // assign another queen
if (r<size)
{
updateAttack(r,c,+1, size);
findNextQueen(r+1, size);
updateAttack(r,c, -1, size);
}
else
{
print1solution(size);
if (solutionCount >= 3)
{
cout << solutionCount << " solutions found. see NQueen.out.\n";
system("pause");
exit(0);
}
}
}
}
return;
}
The constraint satisfaction attempts to solve a problem caused during this backtracking where you might later on completely fill rows below with attack values which will cause alot of backtracking to be required increasing the time it takes by alot of time. It does this by attempting to choose rows that have more spaces being attacked first in order to prevent them from being lost and requiring the late backtracking. My example of this that is causing the issues, currently that it always seems to come to 0 solutions possible below.
void findNextQueen(int size)
{
int bestRowCount = 0;
int bestRow = 2;
for (int r = 2; r <= size; r++) // Meant to find the most constrained row and use that as my r value for attack array
{
int aRowCount = 0; // Count of attacks in current row
for (int c = 1; c <= size; c++)
{
if (attack[r][c] >= 1)
{
aRowCount++;
}
}
if ((aRowCount > bestRowCount) && (aRowCount != size))
{
bestRowCount = aRowCount;
bestRow = r;
}
}
for (int c = 1; c <= size; c++)
{
if (attack[bestRow][c] == 0) // not under attack
{
cols[bestRow] = c; // assign another queen
if (queensLeft(size) == 1) // returns true if there are rows that still lack a queen
{
updateAttack(bestRow, c, +1, size);
findNextQueen(size);
cols[bestRow] = 0;
updateAttack(bestRow, c, -1, size);
}
else
{
print1solution(size);
if (solutionCount >= 3)
{
cout << solutionCount << " solutions found. see NQueen.out.\n";
system("pause");
exit(0);
}
}
}
}
return;
}
The very similar problem was introduced in LeetCode:
https://leetcode.com/problems/n-queens-ii
You can go to discussions and find explanation with code solutions.
You will need to modify code to return possible results when you reach your limit.
I think my code has an infinite loop. Can someone tell me where I went wrong?
The code is supposed to find the number of valid numbers, with a valid number being a number without a digit repeating. For example, 1212 would be a non-valid number because 1 and 2 repeated.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
int a; int b; int count_validNums = 1; int digit; int last_digit; bool is_valid = true;
vector <int> num_list;
cout << "Enter numbers 0 < a <= b < = 10000: ";
cin >> a >> b;
// Checks for invalid input
if (a < 0 || b < 0 || a > 10000 || b > 10000) {
cout << "Invalid input";
return 1;
}
// Checks every number from the range [a,b]
for (int i = a; i <= b; i++){
last_digit = i % 10;
num_list.push_back(last_digit);
i = i / 10;
while (i != 0){
digit = i % 10;
if (find(num_list.begin(), num_list.end(), digit) != num_list.end()){
is_valid = false;
}
num_list.push_back(digit);
i = i / 10;
}
if (is_valid) count_validNums++;
}
cout << "They are " << count_validNums << " valid numbers between" << a << " and " << b << endl;
}
The inner while loop terminates when i == 0. Then the outer for loop increments it (so i == 1), then the inner loop reduces it to zero again. Then the other loop increments it, then ...
What is happening to cause the infinite loop is that you are constantly reducing the int i back down to 0. Consider these highlights:
`for(int i = a; i <= b; i++){
//stuff
while(i != 0){ //<--this forces i down to 0
//more stuff
i = i / 10;
}
//final stuff
}`
i here is all one variable, so any changes you make to it anywhere will affect it everywhere else it exists! Instead, you can try saying something like int temp = i; and then perform your operations on temp so that i remains independent, but because your for-loop terminates when i <= b and you are constantly resetting i to 0, it will never reach b.
Also, I noticed that in your check for valid numbers you verify that 0 < a,b < 10000, but later in your for-loop you seem to make the assumption that a <= b will be true. Unfortunately, your test does not ensure this, so the for-loop will immediately terminate for inputs where b < a is true (which your program currently allows) and your program will report answers that are likely incorrect. The same is true when I enter letters as input instead of numbers. You might want to revisit that portion of code.
First of all, sorry for the mis-worded title. I couldn't imagine a better way to put it.
The problem I'm facing is as follows: In a part of my program, the program counts occurences of different a-zA-Z letters and then tells how many of each letters can be found in an array. The problem, however, is this:
If I have an array that consists of A;A;F;A;D or anything similar, the output will be this:
A - 3
A - 3
F - 1
A - 3
D - 1
But I am required to make it like this:
A - 3
F - 1
D - 1
I could solve the problem easily, however I can't use an additional array to check what values have been already echoed. I know why it happens, but I don't know a way to solve it without using an additional array.
This is the code snippet (the array simply consists of characters, not worthy of adding it to the snippet):
n is the size of array the user is asked to choose at the start of the program (not included in the snippet).
initburts is the current array member ID that is being compared against all other values.
burts is the counter that is being reset after the loop is done checking a letter and moves onto the next one.
do {
for (i = 0; i < n; i++) {
if (array[initburts] == array[i]) {
burts++;
}
}
cout << "\n\n" << array[initburts] << " - " << burts;
initburts++;
burts = 0;
if (initburts == n) {
isDone = true;
}
}
while (isDone == false);
Do your counting first, then loop over your counts printing the results.
std::map<decltype(array[0]), std::size_t> counts;
std::for_each(std::begin(array), std::end(array), [&counts](auto& item){ ++counts[item]; });
std::for_each(std::begin(counts), std::end(counts), [](auto& pair) { std::cout << "\n\n" << pair.first << " - " pair.second; });
for (i = 0; i < n; i++)
{
// first check if we printed this character already;
// this is the case if the same character occurred
// before the current one:
bool isNew = true;
for (j = 0; j < i; j++)
{
// you find out yourself, do you?
// do not forget to break the loop
// in case of having detected an equal value!
}
if(isNew)
{
// well, now we can count...
unsigned int count = 1;
for(int j = i + 1; j < n; ++j)
count += array[j] == array[i];
// appropriate output...
}
}
That would do the trick and retains the array as is, however is an O(n²) algorithm. More efficient (O(n*log(n))) is sorting the array in advance, then you can just iterate over the array once. Of course, original array sequence gets lost then:
std::sort(array, array + arrayLength);
auto start = array;
for(auto current = array + 1; current != array + arrayLength; ++current)
{
if(*current != *start)
{
auto char = *start;
auto count = current - start;
// output char and count appropriately
}
}
// now we yet lack the final character:
auto char = *start;
auto count = array + arrayLength - start;
// output char and count appropriately
Pointer arithmetic... Quite likely that your teacher gets suspicious if you just copy this code, but it should give you the necessary hints to make up your own variant (use indices instead of pointers...).
I would do it this way.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string s;
vector<int> capCount(26, 0), smallCount(26, 0);
cout << "Enter the string\n";
cin >> s;
for(int i = 0; i < s.length(); ++i)
{
char c = s.at(i);
if(c >= 'A' && c <= 'Z')
++capCount[(int)c - 65];
if(c >= 'a' && c <= 'z')
++smallCount[(int)c - 97];
}
for(int i = 0; i < 26; ++i)
{
if(capCount[i] > 0)
cout << (char) (i + 65) << ": " << capCount[i] << endl;
if(smallCount[i] > 0)
cout << (char) (i + 97) << ": " << smallCount[i] << endl;
}
}
Note: I have differentiated lower and upper case characters.
Here's is the sample output:
output
EDIT: Posting everything, because it gets really weird.
using namespace std;
int main()
{
int doors = -1;
int jumper = 1;
bool isOpen[100];
string tf;
for(int i = 0 ; i < 100; i++){
isOpen[i] = false;
}
while(jumper < 100){
while(doors < 100){
if(isOpen[doors + jumper] == true){
isOpen[doors + jumper] = false;
}
else{
isOpen[doors + jumper] = true;
}
doors += jumper;
cout << doors << endl;
}
doors = -1;
jumper+=1;
}
for(int i = 0; i < 100; i++){
if(isOpen[i]){
tf = "open";
}
else{
tf = "closed.";
}
cout << "Door " << i << " is " << tf << endl;
}
return 0;
}
So I'm having a very odd problem with this piece of code.
It's supposed to go through an array of 100 items. 0 - 99 by ones then tows then threes, etc. However, after a = 10, it shoots up to 266.
Can anyone tell me why?
Edit:
This problem only happens when the for loop is commented out. When it is left in the code, it does the same thing, but it doesn't happen until 19.
If I comment out the "string tf;" as well, it continues to loop at 99.
This is all based on the doors count.
I'm unsure why either of these should be a factor to the loop that neither are connected to.
According to your description this is what you should do:
for(int adv = 1, i = 0; adv < 100;)
{
// i is array index (your b) -> use it somehow:
doSomething(arr[i]);
i += adv;
if(i >= 100)
{
i = 0;
adv++;
}
}
The (probable) reason you got weird behavior (including the 266 value) is that your code overruns the buffer. When b will be high enough (say 99), you'd write to isOpen[b + a] which will be 100 or higher (100 if a is 1, and that's just the first iteration, later iterations will go much further). If the compiler allocates isOpen before the ints you'll be overwriting them.