Trouble Implementing nested loops into a recursive solution - c++

Non-Recursive Code
Here is the code I am trying to convert into a recursive solution.
int main()
{
int number[3];
for (number[0]=0; number[0] <= 9; number[0]++)
{
for (number[1]=0; number[1] <= 4; number[1]++)
{
for (number[2]=0; number[2] <= 9; number[2]++)
{
std::cout << number[0] << number[1] << number[2] << std::endl;
}
}
}
std::cout << "Press any key to continue";
std::cin.ignore();
return 0;
}
The output of this code can be found here http://pastebin.com/f20X3gT3.
Recursive Attempt
Here is my failed attempt at replicating the above algorithm into a recursive solution. It compiles without any errors but it does not give the same results as the above Non-Recursive solution does.
#include <iostream>
const int NumberLength = 3;
int number[3];
int element;
void generateFormula(const int Length) {
if(Length == 0) {
for (int n = 0; n <= NumberLength; ++n) {
std::cout << number[n];
}
std::cout << std::endl;
return;
}
if(element%2==0) {
for(number[element]=0; number[element] <= 9; number[element]++);
generateFormula(Length-1);
}
else {
for(number[element]=0; number[element] <= 4; number[element]++);
generateFormula(Length-1);
}
element++;
}
int main()
{
for (int i = 0; i <= NumberLength; ++i)
generateFormula(i);
std::cout << "Press any key to continue";
std::cin.ignore();
return 0;
}
Output:
0000
10000
10501
10500

If you change your function a little bit, you'll be able to see how it can be transformed to a recursive function.
// Drive it using externally supplied data.
void generateFormula1(int number[], int loopCounter[])
{
for (; number[0] <= loopCounter[0]; number[0]++)
{
for (; number[1] <= loopCounter[1]; number[1]++)
{
for (; number[2] <= loopCounter[2]; number[2]++)
{
std::cout << number[0] << number[1] << number[2] << std::endl;
}
}
}
}
Now, it is a bit easier to transform it to a recursive function.
void generateFormula2(int number[], int loopCounter[], int nestingLevel)
{
// The terminating condition of the recursive function.
if ( nestingLevel == 3 )
{
std::cout << number[0] << number[1] << number[2] << std::endl;
return;
}
for (; number[nestingLevel] <= loopCounter[nestingLevel]; number[nestingLevel]++)
{
generateFormula2(number, loopCounter, nestingLevel+1);
}
}
Test it using:
int main()
{
int loopCounter[3] = {9, 4, 9};
int number1[3] = {0};
generateFormula1(number1, loopCounter);
int number2[3] = {0};
generateFormula2(number2, loopCounter, 0);
return 0;
}
See it working at http://ideone.com/JH76sa.

You can simplify your function quite a bit. Using std::setw() and std::setfill() you don't need to have three different variables.You can change the iterative approach to
void print()
{
for (int i = 0; i < 950; i++)
{
cout << setw(3) << setfill('0') << i << "\n";
if (((i+1) % 50) == 0)
i += 50;
}
}
Live Example
And the recursive approach would become:
void print(int i)
{
cout << setw(3) << setfill('0') << i << "\n";
if (i == 949)
return;
if (((i+1) % 50) == 0)
i += 50;
print(++i);
}
Live Example

void print(int x, int y, int z){
std::cout << '(' << x << ", " << y << ", " << z << ")\n";
++x;
if(x == 10){
x = 0;
++y;
if(y == 10){
y = 0;
++z;
if(z == 10)
return;
}
}
print(x, y, z);
}
auto main() -> int{
print(0, 0, 0);
}
This will print out (0, 0, 0) through to (9, 9, 9)
You can replace x, y and z with whatever you like and modify the parameters of the if statements to get the results you want. You could also generalize the function to get a limit for each parameter:
template<int XLim, int YLim, int ZLim>
void print(int x, int y, int z){
std::cout << '(' << x << ", " << y << ", " << z << ")\n";
if(z >= ZLim && y >= YLim && z >= ZLim) return;
++x;
if(x == 10){
x = 0;
++y;
if(y == 10){
y = 0;
++z;
if(z == 10) return;
}
}
print<XLim, YLim, ZLim>(x, y, z);
}
auto main() -> int{
print<9, 4, 9>(0, 0, 0);
}

