convert iterative function to recursive function - c++

i have a problem on iterative function and recursive function.
i have a iterative function and i have to convert it into a recursive one.
could you give me some advice on my code?thanks so much
the code is to determine if the array of data points correspond to a concave function using recursion.
Here is the code of the iterative version:
bool isConcave(double a[], int n)
{
int slope = 1;
bool concave = true;
for (int i = 1; i < n && concave; i++)
{
double delta = a[i] - a[i-1];
if (slope > 0)
{
if (delta < 0)
slope = -1;
}
else if (delta > 0)
concave = false; // slope == -1 and delta > 0
}
return concave;
}
And, here is the code of my recursive version which can't work:
bool isConcave_r(double a[], int n, int& slope)
{
//Implement this function using recursion
double delta = a[n] - a[n-1];
bool concave = true;
if (n == 0)
return false;
if (slope > 0)
{
if (delta < 0)
{
slope = -1;
}
else
concave = true;
}else
return 0;
//dummy return statement
return isConcave_r(a, n, slope);
}

In the iterative version of your program, the computation moves from 1 to n-1, but in the recursive version computation moves form n-1 to 1. So, instead of tail recursion, use head recursion. And slope should be static variable. So, declare slope as static variable. It will work.

Not necessary the best/cleanest way, but you may replace any loop
for (int i = 0; i != N; ++i) {
body(i, localVars);
}
by
void body_rec(int N, int i, LocalVars& localVars)
{
if (i == N) return;
body(i, localvars);
body_rec(N, i + 1, localVars);
}
or
int body_rec(int N, int i, LocalVars& localVars)
{
if (i == N) return localVars.res; // or any correct value
body(i, localvars);
if (localVars.end) { // break the "loop", and so stop the recursion.
return localVars.res; // or any correct value
}
return body_rec(N, i + 1, localVars);
}
So, in your case, you forget to pass slope into the recursion.
[edit]
Full solution:
bool isConcave_r(int N, int i, double a[], int slope)
{
if (i >= N) return true;
const double delta = a[i] - a[i-1];
if (slope > 0) {
if (delta < 0) {
slope = -1;
}
}
else if (delta > 0) {
return false;
}
return isConcave_r(N, i + 1, a, slope);
}
bool isConcave(double a[], int n)
{
int i = 1;
int slope = 1;
return isConcave_r(n, i, a, slope);
}
Note also that the name seems "incorrect", you don't check if the "curve" is concave, case where delta == 0 should be specific I think...

Related

I need to convert this head recursion function to tail recursive

I need to convert this recursive function into tail recursive function but i am getting the wrong output can any help me out with this.
Here is the function definition:
f(n) = 3f(n − 1) - f(n − 2) + n,
with initial conditions f(0) = 1 and f(1) = 2.
#include <iostream>
using namespace std;
int headRecursion(int n) {
if(n == 0) {
return 1;
}
if (n == 1) {
return 2;
}
return 3 * headRecursion(n - 1) - headRecursion(n - 2) + n;
}
int main(){
cout << endl << headRecursion(3);
return 0;
}
This is kind of an interesting problem. We can start with how to implement as a loop:
int minus2 = 1;
int minus1 = 2;
if (n == 0) return minus2;
if (n == 1) return minus1;
for( int i = 2; i <= n; i++)
{
int next = minus1 * 3 - minus2 + i;
minus2 = minus1;
minus1 = next;
}
return minus1;
The takeaway is we need to count UP. In order to make this tail recursive we need to pass in our accumulators (there is no reason to do this other than to show off, but it adds nothing to readability or efficiency)
int tailRecursive(int minus2, int minus1, int step, int n)
{
if (step == n) return minus1;
return tailRecursive(minus1, minus1*3 - minus2 + step+1, step+1, n);
}
you can use an intermediate to set it up and handle the n==0 case.
int calcIt(int n) {
if (n == 0) return 1;
// step must start with 1, since we handled 0 above
return tailRecursive(1, 2, 1, n);
}
Something along these lines:
std::pair<int, int> next_result(std::pair<int, int> prev_result, int n) {
return {3*prev_result.first - prev_result.second + n, prev_result.first};
}
std::pair<int, int> tailRecursion(int n) {
if (n == 0) {
return {1, 0};
}
if (n == 1) {
return {2, 1};
}
return next_result(tailRecursion(n-1), n);
}
int compute(int n) {
return tailRecursion(n).first;
}
int main(){
std::cout << compute(3) << std::endl;
}
Demo
The key is that you need a function that computes a pair {f(n), f(n-1)} given the previously computed pair {f(n-1), f(n-2)}

