Recursion not working properly - recursion

This is a recursive solver to try to solve Euler#60. http://projecteuler.net/problem=60
The solver runs through, but fails to find a solution for the last array member, so backtracks (like I think it's supposed to) but when I get back to the first array member, the loop runs out all the way. Can anybody spot for me why it doesn't stop at the next prime?
I've posted just the solver function below; the other function (Concat check) works properly and returns true for a partially filled array.
int Solver (int primes[5])
{
int i=1;
int x=0;
while (primes[x]!=0) {++x;} //work on the next one
if ((x>5) && Concat_Check(primes)) {return 1;} //solved array
for (i=3; i<=SIZE; i++) //try each value, if successful, return true
{
if (Is_Prime(i)) {primes[x]=i; cout<<"primes["<<x<<"] = "<<i<<endl;}
if ((Concat_Check (primes)) && Solver (primes)) {return 1;}
}
primes[x-1] = 0;
return 0;
}

I can't get the purpose of recursion in your code, seems a loop...
Anyway, maybe you forgot to increment x in loop, and the test seems incomplete.
for (i=3; i<=SIZE; i+=2) //try each value, if successful, return true
{
if (Is_Prime(i)) {
primes[x++]=i; cout<<"primes["<<x<<"] = "<<i<<endl;}
if ((Concat_Check (primes)) && Solver (primes)) {return 1;}
}
}

Related

Check for abort

I used to depend on the package RcppProgress to check for user abortion inside a long loop with Progress::check_abort(). But I just received an email from the CRAN team to tell me (and to other maintainers) that RcppProgress has bugs and will be removed soon in absence of maintainer (actually it seems already removed). Is there another way to check for abortion?
I found that R_CheckUserInterrupt exists. How to change my code to use this function? In Writing R extensions the function returns void so I do not understand how it works. It seems to exit immediately.
Rcpp::checkUserInterrupt seems to present the same behavior. And R: How to write interruptible C++ function, and recover partial results presents a kind of hack not recomented by its author. I would like to exit the loop correctly cleaning object allocated on the heap and returning partial output
// [[Rcpp::depends(RcppProgress)]]
#include <progress.hpp>
#include <Rcpp.h>
// [[Rcpp::export]]
SEXP f()
{
for( int i = 0 ; i < 100000 ; i++)
{
if (Progress::check_abort())
{
delete some_var;
return partial_output;
}
else
//do_stuff();
}
}
After reading the sources of Rcpp I found that Rcpp::checkUserInterrupt() throw an internal::InterruptedException. This works:
for (long i = 0 ; i < 100000000 ; i++)
{
try
{
Rcpp::checkUserInterrupt();
}
catch(Rcpp::internal::InterruptedException e)
{
delete some_var;
return partial_output;
}
}
It is slow but exactly like Process::check_abort. Optionally, as advised in Rcpp Attributes, one can check only every 100 or 1000 iteration to speed up the code.
for (long i = 0 ; i < 100000000 ; i++)
{
if (i % 100 == 0)
{
try
{
Rcpp::checkUserInterrupt();
}
catch(Rcpp::internal::InterruptedException e)
{
delete some_var;
return partial_output;
}
}
}

Count the number of nodes of a doubly linked list using recursion

Here is what I've done so far:
struct rep_list {
struct node *head;
struct node *tail;
}
typedef rep_list *list;
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
lst->head = lst->head->next;
return 1 + length(lst);
}
}
This works, but the head of the list the function accepts as a parameter gets changed. I don't know how to fix that.
I'm not allowed to change the function definition so it should always accept a list variable.
Any ideas?
EDIT: I tried to do what Tyler S suggested in the comments but I encountered another problem. If I create a node* variable at the beginning, it should point to lst->head. But then every recursive call to the function changes the value back to lst->head and I cannot move forward.
You don't need a local node: just don't change the list head. Instead, pass the next pointer as the recursion head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
return 1 + length(lst->head-next);
}
}
I see. Okay; this gets a bit clunky because of the chosen representation. You need a temporary variable to contain the remaining list. This iscludes changing the head.
int length(const list lst) {
if (lst->head == NULL) {
return 0;
}
else {
new_lst = new(list)
new_lst->head = lst->head->next;
var result = 1 + length(new_lst);
free(new_lst)
return result
}
}
At each recursion step, you create a new list object, point it to the 2nd element of the current list, and continue. Does this do the job for you?
Although this solution is clunky and I hate it, its the only way I can see to accomplish what you're asking without modifying the method signature. We create a temporary node * as member data of the class and modify it when we start.
struct rep_list {
struct node *head;
struct node *tail;
}
node *temp = NULL;
bool didSetHead = false;
typedef rep_list *list;
int length(const list lst) {
if ((didSetHead) && (lst->head != temp)) {
temp = lst->head;
didSetHead = false;
}
if (temp == NULL) {
didSetHead = true;
return 0;
}
else {
temp = temp->next;
return 1 + length(temp);
}
}
Please note, I haven't tested this code and you may have to play with a bit, but the idea will work.

