Recursive functions in winning number - c++

I need to make a code that checks if parameter r is a winner.
int is_winner(const float r){
}

You could try something like the following.
if (r <= max_winner && r => 0) {
if (/* simple criterion */) { // i.e. whole game even
return true;
} else if ( /* recursive call */ ){ // recursion, i.e. r/2 is winner and r*r is winner
return true;
}
}
Note that I assume (for sake of simplicity) that the output of your function should be a boolean variable, since the function is called is_winner, where we just want to check if it is true or false.
Try to fill in the conditions on your own. Note, that there are functions like std::floor, std::ceil. Also be aware of conversion from float or double to integer; e.g. check the beahviour of
float r = 2.7189;
int r_int = r;

(I'm not giving code because I think this is an exercise that you should make yourself)
In this particular exercise, it is harder to understand what the required test actually is than to implement it after a lesson on recursive functions.
Basically, if the number is within the range and the integer part of the number is not even, check its half and its square until one of them goes out of limit or is even by calling is_winner() for both from within is_winner() and pass the result back (both should be winners) until you know that the given number is a winner or not.
I would print results in the function to see what is going on.
I guess, since 0 is part of the range, half is always a winner if the number is within the range.

Related

Is there a way to make a function do something different the second time a number appears?

Im trying to make a small program about the method in which the amount of money awarded to players at the end of a game is decided. So far I have used a RNG to simulate what happens in a round of the game but have gotten stuck. I want to find out how to design my code in order for it to do something different the second time the same number is generated from the RNG.
while (active==1)
{
random=rand()%11+1;
if (random==11)
{
bomb=1;
}
}
Thanks for any responses :)
Keep a map of (number, count) pairs:
std::unordered_map<int, std::size_t> number_frequencies;
while (active) {
int number = random_number();
++number_frequencies[number];
if (number_frequencies[number] == 2) {
// do something
} else {
// do something else
}
}
First of all, for clarity, apply the following:
Define MAX to whatever maximum value you want to have (e.g., 11)
Use random between 0 and MAX-1 (instead of between 1 and MAX)
Then, you can try to adjust the following piece of code to your requirements:
#define MAX 11
...
int count[MAX] = {0};
while (active == 1)
{
random = rand()%MAX;
count[random]++;
...
}
The count array indicates the number of times that each random value was generated.
So at each iteration, you can use count[random] in order to choose what action to take.

knights tour in c++ using recursion

I have created a class Board which deals with 2d vectors specifically for this purpose. I am trying to solve the Knight's Tour. I want to print out the thing when it is done. Using the recursive voyagingKnight() function I find that it does not do anything, does not print the result. It seems that I would want to increment the step number for the recursive call but this is not working.
The vector argument incs is a 2d vector of increments for moving the knight, in each row a row move in the first colum and a column move in the second column.
Does anyone have any suggestions as to a flaw in my reasoning here?
The relevant code
bool voyaging_knight( Board &board, int i, int j, int steps ,vector< vector<int> > &increments)
{
if( !newplace(theboard, i, j) ) return false;
board.setval(i,j,step);
if( gone_everywhere( board, steps) )
{
cout <<"DONE" << endl;
board.showgrid();
return true;
}
int n;
int in, jn;
for(n=0; n<8; n++ )
{
in = i + increments[n][0];
jn = j + increments[n][1];
if( inboard(board, i, j)&& newplace(board,i,j) )
{
voyaging_knight( board, in, jn, steps+1 ,increments);
return true;
}
}
theboard.setval(i,j,-1);
}
Yes, change this:
voyagingKnight( theboard, inext, jnext, step+1 ,incs);
return true;
To this:
return voyagingKnight( theboard, inext, jnext, step+1 ,incs);
In addition, it seems that you need to return something (probably false) at the end of the function.
BTW, I'm assuming that you have all the entries in theboard initialized to -1.
I'm guessing that you want 1 continuous path made by horse movements on a (chess)-board found by backtracking. In that case you have to pass the board by value, so each path you take has its own instance to fill. By passing by reference, every path fills the same board, so you can never take all the steps.
Also you should pass a result by value and fill it with the positions you visited and return that from the recursive function, so each path has its own instance of resulting positions and by returning it, you end up with the final result.
You should not pass inc because that is just a helper container that doesn't change.
Make the board a global variable, and build up a sequence of visited squares in a global variable too. Make sure that when retracting each tentative step you undo any changes (square visited, last step of sequence). Call your knight's tour function, make it return success if it reaches the end, and do any output after finishing.
Package the whole shebang in a file or as a class, so as to not expose private details to prying eyes.

My while loop exits prematurely

