GfG QA is closing soon... Please refer PRACTICE or GfG now on wards !!

Microsoft Interview Question!

You are given a matrix of dimensions m*n where each cell in the matrix can have values 0,1 or 2 which has the following meaning :

0:empty cell

1:cells have fresh oranges

2:cells have rotten oranges

So we have to determine what is the minimum time required so that all the oranges will be rotten.A rotten orange at index [i,j] can rot other fresh orange at indexes [i+1,j] ,[i,j+1] ,[i-1,j] ,[i,j-1]. If it is impossible to rot every orange then simply return -1.

asked Aug 5, 2015 by cu

6 Answers

// Author :: Gaurav Ahirwar
#include<bits/stdc++.h>
#define FOR(i,n) for(int i=(0);i<(n);i++)
#define R 3
#define C 5
using namespace std;
typedef long long int ll;
 
bool isvalid(int i, int j) {
	if(i < 0 || j < 0 || i >= R || j >= C) return false;
	else return true;
}
 
struct ele {
	int x;
	int y;
};
 
bool isdelim(ele temp) {
	if(temp.x == -1 && temp.y == -1) return true;
	else return false;
}
 
bool checkall(int arr[][C]) {
	FOR(i,R) FOR(j,C) if(arr[i][j] == 1) return true;
	return false;
}
 
void solve(int arr[][C]) {
 
	queue<ele> Q;
	ele temp;
	int ans = 0;
 
	FOR(i,R) {
		FOR(j,C) {
			if(arr[i][j] == 2) {
				temp.x = i;
				temp.y = j;
				Q.push(temp);
			}
		}
	}
 
	temp.x = -1;
	temp.y = -1;
	Q.push(temp);
 
	while(!Q.empty()) {
 
		bool flag = false;
 
		while(!isdelim(Q.front())) {
 
			temp = Q.front();
 
			if(isvalid(temp.x+1, temp.y) && arr[temp.x+1][temp.y] == 1) {
				if(!flag) ans++, flag = true;
				arr[temp.x+1][temp.y] = 2;
				temp.x++;
				Q.push(temp);
				temp.x--;
			}
 
			if(isvalid(temp.x-1, temp.y) && arr[temp.x-1][temp.y] == 1) {
				if(!flag) ans++, flag = true;
				arr[temp.x-1][temp.y] = 2;
				temp.x--;
				Q.push(temp);
				temp.x++;
			}
 
			if(isvalid(temp.x, temp.y+1) && arr[temp.x][temp.y+1] == 1) {
				if(!flag) ans++, flag = true;
				arr[temp.x][temp.y+1] = 2;
				temp.y++;
				Q.push(temp);
				temp.y--;
			}
 
			if(isvalid(temp.x, temp.y-1) && arr[temp.x][temp.y-1] == 1) {
				if(!flag) ans++, flag = true;
				arr[temp.x][temp.y-1] = 2;
				temp.y--;
				Q.push(temp);
			}
 
			Q.pop();
		}
 
		Q.pop();
 
		if(!Q.empty()) {
			temp.x = -1;
			temp.y = -1;
			Q.push(temp);
		}
	}
 
	if(checkall(arr)) cout << "All Apples cannot rot\n";
	else cout << "Time required for all apples to rot => " << ans << endl;
}
 
int main() {
 
	int arr[][C] = { {2, 1, 0, 2, 1},
					 {1, 0, 1, 2, 1},
                     {1, 0, 0, 2, 1}};
	solve(arr);
	return 0;
}

 

answered Aug 5, 2015 by Mr.Lazy

Assuming that the rotten oranges rote the fresh oranges at the same time. i.e. concurrently.

You can do a BFS here. Just add all the rotten oranges (i,j) pair in a queue and start popping the elements from the queue and add a  (-1,-1) to mark that the one unit of time has been passed. Now check all four sides of that particular pair and if fresh oranges are present at that point make them rotten and add those points to the queue. If the cell is empty then do nothing and if the cell contains the rotten orange then also do nothing. So whenever you got a pair (-1,-1) increment time by 1 unit if in this interval some oranges becomes rotten. So when the queue becomes empty check if there is some fresh oranges left or not in the matrix. if yes return -1 else time.

Time complexity O(n*m)