Additional return statement while finding minimum depth of a Binary Search Tree

Following is the code that I found online to find the minimum depth of a binary search tree:
public class Solution {
public int minDepth(TreeNode root) {
if(root == null){
return 0;
}
LinkedList<TreeNode> nodes = new LinkedList<TreeNode>();
LinkedList<Integer> counts = new LinkedList<Integer>();
nodes.add(root);
counts.add(1);
while(!nodes.isEmpty()){
TreeNode curr = nodes.remove();
int count = counts.remove();
if(curr.left != null){
nodes.add(curr.left);
counts.add(count+1);
}
if(curr.right != null){
nodes.add(curr.right);
counts.add(count+1);
}
if(curr.left == null && curr.right == null){
return count;
}
}
return 0;
}
}
What I do not understand is the extra return statement at the end- return 0. Why is this needed?
It's for the case where the root isn't null, but it's the only node in the tree (the root is at depth 0). That return statement is needed because if the tree is empty, then something must be returned. It returns 0, because the depth is 0.
Similar to ghostofrasputin, the return statement is there because if the while condition is not met, then there is still a value to return.
Now the more important question, why do we need the last return if the program will never reach that return statement? (which I believe is this case for this)
Even though you are able to tell that the return statement wont be used, the compiler is not sophisticated enough to determine that, so it requires a return statement just in case the while loop is exited.
It's similar to the following code
public boolean getTrueOrFalse() {
if(Math.random() < 1) {
return true;
}
return false;
}
Though we know that this will always return true because Math.random() is always less than 1, the compiler isn't able to figure that out and thus the return statement is required if the if-statement is not met.

Issue with Recursive Methods ("missing return statement")

so I have a program that is running a bunch of different recursive methods, and I cannot get it to compile/run. The error is in this method, according to my computer:
public static int fibo(int n)
// returns the nth Fibonacci number
{
if (n==0)
{
return 0;
}
else if (n==1)
{
return 1;
}
else if (n>1)
{
return fibo(n-1) + fibo(n-2);
}
}
I have this method called correctly in my main method, so the issue is in this bit of code.
I think I can help you in this. Add return n; after your else if. Outside of the code but before the last curlicue.
The code will work as long as n ≥ 0 btw; another poster here is right in that you may want to add something to catch that error.
Make sure all possible paths have a return statement. In your code, if n < 0, there is no return statement, the compiler recognizes this, and throws the error.
public static int fibo(int n)
// returns the nth Fibonacci number
{
if (n<=0)
{
return 0;
}
else if (n==1)
{
return 1;
}
else // All other cases, i.e. n >= 1
{
return fibo(n-1) + fibo(n-2);
}
}

Return a result of type error in a Method