Related

Print prime factorization in exponential form in C++

So far I have this code. I'm trying to print prime factorization with exponents. For example, if my input is 20, the output should be 2^2, 5
#include <iostream>
#include <cmath>
using namespace std;
void get_divisors (int n);
bool prime( int n);
int main(int argc, char** argv) {
int n = 0 ;
cout << "Enter a number and press Enter: ";
cin >>n;
cout << " Number n is " << n << endl;
get_divisors(n);
cout << endl;
return 0;
}
void get_divisors(int n){
double sqrt_of_n = sqrt(n);
for (int i =2; i <= sqrt_of_n; ++i){
if (prime (i)){
if (n % i == 0){
cout << i << ", ";
get_divisors(n / i);
return;
}
}
}
cout << n;
}
bool prime (int n){
double sqrt_of_n = sqrt (n);
for (int i = 2; i <= sqrt_of_n; ++i){
if ( n % i == 0) return 0;
}
return 1;
}
I hope someone can help me with this.
You can use an std::unordered_map<int, int> to store two numbers (x and n for x^n). Basically, factorize the number normally by looping through prime numbers smaller than the number itself, dividing the number by the each prime as many times as possible, and recording each prime you divide by. Each time you divide by a prime number p, increment the counter at map[p].
I've put together a sample implementation, from some old code I had. It asks for a number and factorizes it, displaying everything in x^n.
#include <iostream>
#include <unordered_map>
#include <cmath>
bool isPrime(const int& x) {
if (x < 3 || x % 2 == 0) {
return x == 2;
} else {
for (int i = 3; i < (int) (std::pow(x, 0.5) + 2); i += 2) {
if (x % i == 0) {
return false;
}
}
return true;
}
}
std::unordered_map<int, int> prime_factorize(const int &x) {
int currentX = abs(x);
if (isPrime(currentX) || currentX < 4) {
return {{currentX, 1}};
}
std::unordered_map<int, int> primeFactors = {};
while (currentX % 2 == 0) {
if (primeFactors.find(2) != primeFactors.end()) {
primeFactors[2]++;
} else {
primeFactors[2] = 1;
}
currentX /= 2;
}
for (int i = 3; i <= currentX; i += 2) {
if (isPrime(i)) {
while (currentX % i == 0) {
if (primeFactors.find(i) != primeFactors.end()) {
primeFactors[i]++;
} else {
primeFactors[i] = 1;
}
currentX /= i;
}
}
}
return primeFactors;
}
int main() {
int x;
std::cout << "Enter a number: ";
std::cin >> x;
auto factors = prime_factorize(x);
std::cout << x << " = ";
for (auto p : factors) {
std::cout << "(" << p.first << " ^ " << p.second << ")";
}
}
Sample output:
Enter a number: 1238
1238 = (619 ^ 1)(2 ^ 1)
To begin with, avoid using namespace std at the top of your program. Second, don't use function declarations when you can put your definitions before the use of those functions (but this may be a matter of preference).
When finding primes, I'd divide the number by 2, then by 3, and so on. I can also try with 4, but I'll never be able to divide by 4 if 2 was a divisor, so non primes are automatically skipped.
This is a possible solution:
#include <iostream>
int main(void)
{
int n = 3 * 5 * 5 * 262417;
bool first = true;
int i = 2;
int count = 0;
while (i > 1) {
if (n % i == 0) {
n /= i;
++count;
}
else {
if (count > 0) {
if (!first)
std::cout << ", ";
std::cout << i;
if (count > 1)
std::cout << "^" << count;
first = false;
count = 0;
}
i++;
if (i * i > n)
i = n;
}
}
std::cout << "\n";
return 0;
}
Note the i * i > n which is an alternative to the sqrt() you are using.