thanks for reading this.
I am writing a code to read a big data file. And I try to use a while loop to read it one piece at a time.
But when I write
while(TimeStep++)
it will exit at the first loop.
if I write,
while(TimeStep+=1)
it will be just fine.
Also, if I initialize
int TimeStep=-1;
it will exit at the first loop. But if I initialize
int TimeStep=0;
it will be fine. The magic of while() confuse me. Please help me understand while loop.
Here is all my code.
//get diffusion of all the particles in the 256Coordinate.txt file and diffusion of a single particle.
using namespace std;
typedef vector<double> vec;
int ReadStructure(vec & Coordinate,int size,ifstream & TrajectoryFile){
double a;
for(int i=0;i<size*3;i++){
if(!(TrajectoryFile.eof())){
TrajectoryFile>>a;
Coordinate[i]=a;
}
}
//cout<<Coordinate[1]<<endl;
if(TrajectoryFile.eof()){
return 1;
} else {
return 0;
}
}
int main(){
int ContinueFlag=0,i,j,k;
double a,b,c;
vec Coordinate;
string filename= ("../256Coordinate.txt"); // a file that contains 256*5000*3 numbers
int size=256;
Coordinate.resize(size*3);
int TimeStep=0;
ifstream TrajectoryFile(filename.c_str());//open the .txt file and begin the read data
//TrajectoryFile>>a;
//cout<<a<<endl;
while(TimeStep+=1){//keep looping untils breaks.
ContinueFlag=ReadStructure(Coordinate,size,TrajectoryFile);//read the .txt file and store the values in the vector Coordinate[3*256]. Read 3
*256 numbers at a time.
// cout<<"ContinueFlag= "<<ContinueFlag<<endl;
if(ContinueFlag==1) break;//if we reach the end of the file, exit.
// cout<<Coordinate[1]<<endl;
}
cout<<"total number of timesteps= "<<TimeStep-1<<endl;
}
the body of while loop will execute when the loop condition under
while(loop condition)
is true.
So if you set TimeStep =0 to start with. It will test whether TimeStep ==0 before executing the while loop. Any non-zero value is treated as True. If it is 0, loop body will not execute.
If you initialize as int TimeStep=-1;, TimeStep+=1 will set TimeStep =0, which is equivalent to false, so loop body will not execute.
If you do not know the loop termination condition beforehand, simply use
while (true)
is better than using such a TimeStep variable.
Try:
while(true){
ContinueFlag=ReadStructure(Coordinate,size,TrajectoryFile);
if(ContinueFlag==1)
break;
}
In C++ the integer value 0 is False, any other value including negative integer is True. While loop exits when false.
I think your main problem is not understanding the while loop, it's understanding the increment operator ++.
Let's work with an example:
int x = 5;
int y = x++;
Here, x will have a value of 6 (because you made ++), but which value will y have? Actually, it will be 5. This is a so-called 'postincrement' operator: see, you assign first, and increment later.
If you wrote this
int x = 5;
int y = (x += 1);
Then you would have x = 6 as before, but this time y = 6 also, so you first increment x and only then assign it to y.
This should make your while loop misunderstanding go away:
int TimeStep = 0;
while(TimeStep++)
Here, TimeStep will get the value of 1, but only after it was used by while to test for exit, but while will see the old value (as y in the example above), and the old value is 0, so while exits immediately.
int TimeStep = 0;
while(TimeStep+=1)
In this case the loop goes on because you first increment the TimeStep and then let while test if it's nonzero.
I would really suggest you write a simple loop, why are you testing if TimeStep is nonzero anyway? Just do it like this:
while(true) { // Infinite cycle, until brake is encountered
TimeStep++;
}
The while loop expects a true/false value, according to that, TimeStep++ if TimeStep = -1 is false, because TimeStep++add 1 to TimeStep , so == 0, if TimeStep = 0and you add 1 then is ALWAYS true, because true is every value != 0...
I think you may need to get a better understanding of boolean algebra.
Here's a link to a tutorial http://www.electronics-tutorials.ws/boolean/bool_7.html.
A while loop is based around a boolean expression. If the expression within the while loop parentheses is true it will enter the loop and stop until that expression evaluates to false.
It works when the integer that you are using is set to 0 or 1 because 0 represents false and 1 represents true. You can't use an integer as a boolean expression if it is not 0 or 1.
It looks like you want the loop to break when ContinueFlag==1. So just use that as the while loop parameter. An alternative way would be to just change that code to while (true).
Since you want ContinueFlag to be set at least once (so you know when to break) I would suggest using a do while loop which executes at least once and then repeats if the expression is true.
USE THIS:
do {
ContinueFlag=ReadStructure(Coordinate,size,TrajectoryFile);
TimeStep++; //This allows for TimeStep to increment
} while (ContinueFlag!=1); //It will loop while ContinueFlag!=1 which will cause
//the loop to end when ContinueFlag==1
This is a better way of writing your code (as opposed to while (true)). This allows you to easily see what the purpose of the loop is.