Optimizing the function for finding a Hamiltionian cycle in a grid graph?

I've made a working algorithm for finding a Hamiltonian cycle in a grid graph. However, the approach I implemented includes recursively checking all the possible combinations until I find the right one. This is fine on small graphs (like 6*6), but becomes way too slow on bigger ones, the ones that I need to find the cycle for (30 * 30).
In main I initialize a 2D vector of ints, representing out graph (board), and initalize it to -1. -1 represents that this space hasn't been 'filled' yet, while values above that represent their place in the cycle (0 - first cell, 1 - second cell etc.). And I use initialize a Vector2f (SFML's way of doing vectors, same as pairs in standard library), which I use to step all the possible states.
And I also initialize the path integer, which will help up later.And lastly I call the Hamiltionan cycle finding algorithm (HamCycle()).
int main(){
int path = 0;
int bx = 8;
std::vector<std::vector<int>> board{ 8 };
Vector2f pos = { 4 , 4 };
for (int i = 0; i < bx; i++) {
board[i].resize(bx);
for (int j = 0; j < bx; j++) board[i][j] = -1;
}
hamCycle(board, pos, path, bx);
};
Then I hamCycle() I check if pos vector goes outside of the grid, and if so return false. Else I give this cell the value of path, which is then increased. I check if the algorithm is done, and if it's a cycle or just a path. If it's a path, it returns false. Then I recursively check the cells around it and repeat the process.
bool hamCycle(std::vector<std::vector<int>> &board,Vector2f pos, int &path, int bx) {
//check if it's outside the box and if it's already occupied
if (pos.x >= bx || pos.x < 0 || pos.y >= bx || pos.y < 0) return false;
if (board[pos.x][pos.y] != -1) return false;
board[pos.x][pos.y] = path;
path++;
//check if the cycle is completed
bool isDone = true;
if (path != (bx * bx)) isDone = false;
//check if this cell is adjacent to the beggining and if so it's done
if (isDone) {
if (pos.x != 0 && pos.x != (size - 1) && pos.y != 0 && pos.y != (size - 1)) {
if ((board[pos.x + 1][pos.y] == 0) || (board[pos.x - 1][pos.y] == 0) || (board[pos.x][pos.y
+ 1] == 0)
|| (board[pos.x][pos.y - 1] == 0)) {
return true;
}
path--;
board[pos.x][pos.y] = -1;
return false;
}
else {
path--;
board[pos.x][pos.y] = -1;
return false;
};
}
//recursion time
if (hamCycle(board, Vector2f(pos.x + 1, pos.y), path, bx)) return true;
if (hamCycle(board, Vector2f(pos.x - 1, pos.y), path, bx)) return true;
if (hamCycle(board, Vector2f(pos.x, pos.y + 1), path, bx)) return true;
if (hamCycle(board, Vector2f(pos.x, pos.y - 1), path, bx)) return true;
path--;
board[pos.x][pos.y] = -1;
return false;
}
Right now it spends a lot of time checking all possible paths when it has already blocked an exit, which is innefficent. How can I improve this, so checking big grids is feasible? Like not checking if has a blocked exit, but if you know any other methods for improvement, please let me know.
You could try divide and conquer : take your board, divide it into small pieces (let's say 4), and find the right path for each of those pieces. The hard part is to define what is the right path. You need a path coming from the previous piece and going into the next one, passing by each cell. To do that, you can divide those pieces into smaller one, etc, until you have pieces of only one cell.
Note that this approach doesn't give you all the cycles possible, but almost always the same ones.
Finding one Hamiltonian cycle on a grid graph is really not that hard. I implemented it below. I used an std::array for the board because I wanted to train a bit the writing of constexpr functions. For the theoritical explanation, see here.
#include <iostream>
#include <array>
#include <optional>
#include <algorithm>
// Allows iterating of a two dimensional array in the cross direction.
template<typename Iter>
struct cross_iterator {
using difference_type = typename Iter::difference_type;
using value_type = typename Iter::value_type;
using pointer = typename Iter::pointer;
using reference = typename Iter::reference;
using iterator_category = typename Iter::iterator_category;
constexpr cross_iterator(Iter it, size_t pos) : _it(it), _pos(pos)
{}
constexpr auto& operator*() {
return (*_it)[_pos];
}
constexpr auto& operator++() {
++_it;
return *this;
}
constexpr auto& operator++(int) {
_it++;
return *this;
}
constexpr auto& operator--() {
--_it;
return *this;
}
constexpr auto& operator--(int) {
_it--;
return *this;
}
constexpr bool operator==(const cross_iterator<Iter> &other) const {
return _pos == other._pos && _it == other._it;
}
constexpr bool operator!=(const cross_iterator<Iter> &other) const {
return !(*this == other);
}
constexpr auto& operator+=(difference_type n) {
_it += n;
return *this;
}
Iter _it;
const size_t _pos;
};
template<typename Iter>
cross_iterator(Iter it, size_t pos) -> cross_iterator<std::decay_t<decltype(it)>>;
template<size_t N, size_t M = N>
using board = std::array<std::array<int, N>, M>;
template<size_t N, size_t M = N>
constexpr std::optional<board<N, M>> get_ham_cycle() {
if constexpr ( N%2 == 1 && M%2 == 1 ) {
if constexpr( N == 1 && M == 1 ) {
return {{{{0}}}};
}
else {
// There is no Hamiltonian Cycle on odd side grid graphs with side lengths > 1
return {};
}
} else
{
std::optional<board<N,M>> ret {std::in_place};
auto &arr = *ret;
int count = 0;
arr[0][0] = count++;
if constexpr ( N%2 == 0 ) {
for(auto i = 0ul; i < N; ++i) {
// We fill the columns in alternating directions
if ( i%2 == 0 ) {
std::generate(std::next(begin(arr[i])), end(arr[i]), [&count] () { return count++; });
} else {
std::generate(rbegin(arr[i]), std::prev(rend(arr[i])), [&count] () { return count++; });
}
}
std::generate(cross_iterator(rbegin(arr), 0), std::prev(cross_iterator(rend(arr), 0)), [&count] () { return count++; });
} else {
for(auto j = 0ul; j < M; ++j) {
// We fill the rows in alternating directions
if ( j%2 == 0 ) {
std::generate(std::next(cross_iterator(begin(arr)), j), cross_iterator(end(arr), j), [&count] () { return count++; });
} else {
std::generate(cross_iterator(rbegin(arr), j), std::prev(cross_iterator(rend(arr), j)), [&count] () { return count++; });
}
}
std::generate(rbegin(arr[0]), std::prev(rend(arr[0])), [&count] () { return count++; });
}
return ret;
}
}
int main() {
auto arr = *get_ham_cycle<30>();
for(auto i = 0ul; i < 30; ++i) {
for(auto j = 0ul; j < 30; ++j) {
std::cout << arr[i][j] << '\t';
}
std::cout << '\n';
}
return 0;
}
In a grid graph there is a hamilton cycle if and only if the width or the height are even (or both). Start in the top left corner, if the height is odd go all the way down, then up and down repeatedly while leaving one space at the top. When having reached the right corner you can go all the way up and to the left again.
4*5:
S<<<
v>v^
v^v^
v^v^
>^>^
4*4:
S<<<
v>v^
v^v^
>^>^
For odd width, just turn it 90 degree.
This runs in O(width*height).
PS: I'm currently looking for a way to find Hamilton Cycles in a grid graph with restrictions (for implementing a perfect snake player)

Child states in alpha-beta pruning

I'm having trouble with the alpha-beta pruning algorithm from Wikipedia:
function alphabeta(node, depth, α, β, Player)
if depth = 0 or node is a terminal node
return the heuristic value of node
if Player = MaxPlayer
for each child of node
α := max(α, alphabeta(child, depth-1, α, β, not(Player) ))
if β ≤ α
break (* Beta cut-off *)
return α
else
for each child of node
β := min(β, alphabeta(child, depth-1, α, β, not(Player) ))
if β ≤ α
break (* Alpha cut-off *)
return β
Specifically the recursive call of alpha-beta. I keep getting a SegFault error on the first pass of alpha-beta.
Here is my alpha-beta function:
int alphabeta(int board[9], int depth, int alpha, int beta, bool max_player) {
int score = 0;
max_player = true;
if(depth == 0){
return score;
}
if(max_player) {
alpha = INT_MIN;
while (depth != 0) {
score = alphabeta(board[9], depth - 1, alpha, beta, !max_player); <--- where error originates
alpha = MAX(alpha, score );
if (beta <= alpha) break;
}
return alpha;
}
else {
beta = INT_MAX;
while (depth != 0) {
score = alphabeta(board[9], depth - 1, alpha, beta, !max_player);
beta = MIN(beta, score );
if (beta <= alpha) break;
}
return beta;
}
}
with the overall implementation here:
# include "stdio.h"
# include "limits.h"
int MAX (int x, int y) {
if (x > y) {
return x;
}
else {
return y;
}
}
int MIN (int x, int y) {
if (x < y) {
return x;
}
else {
return y;
}
}
char gridChar(int i) {
switch(i) {
case -1:
return 'X';
case 0:
return ' ';
case 1:
return 'O';
}
}
void draw(int b[9]) {
printf(" %c | %c | %c\n",gridChar(b[0]),gridChar(b[1]),gridChar(b[2]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[3]),gridChar(b[4]),gridChar(b[5]));
printf("---+---+---\n");
printf(" %c | %c | %c\n",gridChar(b[6]),gridChar(b[7]),gridChar(b[8]));
}
int win(const int board[9]) {
//determines if a player has won, returns 0 otherwise.
unsigned wins[8][3] = {{0,1,2},{3,4,5},{6,7,8},{0,3,6},{1,4,7},{2,5,8},{0,4,8},{2,4,6}};
int i;
for(i = 0; i < 8; ++i) {
if(board[wins[i][0]] != 0 &&
board[wins[i][0]] == board[wins[i][1]] &&
board[wins[i][0]] == board[wins[i][2]])
return board[wins[i][2]];
}
return 0;
}
int alphabeta(int board[9], int depth, int alpha, int beta, bool max_player) {
int score = 0;
max_player = true;
if(depth == 0){
return score;
}
if(max_player) {
alpha = INT_MIN;
while (depth != 0) {
score = alphabeta(board[9], depth - 1, alpha, beta, !max_player);
alpha = MAX(alpha, score );
if (beta <= alpha) break;
}
return alpha;
}
else {
beta = INT_MAX;
while (depth != 0) {
score = alphabeta(board[9], depth - 1, alpha, beta, !max_player);
beta = MIN(beta, score );
if (beta <= alpha) break;
}
return beta;
}
}
void computerMove(int board[9]) {
int move = -1;
int score = -2;
int i;
for(i = 0; i < 9; ++i) {
if(board[i] == 0) {
board[i] = 1;
int tempScore = -alphabeta(board[9],6, -10000, 10000, true);
board[i] = 0;
if(tempScore > score) {
score = tempScore;
move = i;
}
}
}
//returns a score based on minimax tree at a given node.
board[move] = 1;
}
void playerMove(int board[9]) {
int move = 0;
do {
printf("\nInput move ([0..8]): ");
scanf("%d", &move);
printf("\n");
} while (move >= 9 || move < 0 && board[move] == 0);
board[move] = -1;
}
int main() {
int board[9] = {0,0,0,0,0,0,0,0,0};
//computer squares are 1, player squares are -1.
printf("Computer: O, You: X\nPlay (1)st or (2)nd? ");
int player=0;
scanf("%d",&player);
printf("\n");
unsigned turn;
for(turn = 0; turn < 9 && win(board) == 0; ++turn) {
if((turn+player) % 2 == 0)
computerMove(board);
else {
draw(board);
playerMove(board);
}
}
switch(win(board)) {
case 0:
printf("A draw. How droll.\n");
break;
case 1:
draw(board);
printf("You lose.\n");
break;
case -1:
printf("You win. Inconceivable!\n");
break;
}
}
I'm thinking that my implementation is not correctly identifying the "child nodes" of the current board, but I am lost as to how to code that with regard to an array of integers. Any advice would be greatly appreciated.
One error is here (and you are making similar mistakes in other places in your code):
score = alphabeta(board[9], depth - 1, alpha, beta, !max_player);
The first parameter, board[9] is accessing an out-of-bounds element of the board array. You're sending a single int, namely board[9], but board[9] is an element that is out-of-bounds of board, thus you're invoking undefined behavior.
I don't know what your intentions are with the code above, but if you are trying to pass the buffer pointed to by board:
score = alphabeta(board, depth - 1, alpha, beta, !max_player);
If you're trying to pass the last element of the board:
score = alphabeta(board[8], depth - 1, alpha, beta, !max_player);
In addition, if you're not aware, function prototypes like this:
int win(const int board[9])
are no different than this:
int win(const int* board)
Arrays decay to pointers -- you are not actually passing an array.
The example here shows what the program would look like when corrected (the runtime error is due to missing input).
You also have some very suspicious code, for example:
while (move >= 9 || move < 0 && board[move] == 0);
If move < 0, you are accessing board with a negative index, which is another out-of-bounds access.

Counting total Paths from (0,0) to (n-1,n-1) in a n*n grid

I am using a simple backtracking algorithm to find all the paths but it does not give the right answer. I am not able to figure out the mistake. We can move up, down, left and right from a given position.
Int path(int a[][200],int n,int m,int r,int c)
{
if(n == r - 1 && m == c-1) {
return 1;
}
else if(n >= r || m >= c || n < 0 || m < 0) {
return 0;
}
else if(vis[n][m] == 1) {
return 0;
}
else {
vis[n][m] = 1;
int x = path(a,n+1,m,r,c);
int y = path(a,n,m+1,r,c);
int u = path(a,n-1,m,r,c);
int v = path(a,n,m-1,r,c);
vis[n][m] = 0;
return (x+y+u+v);
}
}
To find the paths or count the paths are not exactly the same thing. I will assume you want to just count the paths (because the title of your question), and that you can only move right or move down.
For this you don't really need a matrix (representing the grid) as a parameter. The following is a simple (although not efficient) recursive solution that also will work for a n*m grid:
int countPaths(int m, int n) {
if (m == 0 || n == 0)
return 1;
return countPaths(m-1, n) + countPaths(m, n-1);
}
The mathematical solution for the general n*n grid is:
(2n choose n) = (2*n)!/(n!*n!)
Then, comparing results with the formula:
countPaths(1, 1) == 2 // (2*1)!/(1!*1!)=2
countPaths(2, 2) == 6 // (2*2)!/(2!*2!)=6
countPaths(3, 3) == 20 // (2*3)!/(3!*3!)=20
Your backtracking approach will give the same results, but with some considerations. For example, consider when n=2, you will need a 3x3 matrix (and in general a (n+1)x(n+1) matrix) to represent/explore (and mark with 1) all the paths for the 2x2 grid:
int countPaths(int a[][3],int n, int m, int r, int c) {
if(n == r-1 && m == c-1) {
return 1;
}
else if(n >= r || m >= c || n < 0 || m < 0) {
return 0;
}
else if(vis[n][m] == 1) {
return 0;
}
else {
vis[n][m] = 1;
int x = countPaths(a,n+1,m,r,c);
int y = countPaths(a,n,m+1,r,c);
vis[n][m] = 0;
return (x+y);
}
}
Then:
countPaths(vis, 0, 0, 3, 3) == 6 // (2*2)!/(2!*2!)=6

Perfect square and perfect cube

Is there any predefined function in c++ to check whether the number is square of any number and same for the cube..
No, but it's easy to write one:
bool is_perfect_square(int n) {
if (n < 0)
return false;
int root(round(sqrt(n)));
return n == root * root;
}
bool is_perfect_cube(int n) {
int root(round(cbrt(n)));
return n == root * root * root;
}
sqrt(x), or in general, pow(x, 1./2) or pow(x, 1./3)
For example:
int n = 9;
int a = (int) sqrt((double) n);
if(a * a == n || (a+1) * (a+1) == n) // in case of an off-by-one float error
cout << "It's a square!\n";
Edit: or in general:
bool is_nth_power(int a, int n) {
if(n <= 0)
return false;
if(a < 0 && n % 2 == 0)
return false;
a = abs(a);
int b = pow(a, 1. / n);
return pow((double) b, n) == a || pow((double) (b+1), n) == a;
}
No, there are no standard c or c++ functions to check whether an integer is a perfect square or a perfect cube.
If you want it to be fast and avoid using the float/double routines mentioned in most of the answers, then code a binary search using only integers. If you can find an n with n^2 < m < (n+1)^2, then m is not a perfect square. If m is a perfect square, then you'll find an n with n^2=m. The problem is discussed here
Try this:
#include<math.h>
int isperfect(long n)
{
double xp=sqrt((double)n);
if(n==(xp*xp))
return 1;
else
return 0;
}
The most efficient answer could be this
int x=sqrt(num)
if(sqrt(num)>x){
Then its not a square root}
else{it is a perfect square}
This method works because of the fact that x is an int and it will drop down the decimal part to store only the integer part. If a number is perfect square of an integer, its square root will be an integer and hence x and sqrt(x) will be equal.
For identifying squares i tried this algorithm in java. With little syntax difference you can do it in c++ too.
The logic is, the difference between every two consecutive perfect squares goes on increasing by 2. Diff(1,4)=3 , Diff(4,9)=5 , Diff(9,16)= 7 , Diff(16,25)= 9..... goes on.
We can use this phenomenon to identify the perfect squares.
Java code is,
boolean isSquare(int num){
int initdiff = 3;
int squarenum = 1;
boolean flag = false;
boolean square = false;
while(flag != true){
if(squarenum == num){
flag = true;
square = true;
}else{
square = false;
}
if(squarenum > num){
flag = true;
}
squarenum = squarenum + initdiff;
initdiff = initdiff + 2;
}
return square;
}
To make the identification of squares faster we can use another phenomenon, the recursive sum of digits of perfect squares is always 1,4,7 or 9.
So a much faster code can be...
int recursiveSum(int num){
int sum = 0;
while(num != 0){
sum = sum + num%10;
num = num/10;
}
if(sum/10 != 0){
return recursiveSum(sum);
}
else{
return sum;
}
}
boolean isSquare(int num){
int initdiff = 3;
int squarenum = 1;
boolean flag = false;
boolean square = false;
while(flag != true){
if(squarenum == num){
flag = true;
square = true;
}else{
square = false;
}
if(squarenum > num){
flag = true;
}
squarenum = squarenum + initdiff;
initdiff = initdiff + 2;
}
return square;
}
boolean isCompleteSquare(int a){
// System.out.println(recursiveSum(a));
if(recursiveSum(a)==1 || recursiveSum(a)==4 || recursiveSum(a)==7 || recursiveSum(a)==9){
if(isSquare(a)){
return true;
}else{
return false;
}
}else{
return false;
}
}
For perfect square you can also do:
if(sqrt(n)==floor(sqrt(n)))
return true;
else
return false;
For perfect cube you can:
if(cbrt(n)==floor(cbrt(n)))
return true;
else
return false;
Hope this helps.
We could use the builtin truc function -
#include <math.h>
// For perfect square
bool is_perfect_sq(double n) {
double r = sqrt(n);
return !(r - trunc(r));
}
// For perfect cube
bool is_perfect_cube(double n) {
double r = cbrt(n);
return !(r - trunc(r));
}
bool isSquare(int n) {
return floor(sqrt(n)) == ceil(sqrt(n));
}
bool isQube(int n) {
return floor(cbrt(n)) == ceil(cbrt(n));
}