I think I have a memory leak?

I am trying to do the Knight's Tour using dynamic arrays because the user will be able to implement their own board size, and where they want to start the knight at in the board.
However, before I changed everything to dynamic arrays, I was able to perform my code just find using static arrays, but now that I switched to dynamic arrays whenever my code executes, I get a memory leak I believe and the program crashes. I was wondering if my deconstructor is not working properly? Or if there is a different way I have to delete the dynamic array?
I am also wondering if there is a way to make this code a little more efficient, more exactly make the Move() function a little more efficient. Thanks.
#include <iostream>
#include <iomanip>
#include "stdafx.h"
using namespace std;
class Knight
{
private:
int Tracker = 1;
int BoardSize;
int **Board = new int*[BoardSize];
public:
Knight(int s)
{
BoardSize = s;
for (int i = 0; i <= s -1; i++)
{
Board[i] = new int[s];
}
for (int i = 0; i <= s - 1; i++)
{
for (int j = 0; j <= s - 1; j++)
{
Board[i][j] = 0;
}
}
}
~Knight()
{
for (int i = 0; i <= BoardSize - 1; i++)
{
delete[] Board[i];
}
delete[] Board;
}
void MarkUp(int &val)
{
val = Tracker;
Tracker++;
}
void MarkDown(int &val)
{
val = 0;
Tracker--;
}
bool PossibleMove(int &val)
{
if (val == 0)
return 1;
else
return 0;
}
void Display()
{
for (int k = 0; k < (BoardSize * 5) + 1; k++)
{
cout << "-";
}
cout << endl;
for (int i = 0; i <= BoardSize - 1; i++)
{
cout << "| ";
for (int j = 0; j <= BoardSize - 1; j++)
{
cout << setw(2) << setfill('0') << Board[i][j] << " | ";
}
cout << endl;
for (int k = 0; k < (BoardSize * 5) + 1; k++)
{
cout << "-";
}
cout << endl;
}
cout << endl << endl;
}
bool Move(int x, int y)
{
if (Tracker > (BoardSize * BoardSize))
{
return true;
}
if (PossibleMove(Board[x][y])) {
if ((x - 2 >= 0) && (y + 1 <= (BoardSize - 1)))
{
MarkUp(Board[x][y]);
if (Move(x - 2, y + 1))
{
return true;
}
else
{
MarkDown(Board[x][y]);
}
}
if ((x - 2 >= 0) && (y - 1 >= 0))
{
MarkUp(Board[x][y]);
if (Move(x - 2, y - 1))
{
return true;
}
else
{
MarkDown(Board[x][y]);
}
}
if ((x - 1 >= 0) && (y + 2 <= (BoardSize - 1)))
{
MarkUp(Board[x][y]);
if (Move(x - 1, y + 2))
{
return true;
}
else
{
MarkDown(Board[x][y]);
}
}
if ((x - 1 >= 0) && (y - 2 >= 0))
{
MarkUp(Board[x][y]);
if (Move(x - 1, y - 2))
{
return true;
}
else
{
MarkDown(Board[x][y]);
}
}
if ((x + 2 <= (BoardSize - 1)) && (y + 1 <= (BoardSize - 1)))
{
MarkUp(Board[x][y]);
if (Move(x + 2, y + 1))
{
return true;
}
else
{
MarkDown(Board[x][y]);
}
}
if ((x + 2 <= (BoardSize - 1)) && (y - 1 >= 0))
{
MarkUp(Board[x][y]);
if (Move(x + 2, y - 1))
{
return true;
}
else
{
MarkDown(Board[x][y]);
}
}
if ((x + 1 <= (BoardSize - 1)) && (y + 2 <= (BoardSize - 1)))
{
MarkUp(Board[x][y]);
if (Move(x + 1, y + 2))
{
return true;
}
else
{
MarkDown(Board[x][y]);
}
}
if ((x + 1 <= (BoardSize - 1)) && (y - 2 >= 0))
{
MarkUp(Board[x][y]);
if (Move(x + 1, y - 2))
{
return true;
}
else
{
MarkDown(Board[x][y]);
}
}
}
return false;
}
};
int main()
{
int size = 0;
int Row, Col;
int opt = 0;
do
{
cout << "Welcome to Knights Tour!" << endl;
cout << "1) Start the Tour." << endl;
cout << "2) Quit." << endl;
cin >> opt;
switch (opt)
{
case 1:
{
cout << "Enter board size:" << endl;
cin >> size;
Knight K1(size);
cout << "Enter Row:" << endl;
cin >> Row;
cout << "Enter Column: " << endl;
cin >> Col;
if (K1.Move(Row, Col))
{
cout << "\nOperation was Successful." << endl;
cout << "Possible Solution:" << endl;
K1.Display();
}
else
{
cout << "\nThat is not Possible." << endl;
}
cout << endl;
break;
}
case 2:
{
exit(0);
break;
}
default:
{
cout << "Not a Valid Option." << endl;
cout << "Try Again Please." << endl;
cout << endl;
break;
}
}
} while (opt != 2);
return 0;
}
This code does not work as you think it does:
int BoardSize;
int **Board = new int*[BoardSize];
The value of BoardSize is going to be whatever happens to be in the memory that gets allocated for it, so the new is going to try to allocate an unknowable size array.
Don't use hand coded dynamic arrays for this. Use std::vector; That's what it's for. In real life production code, you should almost never ever use dynamically allocated arrays. You'll use one of the standard containers.
As noted in the comments by multiple people, memory leaks do not cause crashes (generally).
The issue is that inside the constructor you assign values to the Board array elements. However, you never allocate memory for the Board array itself. I.e. when you do Board[i] = new int[s];, Board points to some random address. This is because the line int **Board = new int*[BoardSize]; is not executed before the constructor starts.
So the following should work:
class Knight {
private:
int BoardSize;
int **Board;
public:
Knight (int s) {
BoardSize = s;
Board = new int*[BoardSize];
// Remainder of code
}
};
However, I really suggest you use std::vector for this instead. Then you won't have to deal with memory (de)allocation at all. That could look as concise as the following:
#include <vector>
class Knight {
private:
int BoardSize;
std::vector<std::vector<int>> Board;
public:
Knight (int s) : BoardSize(s), Board(s, std::vector<int>(s, 0)) { }
};
Note that I initialized the class members directory in the member initializer list.

