Directi Interview Question
Software Engineer / DevelopersI hope people on this site make statements using reasoning rather than as an opinion. Because as humans we understand and learn based on reasoning.
ok..lemme try my hand at it..
Consider an output matrix M, defined as below,to be computed
M(i,j)= maximum grass that could be consumed on any path starting at 1,1 and ending at i,j subject to movement direction constraints (right and bottom from the current position)
Then the solution to the problem would be M(m,n)(think why?) [m and n denote the number of rows and cols respectively in M and A(the input matrix)]
We now need to set up a recurrence relation for M(i,j) and evaluate M(m,n) using the same.
Observation : to reach (i,j) , we can reach (i-1,j) and move down or reach (i,j-1) and move right.
So M(i,j) = max(M(i-1,j),M(i,j-1)) + A(i,j)
Run this in a nested loop setting M(1,1) = A(1,1)
Here is an example :-
A[4][4] = 1,7,5,2
5,12,3,6
100,9,23,16
16,4,5,9
The path would be {1,5,100,9,23,16,9}
Note that here 100 maximizes the sum .
<pre lang="c++" line="1" title="CodeMonkey5181" class="run-this">Can anyone check this code although I have tested it twice it runs fine according to me . Also comment on complexity .
#include<iostream>
#include<conio.h>
using namespace std;
int a[4][4] =
{
{ 1,7,5,2 },
{ 5,12,3,6 },
{ 100,9,23,16 },
{ 16,4,5,9 },
};
int m=4,n=4;
int path(int sum , int i , int j)
{
if(j==(n-1)&&i==(m-1))
return sum;
if(i==(m-1))
return path(sum+a[i][j+1],i,j+1);
if(j==(n-1))
return path(sum+a[i+1][j],i+1,j);
else
{
int sum1 = path(sum+a[i+1][j],i+1,j);
int sum2 = path(sum+a[i][j+1],i,j+1);
int sum3 = (sum1>sum2)?sum1:sum2;
return sum3;
}
}
int main()
{
cout<<path(a[0][0],0,0);
getch();
}
</pre>
Code based on comment from Anonymous' comment
//dp[i][j] = max(dp[i-1][j],dp[i][j-1])+a[i][j];
/* //! Complexity for a nxn matrix is O(nxn) i.e. Linear (since nxn elements)
*/
#include <iostream>
#include <vector>
using namespace std;
int main(){
int arr[4][4] =
{ { 1,7,5,2 },
{ 5,12,3,6 },
{ 100,9,23,16 },
{ 16,4,5,9 },
};
int n=4;
vector<vector<int> > maxRoute(n,vector<int> (n,0)); //initialize vector
//dp[i][j] = max(dp[i-1][j],dp[i][j-1])+a[i][j]; //Dynamic programming //from Anonymous
for(int i=0;i<n;++i){ //move right
for(int j=0;j<n;++j){ //move down
if(i==0 && j==0)
maxRoute[i][j] = arr[i][j];
else if(i==0 && j!=0)
maxRoute[i][j] = arr[i][j]+maxRoute[i][j-1];
else if(i!=0 && j==0)
maxRoute[i][j] = arr[i][j]+maxRoute[i-1][j];
else
maxRoute[i][j] = max(maxRoute[i-1][j],maxRoute[i][j-1])+arr[i][j];
}
}
cout<<"Max grass ::"<<maxRoute[n-1][n-1]<<endl;
}
please suggest if any thing's wrong,Thanks.
The code of the solution in c using Dynamic Programming:
#include<stdio.h>
int main()
{
// a holds the grass values
int a[4][4]={
{ 1,7,5,2 },
{ 5,12,3,6 },
{ 100,9,23,16 },
{ 16,4,5,9 },
};
int m=4,n=4;
// sum[i][j] holds the maximum grass that can be eaten if the goat goes from a[i][j] point to a[m-1][n-1]
// sum[0][0] == the maximum amount of grass the goat eats
// we build the matrix sum using dynamic programming paradigm
int sum[m][n];
// move[i][j] stores the next best move from a[i][j], that will allow the goat to eat maximum grass on its path from a[i][j] to a[m-1][n-1]
// move[i][j]='r' : move right
// move[i][j]='d' : move down
char move[m][n];
// calculate the solution and max grass to eat using the relation: sum[i][j] = a[i][j] + max(sum[i-1][j],sum[i][j-1])
int i,j;
for(i=m-1;i>=0;i--){
for(j=n-1;j>=0;j--){
if(i == m-1 && j == n-1 ){
sum[i][j] = a[i][j];
}
else if(i == m-1 ){
sum[i][j] = a[i][j] + sum[i][j+1];
move[i][j]='r';
}
else if(j == n-1 ){
sum[i][j] = a[i][j] + sum[i+1][j];
move[i][j] = 'd';
}
else if(sum[i][j+1]>sum[i+1][j]){
sum[i][j]= a[i][j] + sum[i][j+1] ;
move[i][j] = 'r';
}
else{
sum[i][j]= a[i][j] +sum[i+1][j];
move[i][j]='d';
}
}
}
// Output the best move solution
i=0;
j=0;
while(i< (m-1) || j< (n-1)){
printf("\nEat: a[%d][%d]=%d\n",i,j,a[i][j]);
if(move[i][j]=='r'){
printf("move right\n");
j++;
}
else{
printf("move down\n");
i++;
}
}
printf("\nEa: a[%d][%d] = %d\n",i,j,a[i][j]);
printf("total grass eaten: %d\n",sum[0][0]);
return 0;
}
<pre lang="" line="1" title="CodeMonkey14944" class="run-this">package Directi;
public class DynamicProgramming {
int rows = 0;
int columns = 0;
public static void main(String[] args){
DynamicProgramming dp = new DynamicProgramming();
int[][] array = {{1, 3, 1},{1, 4, 3},{12, 1, 1}};
dp.rows = array.length;
dp.columns = array[0].length;
System.out.println(dp.maximumGrass(0, 0, array));
}
int maximumGrass(int x, int y, int[][] array){
if(x == (rows-1) && y == (columns-1)){
return array[x][y];
} else if( y ==(columns-1)){
return ( maximumGrass(x + 1, y, array) + array[x][y]);
} else if( x == (rows-1)){
return (maximumGrass(x, y + 1, array) + array[x][y]);
} else{
return (Math.max(maximumGrass(x+1, y, array), maximumGrass(x, y+1, array)) + array[x][y]);
}
}
}
</pre>
#include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define INFINITY 1<<31
struct e
{
int val,i,j;
};
class compare
{
public:
bool operator()(e &x,e &y)
{
if(x.val<y.val)
return true;
return false;
}
};
main()
{
int n;
e temp;
vector<vector<int> > arr2d;
priority_queue<e,vector<e>,compare> q;
cout<<"Enter the matrix size and matrix on which goat will move: ";
cin>>n;
char parent[n][n];int cost[n][n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++) cost[i][j]=-INFINITY;
arr2d.resize(n);
for(int i=0;i<n;i++) arr2d[i].resize(n);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>arr2d[i][j];
cost[0][0]=arr2d[0][0];
temp.val=arr2d[0][0];temp.i=temp.j=0;
q.push(temp);
while(!q.empty())
{
e temp1;
temp=q.top();
q.pop();
if(temp.i+1<n)
{
if(cost[temp.i+1][temp.j]<temp.val+arr2d[temp.i+1][temp.j])
{
cost[temp.i+1][temp.j]=temp.val+arr2d[temp.i+1][temp.j];
parent[temp.i+1][temp.j]='u';
}
temp1.val=cost[temp.i+1][temp.j];temp1.i=temp.i+1;temp1.j=temp.j;
q.push(temp1);
}
if(temp.j+1<n)
{
if(cost[temp.i][temp.j+1]<temp.val+arr2d[temp.i][temp.j+1])
{
cost[temp.i][temp.j+1]=temp.val+arr2d[temp.i][temp.j+1];
parent[temp.i][temp.j+1]='l';
}
temp1.val=cost[temp.i][temp.j+1];temp1.i=temp.i;temp1.j=temp.j+1;
q.push(temp1);
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
cout<<parent[i][j]<<" ";
cout<<endl;
}
cout<<endl<<cost[n-1][n-1]<<endl;
}
dynamic programming...
- biswa November 03, 2010