answered Aug 5, 2015 by livefree

Here's my solution to the problem in go. Any feedback is appreciated.

package main

import (
    "fmt"
)

type inp2dArray [3][5]int

type element struct {
    i, j int
}

type queue struct {
    elements []*element
}

// IsEmpty(), Push(element) and Pop() implemented for queue

func main() {

arr := inp2dArray{
    [5]int{2, 1, 0, 2, 1},
    [5]int{1, 0, 1, 2, 1},
    [5]int{1, 0, 0, 2, 1},
    }

// arr := inp2dArray{
// [5]int{2, 1, 0, 2, 1},
// [5]int{0, 0, 1, 2, 1},
// [5]int{1, 0, 0, 2, 1},
// }

    minTime := 0
    minTime = minimumTimeToRotAllOranges(arr, formFreshQueue(arr), &minTime)
    fmt.Println("Minimum time to rot all oranges :", minTime)
    
}

func formFreshQueue(arr inp2dArray) *queue {

    q := new(queue)
    for i := 0; i < 3; i++ {
        for j := 0; j < 5; j++ {
            if arr[i][j] == 1 {
                el := &element{i, j}
                q.Push(el)
            }
        }
    }
    return q
}

func isValid(i, j int) bool {
    return i >= 0 && i < 3 && j >= 0 && j < 5
}

func minimumTimeToRotAllOranges(arr inp2dArray, freshQueue *queue, time *int) int {

    *time++
    toBeRotten := new(queue)
    stillFresh := new(queue)
    el := freshQueue.Pop()

    for ; el != nil; el = freshQueue.Pop() {

        i, j := el.i, el.j
        if isValid(i-1, j) && arr[i-1][j] == 2 ||
            isValid(i+1, j) && arr[i+1][j] == 2 ||
            isValid(i, j-1) && arr[i][j-1] == 2 ||
            isValid(i, j+1) && arr[i][j+1] == 2 {

            toBeRotten.Push(el)
        } else {

            stillFresh.Push(el)
        }
    }
    if stillFresh.IsEmpty() {
        return *time
    }

    if toBeRotten.IsEmpty() {
        return -1
    } else {
        el := toBeRotten.Pop()
        for ; el != nil; el = toBeRotten.Pop() {
            arr[el.i][el.j] = 2
        }

        return minimumTimeToRotAllOranges(arr, stillFresh, time)
    }
}

 

answered Aug 23, 2015 by pritz
edited Aug 23, 2015 by pritz

use the code tag..i would encourage more GO solutions

the code tag doesn't work for Go I suppose

select any language like C/C++..atleast it will be readable then

Selecting other languages doesnt work either. I formatted it myself

it looks good..

package main

import (
    "fmt"
)

type inp2dArray [3][5]int

type element struct {
    i, j int
}

type queue struct {
    elements []*element
}

// IsEmpty(), Push(element) and Pop() implemented for queue

func main() {

arr := inp2dArray{
    [5]int{2, 1, 0, 2, 1},
    [5]int{1, 0, 1, 2, 1},
    [5]int{1, 0, 0, 2, 1},
    }

// arr := inp2dArray{
// [5]int{2, 1, 0, 2, 1},
// [5]int{0, 0, 1, 2, 1},
// [5]int{1, 0, 0, 2, 1},
// }

    minTime := 0
    minTime = minimumTimeToRotAllOranges(arr, formFreshQueue(arr), &minTime)
    fmt.Println("Minimum time to rot all oranges :", minTime)
    
}

func formFreshQueue(arr inp2dArray) *queue {

    q := new(queue)
    for i := 0; i < 3; i++ {
        for j := 0; j < 5; j++ {
            if arr[i][j] == 1 {
                el := &element{i, j}
                q.Push(el)
            }
        }
    }
    return q
}

func isValid(i, j int) bool {
    return i >= 0 && i < 3 && j >= 0 && j < 5
}