why increment variable changing the value of the array when they have different names

Can someone please help me. I am struggling to find in my code why the last value in column B always gets incremented by one. I have written some code since its an assignment due today. I also cant figure out why the last value in column B is not equal to 196 because in the reset function it sets all the values in the array to 196 . Any suggestion would be appreciated. Thank you in advance
#include <iostream> //includes cin cout
#include <iomanip>
using namespace std; //setting up the environment
const int NUMBER_OF_ROWS = 3;
const int NUMBER_OF_COLUMNS = 3;
void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats);
bool isFull(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
bool isEmpty(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
int main() { //main starts
int maxSeats;
int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
int SeatCountNumber = 0;
bool anyFreeSeats;
reset(seats);
anyFreeSeats = true;
SeatCountNumber = 0;
while (anyFreeSeats) {
printAllSeats(seats);
askForUsersSeat(seats, SeatCountNumber, anyFreeSeats);
}
system("pause");
return 0;
} //main ends
void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]) {
cout << endl;
cout << setw(10) << " - = Available R = Reserved\n\n";
for (int i = 0; i <= NUMBER_OF_ROWS; i++) {
cout << setw(15) << i << " ";
for (int j = 0; j < NUMBER_OF_COLUMNS; j++) {
if (i == 0) {
cout << " " << static_cast<char>(j + 65) << " ";
} else {
cout << " " << static_cast<char>(seats[i][j]) << " ";
}
}
cout << endl;
}
cout << endl;
}
void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]) {
//set all values in array to 196
for (int i = 0; i <= NUMBER_OF_ROWS; i++) {
for (int j = 0; j <= NUMBER_OF_COLUMNS; j++) {
seats[i][j] = 196;
}
}
}
void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats) {
int seatChoiceNumber;
char seatChoiceLetter;
int letter;
int maxSeats = NUMBER_OF_ROWS * NUMBER_OF_COLUMNS;
cout << "Seat (Row, Column): ";
cin >> seatChoiceNumber >> seatChoiceLetter;
letter = static_cast<int>(toupper(seatChoiceLetter));
if (((letter >= 65) && (letter < (65 + NUMBER_OF_COLUMNS))) && ((seatChoiceNumber > 0) && (seatChoiceNumber <= NUMBER_OF_ROWS))) {
if (seats[(seatChoiceNumber)][(letter - 65)] == 82) {
} else {
seats[(seatChoiceNumber)][(letter - 65)] = 82;
SeatCountNumber++; //this changes last value in column B for some reason
if (SeatCountNumber < maxSeats) {
anyFreeSeats = true;
}
else if (SeatCountNumber > maxSeats) {
printAllSeats(seats);
anyFreeSeats = false;
}
}
} else {
}
}
I kind of cleaned up the code a bit. It seems you found your answer in the comments, so I just did some indentation. Try and eliminate whitespaces in your code (mind you, the one I am putting here is not perfect either, but you get the point). Clean and easy to read code doesn't only make it better for you, but as you get higher up in the industry and other people begin reading and working on your code, having clean and easy to read code really helps :)
#include <iostream> //includes cin cout
#include <iomanip>
using namespace std; //setting up the environment
const int NUMBER_OF_ROWS = 3;
const int NUMBER_OF_COLUMNS = 3;
void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats);
bool isFull(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
bool isEmpty(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS]);
int main()
{
int maxSeats;
int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS];
int SeatCountNumber = 0;
bool anyFreeSeats;
reset(seats);
anyFreeSeats = true;
SeatCountNumber = 0;
while (anyFreeSeats)
{
printAllSeats(seats);
askForUsersSeat(seats, SeatCountNumber, anyFreeSeats);
}
system("pause");
return 0;
} //main ends
void printAllSeats(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS])
{
cout << endl;
cout << setw(10) << " - = Available R = Reserved\n\n";
for (int i = 0; i <= NUMBER_OF_ROWS; i++)
{
cout << setw(15) << i << " ";
for (int j = 0; j < NUMBER_OF_COLUMNS; j++)
{
if (i == 0)
{
cout << " " << static_cast<char>(j + 65) << " ";
}
else
{
cout << " " << static_cast<char>(seats[i][j]) << " ";
}
}
cout << endl;
}
cout << endl;
}
void reset(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS])
{
//set all values in array to 196
for (int i = 0; i <= NUMBER_OF_ROWS; i++)
{
for (int j = 0; j <= NUMBER_OF_COLUMNS; j++)
{
seats[i][j] = 196;
}
}
}
void askForUsersSeat(int seats[NUMBER_OF_ROWS][NUMBER_OF_COLUMNS], int &SeatCountNumber, bool &anyFreeSeats)
{
int seatChoiceNumber;
char seatChoiceLetter;
int letter;
int maxSeats = NUMBER_OF_ROWS * NUMBER_OF_COLUMNS;
cout << "Seat (Row, Column): ";
cin >> seatChoiceNumber >> seatChoiceLetter;
letter = static_cast<int>(toupper(seatChoiceLetter));
if (((letter >= 65) && (letter < (65 + NUMBER_OF_COLUMNS))) && ((seatChoiceNumber > 0) && (seatChoiceNumber <= NUMBER_OF_ROWS)))
{
if (seats[(seatChoiceNumber)][(letter - 65)] == 82)
{
}
else
{
seats[(seatChoiceNumber)][(letter - 65)] = 82;
SeatCountNumber++; //this changes last value in column B for some reason
if (SeatCountNumber < maxSeats)
{
anyFreeSeats = true;
}
else if (SeatCountNumber > maxSeats)
{
printAllSeats(seats);
anyFreeSeats = false;
}
}
}
else {
}
}
Note: Some more whitespaces could even come out but I generally like to have spaces after certain statements (personal preference).