Im working on the collision detection in my 2D Processing 2.2.1 game. Basically what I did was write a class which creates a box by defining the coordinates of its endpoints and which has a method to check if two of these boxes overlap. I did this by introducing a boolean which is set to true as soon two of these boxes overlap. Then basically implementing a get method which creates these boxes, I run into a return a result of type error. It says that the method is not returning the correct type of Box1. I dont really understand since the box which I am returning does fit the constructor. I am pretty sure it is due to the fact that the objects colliding are in an array which generates more and more objects with time, but I sadly do not know how I would have to change my Collider ( Box1) class.
here is the code im getting the error on:
//returning collider info
public Box1 getBox1() {
for (int i =frameCount/600; i >0; i--) {
return new Box1( block[i].x - Blockpic.width/2, block[i].y-Blockpic.height/2, block[i].x+Blockpic.height/2, block[i].y+Blockpic.height/2);
}
}
this is my collider (Box1) class:
public class Box1 {
float x1, x2;
float y1, y2;
Box1( float x1, float y1, float x2, float y2 ) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
boolean isOverlap( Box1 b ) {
if ((( x1 <= b.x1 && b.x1 <= x2 ) || ( x1 <= b.x2 && b.x2 <= x2 ))
&& (( y1 <= b.y1 && b.y1 <= y2 ) || ( y1 <= b.y2 && b.y2 <= y2 ))) {
return true;
}
return false;
}
}
just for complete info my spawning objects class ( where the error is situated) :
public class Blockfield {
private int Blockcount;
private PImage Blockpic;
private Block block[];
//Constructor
public Blockfield (int Blockcount) {
this.Blockcount = Blockcount;
Blockpic = loadImage("block2.png");
//new array
block = new Block [Blockcount];
for ( int i=0; i < Blockcount; i++) {
block[i] = new Block( width+Blockpic.width, random (height),7);
}
}
//Draw method for this class
public void draw () {
for (int i =frameCount/600; i >0; i--) {
pushMatrix();
translate ( block[i].x,block[i].y );
image ( Blockpic, block[i].x, block[i].y);
popMatrix();
}
}
public void update() {
for (int i =frameCount/600; i >0; i--) {
//moves blocks right to left
block[i].x -=(6 * (frameCount/200));
//spawns block when they leave the screen
if (block[i].x < 0 - Blockpic.width) {
block[i] = new Block( width+Blockpic.width, random (height),7);
}
}
}
//returning collider info
public Box1 getBox1() {
for (int i =frameCount/600; i >0; i--) {
return new Box1( block[i].x - Blockpic.width/2, block[i].y-Blockpic.height/2, block[i].x+Blockpic.height/2, block[i].y+Blockpic.height/2);
}
}
}
class Block {
float x, y;
int speed;
Block ( float x, float y, int speed) {
this.x= x;
this.y= y;
this.speed = speed;
}
}
Thanks alot!!!
The problem, as you say, is with this method:
public Box1 getBox1() {
for (int i =frameCount/600; i >0; i--) {
return new Box1( block[i].x - Blockpic.width/2, block[i].y-Blockpic.height/2, block[i].x+Blockpic.height/2, block[i].y+Blockpic.height/2);
}
}
Ignoring for a second that it doesn't make sense to have a return statement inside a for loop like this, the whole problem is that computers are too stupid to know what the value of frameCount is before they run the code. What if frameCount is 0? Or negative?
If frameCount is 0 or negative, then the body of the for loop will never be executed, and this method will never return anything. That's the error.
You might know that frameCount will always be positive, but the computer doesn't.
Edit: Continuing in response to your below comment:
If you want help, you have to provide an MCVE. Note that this should be as few lines as possible, just to get the basics across. We don't need any collision detection, just a function you call. Here's an example:
void setup(){
String s = getString(true);
println(s);
}
String getString(boolean b){
if(b){
return "testing";
}
}
If you try to run this code, you'll get an error telling you that "This method must return a result of type String".
The reason you get this error is because: what will the getString() function return if I pass in a value of false? It won't return anything! This is exactly like what your code is complaining about. We can see that getString() is only ever called with a value of true, but the computer isn't smart enough to figure that out.
You seem to misunderstand the power that a compiler has. It can't see what will happen at runtime. Even if it's obvious to you that the boolean will always be true (or in your case, that frameCount is always positive), the compiler can't know that. And since it can't know that, it's telling you that you might not return a value from a method with a return type, and that's a compiler error.
You need to refactor your code so that it always returns something from methods that have a return type. However, I'm skeptical that the for loop does what you think it does- but you haven't really explained what you think it does, so that's just a guess.
And the reason you didn't encounter this error in your other methods is because none of them contain this logical error. The only other function that has a return type is this one:
boolean isOverlap( Box1 b ) {
if (lotsOfLogic) {
return true;
}
return false;
}
Notice how even if the if statement evaluates to false, you still return something from this function. That's what you need to do with your getBox1() function.

Resources