Logic Help: comparing values and taking the smallest distance, while removing it from the list of "available to compare"

Okay, I have been set with the task of comparing this list of Photons using one method (IU) and comparing it with another (TSP). I need to take the first IU photon and compare distances with all of the TSP photons, find the smallest distance, and "pair" them (i.e. set them both in arrays with the same index). Then, I need to take the next photon in the IU list, and compare it to all of the TSP photons, minus the one that was chosen already.
I know I need to use a Boolean array of sorts, with keeping a counter. I can't seem to logic it out entirely.
The code below is NOT standard C++ syntax, as it is written to interact with ROOT (CERN data analysis software).
If you have any questions with the syntax to better understand the code, please ask. I'll happily answer.
I have the arrays and variables declared already. The types that you see are called EEmcParticleCandidate and that's a type that reads from a tree of information, and I have a whole set of classes and headers that tell that how to behave.
Thanks.
Bool_t used[2];
if (num[0]==2 && num[1]==2) {
TIter photonIterIU(mPhotonArray[0]);
while(IU_photon=(EEmcParticleCandidate_t*)photonIterIU.Next()){
if (IU_photon->E > thresh2) {
distMin=1000.0;
index = 0;
IU_PhotonArray[index] = IU_photon;
TIter photonIterTSP(mPhotonArray[1]);
while(TSP_photon=(EEmcParticleCandidate_t*)photonIterTSP.Next()) {
if (TSP_photon->E > thresh2) {
Float_t Xpos_IU = IU_photon->position.fX;
Float_t Ypos_IU = IU_photon->position.fY;
Float_t Xpos_TSP = TSP_photon->position.fX;
Float_t Ypos_TSP = TSP_photon->position.fY;
distance_1 = find distance //formula didnt fit here //
if (distance_1 < distMin){
distMin = distance_1;;
for (Int_t i=0;i<2;i++){
used[i] = false;
} //for
used[index] = true;
TSP_PhotonArray[index] = TSP_photon;
index++;
} //if
} //if thresh
} // while TSP
} //if thresh
} // while IU
Thats all I have at the moment... work in progress, I realize all of the braces aren't closed. This is just a simple logic question.
This may take a few iterations.
As a particle physicist, you should understand the importance of breaking things down into their component parts. Let's start with iterating over all TSP photons. It looks as if the relevant code is here:
TIter photonIterTSP(mPhotonArray[1]);
while(TSP_photon=(EEmcParticleCandidate_t*)photonIterTSP.Next()) {
...
if(a certain condition is met)
TSP_PhotonArray[index] = TSP_photon;
}
So TSP_photon is a pointer, you will be copying it into the array TSP_PhotonArray (if the energy of the photon exceeds a fixed threshold), and you go to a lot of trouble keeping track of which pointers have already been so copied. There is a better way, but for now let's just consider the problem of finding the best match:
distMin=1000.0;
while(TSP_photon= ... ) {
distance_1 = compute_distance_somehow();
if (distance_1 < distMin) {
distMin = distance_1;
TSP_PhotonArray[index] = TSP_photon; // <-- BAD
index++; // <-- VERY BAD
}
}
This is wrong. Suppose you find a TSP_photon with the smallest distance yet seen. You haven't yet checked all TSP photons, so this might not be the best, but you store the pointer anyway, and increment the index. Then if you find another match that's even better, you'll store that one too. Conceptually, it should be something like this:
distMin=1000.0;
best_photon_yet = NULL;
while(TSP_photon= ... ) {
distance_1 = compute_distance_somehow();
if (distance_1 < distMin) {
distMin = distance_1;
best_pointer_yet = TSP_photon;
}
}
// We've now finished searching the whole list of TSP photons.
TSP_PhotonArray[index] = best_photon_yet;
index++;
Post a comment to this answer, telling me if this makes sense; if so, we can proceed, if not, I'll try to clarify.

C++ Prime factor program 2 problems

Okay so I"m writing a program (in C++) that is supposed to take a number, go through it, find out if it's factors are prime, if so add that to a sum, and then output the sum of all of the imputed number's prime factors.
My program successfully seems to do this however it has 2 problems,
1) The number I am supposed to test to see the sum of the prime factors of this number (600851475143) but it's too big for an int. I'm not sure what other variable type to use, or which variable's types to change. I would really like a clear explanation on this if at all possible.
2) For some reason, when the program checks to see if 1 is a factor of the number, and then checks to see if 1 is prime, it says 1 is prime, even though the first step of the function for checking to see if it's prime is that if it's 1 then it isn't prime. I found a fix for this, by telling it to subtract 1 from the very last value for the sum of all prime factors. However, this is a fix, not really finding the problem. If someone could point out at least where the problem is I would appreciate it!
Here's the code, if you have questions, please ask!
#include <iostream>
using namespace std;
bool prime (int recievedvalue) { //starts a function that returns a boolean with parameters being a factor from a number
int j =1;
int remainderprime = 0;
bool ended = false;
while (ended == false){ //runs loop while primality is undetermined
if (recievedvalue == 1){ //if the recieved value is a 1 it isn't prime
//not prime
break; // breaks loop
return false;
}
remainderprime=recievedvalue%j; //gives a remainder for testing
if ((remainderprime==0 && j>2) && (j!=recievedvalue || j == 4)){ //shows under which conditions it isn't prime
ended=true;
//not prime
return false;
}
else if (j==1){
j++;
}
else if ( recievedvalue==2 || j==recievedvalue ){ // shows what conditions it is prime
ended = true;
//prime
return true;
}
else {
j++;
}
}
}
int multiple(int tbfactor){ //factors and then checks to see if factors are prime, then adds all prime factors together
//parameter is number to be factored
int sum = 0;
bool primetest = false;
int remainderfact;
int i=1;
while (i<=tbfactor){ //checks if a i is a factor of tbfactor
remainderfact=tbfactor%i;
if (remainderfact==0){ //if it is a factor it checks if it is a prime
primetest = prime(i);
}
if (primetest ==true){ //if it is prime it add that to the sum
sum += i;
primetest=false;
}
i++;
}
sum --; // for some reason it always ads 1 as a prime number so this is my fix for it
return sum;
}
int main()
{
int input;
int output;
cout << "Enter number to find the sum of all it's prime factors: ";
cin >> input;
output = multiple(input);
cout << output;
return 0;
}
I'm really new to this, like a few days or so, so I'm very unfamiliar with stuff right now so please explain easily for me! I look forward to your help! Thanks!
For 1), you need to use a larger datatype. A 64-bit integer should be enough here, so change your ints to whatever the 64-bit integer type is called on your platform (probably long, or maybe long long).
For 2), the problem appears to be that you have a break before your return false. The break causes the code to stop the while loop immediately and continues execution immediately after the loop. It doesn't appear that the return value is ever assigned in that case (which your compiler should be warning you about), so the actual value returned is effectively arbitrary.
While others have pointed out a problem with your data types, there's a few problems with the structure of the first function that immediately caught my eye. (BTW, your indentation is enraging.) Look at this stripped-down version:
bool prime (int recievedvalue) {
// ...
bool ended = false;
while (ended == false){
if (...){
break; // jumps _behind_ the loop
return false;
}
// ...
if (...) {
ended=true;
return false; // leaves function returning true
}
else if (...) {
// ...
}
else if (...) {
ended = true;
return true; // leaves function returning false
}
else {
// ...
}
}
// behind the loop
// leaves function returning random value
}
For one, every time you set the loop control variable ended, you leave the loop anyway using some other means, so this variable isn't needed. A while(true) or for(;;) would suffice.
Also, that break jumps behind the loop's body, but there isn't a statement there, so the code leaves the function without explicitly returning anything! That's invoking so-called Undefined Behavior. (According to the C++ standard, your program is, from this point on, free to do whatever it pleases, including returning random values (most implementations will do that), formatting your HD, invoking nasty Nasal Demons on you, or returning exactly what you expected, but only on Sundays.)
Finally, that break occurs right before a return false; which is therefor never reached. Actually your compiler should warn about that. If it doesn't, you're likely not compiling at the highest warning level. (You should turn this on. Always try to cleanly compile your code at the highest warning level.) If it does, learn to pay attention to compiler warnings. They are a very important tool for diagnosing problems during compilation. (Remember: Errors diagnosed during compilation need no testing and never make it to the customer.)
Use either a 64 bits number on a 64 bits system, or use a library that does arbitrary precision arithmetic
Remove the break before the return false. Because of the break, execution is resumed outside the loop and return false is never executed.
To store values larger than 4 bytes (the capacity of an int) you have a variety of options. Refer to this page for those options. As to why you're program is returning true for the check on whether or not 1 is prime, check out this section of code:
if (recievedvalue == 1){ //if the recieved value is a 1 it isn't prime
//not prime
break; // breaks loop
return false;
}
The break statement will exit and return false will never be reached. To solve the problem, remove the break statement.