Why is there a Segmentation Fault from this vector code?

When I execute this code in Code::Blocks I get a segmentation fault. Why? I've used debug and haven't found why. Any help is useful.
The debugger showed it was from the vector push_back method, but specifically on the "this" pointer used in the copy constructor.
#include <iostream>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <cmath>
const int MAX_COL = 7, MAX_ROW = 6;
const int NOPLAYER = 0, PLAYER1 = 1, PLAYER2 = 2;
const int NOTHING = 123;
int movesBeingStored = 0;
int movesCreated = 0;
class Move{
public:
Move() : row(-1), col(-1), plr(-1) {
//std::cout << "Placed #" << col << "," << row << std::endl;
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
};
Move(int r, int c, int p) : row(r), col(c), plr(p) {
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
};
~Move() {
--movesBeingStored;
std::cout << "-Now " << movesBeingStored << " move(s)" << std::endl;
};
int getRow() const { return row; }
int getCol() const { return col; }
int getPlayer() const { return plr; }
Move(const Move* other) {
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
col = other->getCol();
row = other->getRow();
plr = other->getPlayer();
}
Move(const Move& other) {
++movesBeingStored;
++movesCreated;
std::cout << "+Now " << movesBeingStored << " move(s), Created " << movesCreated << std::endl;
col = other.getCol(); //This line causes a segment fault
row = other.getRow();
plr = other.getPlayer();
}
bool operator== (const Move& other) const {
return (&other == this);
}
private:
int row, col, plr;
};
int board[MAX_COL * MAX_ROW];
std::vector<Move> moves;
bool isFull[MAX_COL];
int tops[MAX_COL];
int currentPlayer = PLAYER1;
int checkedCollumns = 0;
void randomize( void ) { srand(time(NULL)); }
void startBoard( void );
void placeMove(int col, int player);
void popMove();
int checkwin(int curPlayer);
int checkMove(int depth, int& bestCol, int curP, int checkP);
int randomInt(int min, int max);
void printMoves( void );
int main()
{
startBoard();
randomize();
int col = -1;
int pts = checkMove(2, col, PLAYER1, PLAYER1);
if(col == -1) {
std::cout << "No best move" << std::endl;
} else {
std::cout << "Best move: Col " << col << std::endl;
if(pts == NOTHING) {
std::cout << "Nothing happens" << std::endl;
} else {
std::cout << "Gives " << pts << " points" << std::endl;
}
}
}
void startBoard( void ) {
for(int i = 0; i < MAX_COL; ++i) {
isFull[i] = false;
tops[i] = 0;
}
for(int p = 0; p < MAX_COL * MAX_ROW; ++p) {
board[p] = NOPLAYER;
}
}
void placeMove(int col, int player) {
if(col < 0 || col >= MAX_COL)
return;
if(isFull[col])
return;
if(player != PLAYER1 && player != PLAYER2)
player = PLAYER1;
moves.push_back(Move(col, tops[col], player));
board[col + tops[col] * MAX_COL] = player;
++tops[col];
isFull[col] = (tops[col] == MAX_ROW);
}
void popMove() {
if(moves.empty())
return;
Move move = moves.back();
moves.pop_back();
int col = move.getCol(), row = move.getRow();
board[col + row * MAX_COL] = NOPLAYER;
tops[col] = row;
isFull[col] = (tops[col] == MAX_ROW);
}
int checkwin(int curPlayer) {
if(randomInt(0,5) != 1)
return NOTHING;
return randomInt(0,4);
}
int checkMove(int depth, int& bestCol, int curP, int checkP) {
int pts = NOTHING, col = -1, p = NOTHING, c = -1;
if(depth <= 0) {
if(moves.empty()) {
bestCol = -1;
return NOTHING;
}
Move move = moves.back();
bestCol = move.getCol();
pts = checkwin((move.getPlayer());
if(move.getPlayer() != checkP && pts != NOTHING)
pts = -pts;
return pts;
}
for(int i = 0; i < MAX_COL; ++i) {
std::cout << "C: " << checkedCollumns;
std::cout << "\tD: " << depth;
std::cout << "\tM: " << moves.size();
std::cout << std::endl;
if(isFull[i])
continue;
++checkedCollumns;
placeMove(i, curP);
p = checkMove(depth - 1, c, ((curP == PLAYER1)?PLAYER2:PLAYER1), checkP);
popMove();
if(p != NOTHING && checkP != curP)
p = -p;
if(col == -1) {
col = i;
pts = p;
continue;
}
if(pts == NOTHING && p != NOTHING && p >= 0) {
col = i;
pts = p;
continue;
}
if(pts != NOTHING && p != NOTHING && p > pts) {
col = i;
pts = p;
}
}
bestCol = col;
return pts;
}
int randomInt(int min, int max) {
double per = (double)(rand() % RAND_MAX) / RAND_MAX;
return min + (max - min) * per;
}
void printMoves( void ) {
std::cout << "M:";
if(moves.empty()) {
std::cout << " --\t" << moves.size();
return;
}
Move m;
for(unsigned int i = 0; i < moves.size(); ++i) {
m = moves.at(i);
std::cout << " {" << m.getCol() << "," << m.getRow() << "}";
}
std::cout << "\t" << moves.size();
}
A very trivial error, manifesting in a very obscure way. The segment fault is caused by the vector trying to construct an object at an invalid location. Why? Because of the following line in void popMove():
board[col + row * MAX_COL] = NOPLAYER;
This line has a buffer overflow caused by invalid coordinates (0, 6), which overwrites the internal memory pointer in moves. That's the problem, the solution is up to you.

User defined function returning wrong count in c++

I'm trying to write program to calculate and display the number of primes in the first 50 “chiliads”. There must be 2 user defined functions "isPrime" and "primeCount". It seems like the "primeCount" is appending 4469969 to every count. It isn't doing that when I paste it into the main function.
int main (){
long x = 1;
long y = 1000;
char reply;
cout << "Start End Number of Primes" << endl;
while (y <= 50000)
{
cout << x << " " << y << " ";
cout << primeCount(x, y) << endl;
x = 1000 + x;
y = 1000 + y;
}
//exits the program
cout << "Enter q to quit... ";
cin >> reply;
return 0;
}// End main function
bool isPrime(long n)
{
long i = 2;
if (n == 1)
return false;
if (n == 2)
return true;
if (n == 3)
return true;
if ((n % 2) == 0)
return false;
if ((n % 3) == 0)
return false;
while (i < n)
{
if (n % i == 0 )
{
return false;
}
else
{
i++;
}
}
return true;
}
long primeCount (long x, long y)
{
long count = 0;
while (x < y)
{
if (isPrime(x) == 1)
{
count++;
}
x++;
}
cout << count;
}
You were not returning a value from "primeCount" you were printing it.
I cleaned up the code as follows, along with some optimizations (we prove that the candidate is odd, so we don't need to check even divisors, and we only check for the value of 2 when we already know the number is even, saving us 1 extra test per odd number).
#include <iostream>
// prototypes for functions we implement after we use them.
long primeCount(long x, long y);
bool isPrime(long n);
int main (){
long x = 1;
long y = 1000;
std::cout << "Start End Number of Primes" << std::endl;
while (y <= 50000)
{
std::cout << x << " " << y << " ";
std::cout << primeCount(x, y) << std::endl;
x += 1000;
y += 1000;
}
return 0;
}
bool isPrime(long n)
{
if((n & 1) == 0) // even
return (n == 2);
if(n == 1)
return false;
for (long i = 3; i < n / 2; i += 2)
{
if ((n % i) == 0 )
return false;
}
return true;
}
long primeCount(long x, long y)
{
long count = 0;
while (x < y)
{
if (isPrime(x))
count++;
++x;
}
return count;
}