Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Consider the following recursive C function that takes two arguments.
unsigned int foo(unsigned int n, unsigned int r)
{
if (n > 0)
return (n % r) + foo(n / r, r);
else
return 0;
}
What is value of function foo when it called as foo(512,2)?
This code ,actually is a recursion.
follow the return happened:
If n == 0; return 0;
If n == 1; return 1+foo(0,2)
If n == 2; return 0 + foo(1,2);
If n == 4; return 0 + foo(2,2);
...
if n == 2^n return 0 + foo(0+foo(z^n-1,2));
....
So foo(512,2) == foo (2^n,2) == 0+f(1,2) == 1 +f(0,2) = 1;
It return 1.
Your result is going to be 1. Here is what happens:
First call: n = 512, r = 2, n % r = 0; calls foo (256, 2)
Second call: n = 256, r= 2, n % r = 0; calls foo (128, 2)
Third call: n = 128, r = 2, n % r = 0; calls foo (64, 2)
Fourth call: n = 64, r = 2, n % r = 0; calls foo (32, 2)
Fifth call: n = 32, r = 2, n % r = 0; calls foo (16, 2)
Sixth call: n = 16, r = 2, n % r = 0; calls foo (8, 2)
Seventh call: n = 8, r = 2, n % r = 0; calls foo (4, 2)
Eighth call: n = 4, r = 2, n % r = 0; calls foo (2, 2)
Ninth call: n = 2, r = 2, n % r = 0; calls foo (1, 2)
Tenth call: n = 1, r = 2, n % r = 1; calls foo (0, 2)
Eleventh call: n = 0, r = 2; returns 0
Tenth call returns 1 + 0 = 1
Ninth call and subsequent calls all return 0 + 1 = 1
Unwinding is complete and the function returns 1.
Related
So I'm trying to make a recursive function that takes an integer, let's say 123, and gives back double every single digit in the integer. So 123 would become 248, not 246. The main difference obviously is that instead of doing 123x2, you do (100x2)+(20x2)+(3x2). There is also the condition that if any of the numbers are equal to or greater than 5, you replace it with a 9, so 345 becomes 689. I am trying to create it iteratively before making it recursively and I am running into an issue with the conditions. Heres what I have so far:
int double_digit(int g) {
int dubl = 0;
int mod = 10;
int i = 1;
while (g > 0) {
mod = pow(10, i);
if (g % 10 < 5) {
dubl = dubl + g % mod * 2;
g = g - (g % mod);
i++;
}
else {
dubl = dubl + (9 * (mod / 10));
g = g - (g % mod);
i++;
}
}
printf("%d", dubl);
}
If you run the code, you will see that it works for numbers under 5, but not greater than or equal to, how can I fix it?
WAY too complicated... A lookup table will shrink the code down to almost nothing. This even tries to protect against receiving a negative number.
int double_digit(int g) {
int dd = 0;
for( int w = abs(g), pow = 1; w; w /= 10, pow *= 10 )
dd += pow * "\0\02\04\06\10\011\011\011\011\011"[ w % 10 ];
return g < 0 ? 0 - dd : dd;
}
int main() {
int tests[] = { 42, 256, 123, 578, -3256, };
for( int i = 0; i < sizeof tests/sizeof tests[0]; i++ )
printf( "%d = %d\n", tests[i], double_digit( tests[i] ) );
return 0;
}
42 = 84
256 = 499
123 = 246
578 = 999
-3256 = -6499
EDIT:
C's understanding of octal bytes specified in a character array (aka string) may be new.
Here is an abridged alternative that may not be as confrontational:
int lut[] = { 0, 2, 4, 6, 8, 9, 9, 9, 9, 9, };
for( int w = abs(g), pow = 1; w; w /= 10, pow *= 10 )
dd += pow * lut[ w % 10 ];
And, then there are branchless techniques (overkill in this instance, but useful to consider in other applications):
for( int d, w = abs(g), pow = 1; w; w /= 10, pow *= 10 )
d = (w%10)<<1, dd += pow * (d*(d<9)+(d>8)*9);
In other words, there are lots of ways to achieve objectives. A good exercise is to try to discover those different ways and then to consider where each may be used to the most benefit (and where other methods may not appropriate or as clear.) Write clean, clear, concise code to the best of your abilities.
I've written the recursive version. Without accounting for negative values, the recursive version requires, to the best of my abilities, more code and takes a 'linear' (iterative) problem into other dimensions. Make the method fit the problem, not vice versa.
I'm trying to solve this problem:
Given a matrix of n * m, with letters(characters), find the longest consecutive path of letters in the matrix and output the string. For example:
m = [[a,c,d],[i,b,e],[h,g,f]]
result = e,f,g,h
You can only move up, down, left, right inside the matrix. This is what I have come up so far following some information online, but I'm not all the way there.
I would also like to make the solution efficient, my current code might have too many loops and is probably slow for a large matrix. Any help would be really appreciated!
R = len(matrix)
C = len(matrix[0])
x = [0, 1, 0, -1]
y = [1, 0, -1, 0]
dp=[[0 for i in range(C)]for i in range(R)]
def isvalid( i, j):
if (i < 0 or j < 0 or i >= R or j >= C):
return False
return True
def getLenUtil(matrix, i, j, prev):
if (isvalid(i, j)==False or isadjacent(prev, mat[i][j])==False):
return 0
if (dp[i][j] != -1):
return dp[i][j]
ans = 0
for k in range(4):
ans = max(ans, 1 + getLenUtil(mat, i + x[k],j + y[k], mat[i][j]))
dp[i][j] = ans
return dp[i][j]
def isadjacent(prev, curr):
if (ord(curr) -ord(prev)) == 1:
return True
return False
def findLongestSequence(matrix):
for i in range(R):
for j in range(C):
dp[i][j]=-1
ans = 0
for i in range(R):
for j in range(C):
if (mat[i][j] == s):
for k in range(4):
ans = max(ans, 1 + getLenUtil(matrix, i + x[k], j + y[k], s));
return ans
Several issues in your code:
mat and matrix spelling should be unified.
s is never initialised
In R = len(matrix) and several other references to mat or matrix, that variable is not defined. findLongestSequence is called with the actual value of matrix, so it is there there R should be defined, ...etc
Also,
it is easier if you don't pass prev, but the actual expected character (that is already "incremented").
Why first initialise dp with zeroes, when then you re-initialise with -1? Just use -1 immediately.
Here is how it could work:
def findLongestSequence(mat):
R = len(mat)
C = len(mat[0])
x = [0, 1, 0, -1]
y = [1, 0, -1, 0]
dp = [[-1 for i in range(C)] for i in range(R)]
def isvalid( i, j):
return (0 <= i < R) and (0 <= j < C)
def getLenUtil(mat, i, j, expected):
if not isvalid(i, j) or mat[i][j] != expected:
return 0
if dp[i][j] == -1:
ans = 0
expected = chr(ord(mat[i][j])+1)
for k in range(4):
ans = max(ans, 1 + getLenUtil(mat, i + x[k], j + y[k], expected))
dp[i][j] = ans
return dp[i][j]
ans = 0
for i in range(R):
for j in range(C):
getLenUtil(mat, i, j, mat[i][j])
ans = max(ans, max(dp[i]))
print(dp)
return ans
res = findLongestSequence([["a","c","d"],["i","b","e"],["h","g","f"]])
print(res)
Note that for this example data the returned answer is 8, not 4, as the longest sequence starts with "b" and ends with "i" -- 8 characters in total.
I am unable to figure out the why my code is not able to satisfy a test case for the question while editorial's code is working fine.
Question:
You are in an infinite 2D grid where you can move in any of the 8 directions :
(x, y) to
(x+1, y),
(x-1, y),
(x, y+1),
(x, y-1),
(x-1, y-1),
(x+1, y+1),
(x-1, y+1),
(x+1, y-1)
You are given a sequence of points and the order in which you need to cover the points. Give the minimum number of steps by which you can achieve it. You start from the first point.
Input:
Given two integer arrays A and B, where A[i] is x coordinate and B[i] is y coordinate of the ith point, respectively.
Output:
Return an Integer, (i.e minimum number of steps).
Example:
Input : [(0, 0), (1, 1), (1, 2)]
Output : 2
It takes one step to move from (0, 0) to (1, 1). It takes one more step to move from (1, 1) to (1, 2).
my code:-
int coverPoints(int *A, int n1, int *B, int n2) {
int count = 0, ele1 = 0, ele2 = 0, i;
for (i = 0; i < n1 - 1; i++) {
ele1 = abs(A[i+1] - A[i]);
ele2 = abs(B[i+1] - A[i]);
if (ele1 > ele2) {
count += ele1;
} else {
count += ele2;
}
}
return count;
}
editorial solution:-
int coverPoints(int *X, int n1, int *Y, int n2) {
int stepsx = 0, stepsy = 0, diffx = 0, diffy = 0, steps = 0;
int i = 0;
for(i = 0; i < (n1-1); i++) {
diffx = X[i+1] - X[i];
if (diffx < 0)
diffx = diffx * (-1);
//stepsx = stepsx + diffx;
diffy = Y[i+1] - Y[i];
if (diffy < 0)
diffy = diffy * (-1);
//stepsy = stepsy + diffy;
if (diffx > diffy)
steps = steps + diffx;
else
steps = steps + diffy;
}
return steps;
}
The test case that is not working is: -
A : [ 4, 8, -7, -5, -13, 9, -7, 8 ]
B : [ 4, -15, -10, -3, -13, 12, 8, -8 ]
expected output = 108
my output = 105
There is a problem in this line
ele2 = abs(B[i+1]-A[i]);
diffy = Y[i+1] - Y[i];
it will be :
ele2 = abs(B[i+1]-B[i]);
There is a copy+paste typo in ele2 = abs(B[i+1] - A[i]);. The code should be:
ele2 = abs(B[i+1] - B[i]);
I'd like to use the Array octave_idx_type as an index vector to insert a matrix into an NDArray ( see stackoverflow thread here ) as in
A.insert( B , Array<octave_idx_type> ) ;
where the array A is 3-dimensional. I know that I can use
A.insert( B , 0 , 0 ) ;
to insert into the first "page" but it is important that I be able to insert into the other pages of A in a loop, presumably by changing the idx_vector values for the page once in each loop.
How do I create this idx_type array?
Hava a look at the Array C'tors: http://octave.sourceforge.net/doxygen41/d0/d26/classArray.html
You can do for example
Array<octave_idx_type> p (dim_vector (3, 1));
as standalone example:
int n = 2;
dim_vector dim(n, n, 3);
NDArray a_matrix(dim);
for (octave_idx_type i = 0; i < n; i++)
for (octave_idx_type j = 0; j < n; j++)
a_matrix(i,j, 1) = (i + 1) * 10 + (j + 1);
std::cout << a_matrix;
Matrix b_matrix = Matrix (n, n);
b_matrix(0, 0) = 1;
b_matrix(0, 1) = 2;
b_matrix(1, 0) = 3;
b_matrix(1, 1) = 4;
std::cout << b_matrix;
Array<octave_idx_type> p (dim_vector (3, 1), 0);
p(2) = 2;
a_matrix.insert (b_matrix, p);
std::cout << a_matrix;
the last cout:
0
0
0
0
11
21
12
22
1
3
2
4
This was an interview question:
Given a sequence of n numbers (n can be any number, assume n <= 100 for this question), say for eg. 11, 23, 9, 17, 20, 8, 5, 6 . Problem is to write a recursive function in C to add each number in the sequence to get the sum. If this sum is of more than one digit then sum the digits again and again if the sum is of more than one digit then sum the digits again. Follow this process until the sum is reduced to one digit no. Now add all the sums obtained in the process to output the final sum.
For illustration take above sequence: 11, 23, 9, 17, 20, 8, 5, 6
SUM(11, 23, 9, 17, 20, 8, 5, 6) = 99 => SUM(9, 9) = 18 => SUM(1, 8) = 9
Now add all the sums obtained, i.e. SUM(99, 18, 9) = 126 <== should be the output.
Please note that the function should be a recursive function in C.
Not sure about C, but the algorithm would look similar to this.
SUM(1, 2, ... n) = 1 + SUM(2, ... n) and so on to get the total, then repeat once the final number is found to be more than one digit.
Here's an Erlang implementation you could use as a guide
-module('summation').
-export([start/1]).
sumlist(List)->
lists:foldl(fun(X, Sum) -> X + Sum end, 0, List). << Inherently recursive
num_to_list(Value) ->
Str = integer_to_list(Value),
lists:map(fun(X) -> X - 48 end, Str). << Inherently recursive
accumulate([_H], List) ->
io:fwrite("~w~n", [List]),
List;
accumulate(Value, List) ->
Tmp = sumlist(Value),
accumulate(num_to_list(Tmp), [Tmp|List]). % << Recurse here
start(List)->
Value = accumulate(List, []),
sumlist(Value).
testing
25> c(summation).
{ok,summation}
26> summation:start([11, 23, 9, 17, 20, 8, 5, 6]).
[9,18,99]
126
27>
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
const int n = 8;
int sumDigits(int x)
{
int d = 0;
while (x != 0)
{
d += x % 10;
x /= 10;
}
return d;
}
int sumArr(int* a, int start)
{
return (start == n)? 0: a[start] + sumArr(a, start + 1);
}
int sum(int x)
{
return (x < 10)? x: x + sum(sumDigits(x));
}
int main(int argc, _TCHAR* argv[])
{
int* a = new int[n];
a[0] = 11; a[1] = 23; a[2] = 9; a[3] = 17; a[4] = 20; a[5] = 8; a[6] = 5; a[7] = 6;
//for (int i = 0; i < n; i++) a[i] = rand() % 100;
//for (int i = 0; i < n; i++) printf("a[%d] = %d\n", i, a[i]);
printf("sum = %d\n", sum(sumArr(a, 0)));
return 0;
}
This outputs:
sum = 126
Here's a Scala implementation:
def sum(lst: List[Int]): Int = {
val sum1 = lst.reduceLeft(_+_)
println(sum1)
sum1 match {
case nb if nb < 10 => sum1
case _ => {
val lst2 = sum1.toString.toList.map(_.toString).map(Integer.parseInt(_))
sum1 + sum(lst2)
}
}
}
val lst = List(11, 23, 9, 17, 20, 8, 5, 6)
val totalSum = sum(lst)
println(totalSum)
Result:
99
18
9
126
I'm really beginning to love, how concise Scala is.
As others had said : the point here is to understand the recursion.
There are 3 place we can use recursion :
sum all the digits in a Integral number:
sum_digital :: (Integral a) => a -> a
sum_digital d
| d < 10 = d
| otherwise = d `mod` 10 + sum_digital (d `div` 10)
chain all the sums from a start value and the rules
chain :: (Integral a) => a -> [a]
chain a
| a < 10 = [a]
| otherwise = a : chain (sum_digital a)
final one. sum of a list
mySum :: (Integral a) => [a]-> a
mySum [] = 0
mySum (x:xs) = x + mySum xs
Put all these together:
*Main> mySum $ chain $ mySum [11, 23, 9, 17, 20, 8, 5, 6]
126
The C version is left for you as the exercise:)
I just want to add this one to 77v's answer in order to make everything hardcore recursive as possible. I know this is a year ago already, and his C++ solution works quite nice already. But I really had no fun that I though I can make that one last function called sumDigits in to recursion. So to rid myself of boredom, here it is:
long sumDigits(long x, long d = 0)
{
if (x != 0)
{
d = x % 10;
return d + sumDigits(x / 10, d);
}
else
return 0;
}
It's the same, 7 lines long and accepts one argument. Note that the second one is defaulted to 0. It's used as a memory for the recursion itself. The user may ignore that second argument entirely. The function is also used the same way as 77v's implementation. You can in fact directly replace his function with this one. Hence making all the function in his solution recursion based. Which makes an already awesome work more awesome! Lol! :D
#include <iostream>
using namespace std;
class RecursiveSum {
public:
int nDigits(int a) {
int d = 0;
while (a > 0) {
d++;
a /= 10;
}
return d;
}
long sum(int *arr, int b, int e, int s) {
if (!arr)
return 0;
if (b < e) {
s += arr[b++];
return sum(arr, b, e, s);
} else { // b >= e
if (s < 10)
return s;
int nd = nDigits(s);
int* narr = new int[nd];
long n = s, itr = 0;
while (n > 0) {
narr[itr++] = n % 10;
n /= 10;
}
s += sum(narr, 0, nd, 0);
delete[] narr;
return s;
}
}
};