func minimumTimeToRotAllOranges(arr inp2dArray, freshQueue *queue, time *int) int {

    *time++
    toBeRotten := new(queue)
    stillFresh := new(queue)
    el := freshQueue.Pop()

    for ; el != nil; el = freshQueue.Pop() {

        i, j := el.i, el.j
        if isValid(i-1, j) && arr[i-1][j] == 2 ||
            isValid(i+1, j) && arr[i+1][j] == 2 ||
            isValid(i, j-1) && arr[i][j-1] == 2 ||
            isValid(i, j+1) && arr[i][j+1] == 2 {

            toBeRotten.Push(el)
        } else {

            stillFresh.Push(el)
        }
    }
    if stillFresh.IsEmpty() {
        return *time
    }

    if toBeRotten.IsEmpty() {
        return -1
    } else {
        el := toBeRotten.Pop()
        for ; el != nil; el = toBeRotten.Pop() {
            arr[el.i][el.j] = 2
        }

        return minimumTimeToRotAllOranges(arr, stillFresh, time)
    }
}

 

#include<iostream.h>
#include<conio.h>
#include<process.h>
void main()
{
	clrscr();
	int i,j,m=3,n=5,flag=0;
	int a[3][5]={{2,1,0,2,1},{1,0,1,2,1},{1,0,0,2,1}},p=0,b[15],c[15],count=0;
	for(i=0;i<15;i++)
	{b[i]=0;c[i]=0;}
	while(1)
	{
		for(i=0;i<m;i++)
		{
			for(j=0;j<n;j++)
			{
				if(a[i][j]==2)
				{
					b[p]=i;
					c[p]=j;
					p++;
				}
			}
		}
		for(i=0;i<p;i++)
		{
			if(a[b[i]-1][c[i]]==1&&b[i]!=0)
			{a[b[i]-1][c[i]]=2;flag=1;}
			if(a[b[i]+1][c[i]]==1&&b[i]!=m-1)
			{a[b[i]+1][c[i]]=2;flag=1;}
			if(a[b[i]][c[i]-1]==1&&c[i]!=0)
			{a[b[i]][c[i]-1]=2;flag=1;}
			if(a[b[i]][c[i]+1]==1&&c[i]!=n-1)
			{a[b[i]][c[i]+1]=2;flag=1;}
		}
		for(i=0;i<p;i++)
		{b[i]=0;c[i]=0;}
		p=0;
		if(flag==0)
		{
		       for(i=0;i<m;i++)
		       {
				for(j=0;j<n;j++)
				{
					if(a[i][j]==1)
					{
						cout<<"All oranges cannot be rotten";
						getch();
						exit(0);
					}
				}
		       }
		       cout<<"All oranges can become rotten in "<<count<<" time frames.";
		       getch();
		       exit(0);
		}
		flag=0;
		count++;
	}
}

 

answered Aug 11, 2015 by sachinkatiyar
Best solution for the problem till now. Kuddos mate.

Could you explain the logic.

a[3][5] is the test case. b and c are the single dimension arrays that will store x and y coordinate of the given dd matrix that have value as 2.In first for loop inside the while loop, we will find all the coordinates having value as 2 and store the x and y coordinate in b and c array respectively. Next, second for loop inside while loop will make each adjacent value from 1 to 2 for each coordinate having value 2. If all adjacent value are already 2 then flag value will not change and will remain zero else it will become 1 and while loop continues. If flag value become become zero then it will enter inside if statement and check whether array a[3][5] has 1 as a value or not. If yes, then print "All oranges cannot be rotten". else print "All oranges become rotten in count no. of frames". count will increment every time while loop execute.

import java.util.LinkedList;
import java.util.List;
class IntegerPair{
	int first;
	int second;
	public IntegerPair() {
	}
	public IntegerPair(int f,int s) {
		this.first = f;
		this.second = s;
	}
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof IntegerPair){
			IntegerPair pair  = (IntegerPair)obj;
			return (this.first == pair.first && this.second==pair.second);
		}
		return false;
	}
	@Override
	public int hashCode() {
		return (first+second);
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return ("("+first+","+second+")");
	}
}

public class OrangeRotteningBFS {
	void solve(int arr[][]){
		if(arr!=null && arr[0]!=null){
			int res = 0;
			int m = arr.length;
			int n = arr[0].length;
			List<IntegerPair> queue = new LinkedList<IntegerPair>();
			/**
			 * Adding all the 2's in the matrix in queue i.e. rooten oranges coordinates
			 */
			for(int i=0;i<n;i++){
				for(int j=0;j<n;j++){
					if(arr[i][j]==2){
						queue.add(new IntegerPair(i,j));
					}
				}
			}
			/**
			 * considering rooten orange can rot only four of its neighbour's
			 * right , left , up , down
			 */
			int dx[] = {0,-1,0,1};
			int dy[] = {-1,0,1,0};
			while(!queue.isEmpty()){
				int sz = queue.size();
				boolean flag = true;
				while(sz>0){
					IntegerPair p = queue.get(0);
					queue.remove(0);
					for(int i=0;i<4;i++){
						int _x = p.first + dx[i];
						int _y = p.second + dy[i];
						// checking the boundary condition 
						if(_x>=0 && _x<m && _y>=0 && _y<n){
							/**
							 * checking if the neighbour is 1 if so add the co-ordinate to queue 
							 * and set it value as 2
							 */
							if(arr[_x][_y]==1){
								flag = true;
								arr[_x][_y] = 2;
								queue.add(new IntegerPair(_x,_y));
							}
						}
					}
					sz--;
				}
				if(flag){
					res++;
				}
			}
			System.out.println("Time " + res);
			int unRottenOranges = 0;
			for(int i=0;i<m;i++){
				for(int j=0;j<n;j++){
					if(arr[i][j]==1){
						unRottenOranges++;
					}
				}
			}
			System.out.println("Unrotten Oranges"+unRottenOranges);
			System.out.println((unRottenOranges==0)? res:-1);
		}else{
			System.out.println("Input is null");
		}
	}
}

 

answered Oct 15, 2015 by codersx
import java.util.LinkedList;

public class Microsoft10_rottenOranges {
    public static void main(String[] args) {
        int mat[][] = { { 2, 1, 0, 2, 1 }, { 1, 0, 1, 2, 1 }, { 1, 0, 0, 2, 1 } };
        System.out.println(days(mat));
    }

    static int days(int mat[][]) {
        int m = mat.length;
        int n = mat[0].length;
        LinkedList<Item> q = new LinkedList<Item>();
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                int val = mat[i][j];
                if (val == 2) {
                    q.add(new Item(i, j, val)); //add all rotten oranges into queue
                }
            }
        }

        q.add(new Item(-1, -1, -1)); // end of time-slot 1
        int dayCount = 0;
        
        //to reach neighbours
        int X[] = { -1, 1, 0, 0 };
        int Y[] = { 0, 0, -1, 1 }; 

        boolean rottedInThisRound = false;

        // apply BFS
        while (!q.isEmpty()) {
            Item curItem = q.poll();
            if (curItem.val == -1) {
                if (!rottedInThisRound) {
                    break;
                }
                dayCount++;
                rottedInThisRound = false;
                q.add(new Item(-1, -1, -1));
                continue;
            }
            // make all it's neighbors .. rotten
            int row = curItem.row;
            int col = curItem.col;
            for (int i = 0; i < 4; i++) {
                if (isValid(row + X[i], col + Y[i], mat)) {
                    mat[row + X[i]][col + Y[i]] = 2;
                    rottedInThisRound = true;
                    q.add(new Item(row + X[i], col + Y[i], 2));
                }
            }
        }

        // check if any orange is not rotten (==1)
        if (!checkAllRotten(mat)) {
            return -1;
        }
        return dayCount;
    }

    static boolean checkAllRotten(int mat[][]) {
        for (int i = 0; i < mat.length; i++) {
            for (int j = 0; j < mat[0].length; j++) {
                if (mat[i][j] == 1) {// if any of them is not rotten
                    return false;
                }
            }
        }
        return true;
    }

    static boolean isValid(int i, int j, int mat[][]) {
        int m = mat.length;
        int n = mat[0].length;
        return i < m && j < n && i >= 0 && j >= 0 && mat[i][j] == 1;
    }

    private static class Item {
        int row;
        int col;
        int val;

        public Item(int i, int j, int val) {
            this.row = i;
            this.col = j;
            this.val = val;
        }

        @Override
        public String toString() {
            return "[" + row + "][" + col + "]:" + val;
        }
    }
}

 

answered Nov 12, 2016 by ABHISHEK KUMAR 54
edited Nov 12, 2016 by ABHISHEK KUMAR 54
...