Given an array dir_list[] that represents direction where the valid directions are “UP”, “Left”, “Right” and “Down”. Your goal is to reduce the instructions by eliminating those that contradict one another, or those consecutive instructions that are opposite to one another. If the list becomes empty, print -1.
Note: UP and Down are opposite to each other and Left and Right are also opposite to each other.
Examples:
Input: dir_list = [“UP”, “Left”, “Right”, “Down”, “Right”, “UP”]
Output: [‘Right’, ‘UP’]
Explanation: Direction at index 1 and 2 cancel out each other. After their removal, dir_list become [“UP”, “Down”, “Right”, “UP”] Direction at index 0 and 1 also cancel out each other. After their removal, dir_list become [“Right”, “UP”]Input: dir_list = [“UP”, “Down”]
Output: []
Explanation: UP and Down are consecutively opposite to each other so, they are cancel out each other leaving an empty list.
Approach: This can be solved using a stack.
The idea is to eliminate the opposite directions by comparing top element of stack and last element of list.
Follow the below steps to implement the idea:
- First check if the List is empty or has only a single element, then, return the list itself.
- Create a stack, append the last element of the list to the stack, and pop it from the list.
-
While the list is not empty
- If the stack is empty, pop the last element of the list and append it to the stack
- Set a = top element of the stack and pop the element and b = last element of the list and pop the element
- Check if a and b are not opposed to each other, append a and b into the stack respectively.
- After executing the loop, reverse the stack and return it.
Below is the implementation of the above approach.
// C++ program to solve desert // crossing problem #include <bits/stdc++.h> using namespace std;
// Function to check if a and b is // opposite or not bool isOpposite(string a, string b)
{ if ((a == "UP" && b == "Down" )
|| (a == "Down" && b == "UP" )) {
return true ;
}
if ((a == "Left" && b == "Right" )
|| (a == "Right" && b == "Left" )) {
return true ;
}
return false ;
} // Function to remove the opposite // instructions vector<string> reduceDir(vector<string> l) { // Create a stack and append the last
// element of list to the stack and
// pop it from list
stack<string> st;
st.push(l.back());
l.pop_back();
// While list is not empty
while (!l.empty()) {
// When stack is empty
if (st.empty()) {
st.push(l.back());
l.pop_back();
continue ;
}
// Find a and b
string a = st.top();
st.pop();
string b = l.back();
l.pop_back();
// Check is a and b are opposite
// or not
if (!isOpposite(a, b)) {
// If it is not then append the
// popped element to the stack
// again and also append the
// popped element of list
st.push(a);
st.push(b);
}
}
vector<string> res;
while (!st.empty()) {
res.push_back(st.top());
st.pop();
}
// Return the stack
return res;
} // Driver Code int main()
{ vector<string> dir_list
= { "UP" , "Left" , "Right" , "Down" , "Right" , "UP" };
vector<string> res_list = reduceDir(dir_list);
if (res_list.empty()) {
cout << "-1" << endl;
}
else {
for ( auto i : res_list) {
cout << i << " " ;
}
cout << endl;
}
return 0;
} |
// Java program to solve desert crossing problem import java.io.*;
import java.util.*;
class GFG {
// Function to check if a and b is opposite or not
static boolean isOpposite(String a, String b)
{
if ((a.equals( "UP" ) && b.equals( "Down" ))
|| (a.equals( "Down" ) && b.equals( "UP" ))) {
return true ;
}
if ((a.equals( "Left" ) && b.equals( "Right" ))
|| (a.equals( "Right" ) && b.equals( "Left" ))) {
return true ;
}
return false ;
}
// Function to remove the opposite instructions
public static List<String> reduceDir(List<String> l)
{
// Create a stack and append the last element of
// list to the stack and pop it from list
Stack<String> stack = new Stack<>();
stack.add(l.remove(l.size() - 1 ));
// While list is not empty
while (!l.isEmpty()) {
// When stack is empty
if (stack.isEmpty()) {
stack.add(l.remove(l.size() - 1 ));
continue ;
}
// Find a and b
String a = stack.pop();
String b = l.remove(l.size() - 1 );
// Check is a and b are oppositte or not
if (!isOpposite(a, b)) {
// If it is not then append the popped
// element to the stack again and also
// append the popped element of list
stack.push(a);
stack.push(b);
}
}
List<String> res = new ArrayList<>(stack);
Collections.reverse(res);
// return the result.
return res;
}
public static void main(String[] args)
{
List<String> dir_list = new ArrayList<>(
Arrays.asList( "UP" , "Left" , "Right" , "Down" ,
"Right" , "UP" ));
List<String> res_list = reduceDir(dir_list);
if (res_list.isEmpty()) {
System.out.println( "-1" );
}
else {
System.out.println(res_list);
}
}
} // This code is contributed by karthik. |
# Python program to solve desert # crossing problem # Function to check if a and b is # opposite or not def isOpposite(a, b):
if (a = = "UP" and b = = "Down" ) or (a = = "Down" and b = = "UP" ):
return 1
if (a = = "Left" and b = = "Right" ) or (a = = "Right" and b = = "Left" ):
return 1
else :
return 0
# Function to remove the opposite # instructions def reduceDir(l):
# List is empty or has only single
# element
if len (l) = = 0 or len (l) = = 1 :
return l
# Create a stack and append the last
# element of list to the stack and
# pop it from list
stack = []
stack.append(l.pop())
# While list is not empty
while len (l) ! = 0 :
# When stack is empty
if len (stack) = = 0 :
stack.append(l.pop())
continue
# Find a and b
a = stack.pop()
b = l.pop()
# Check is a and b are opposite
# or not
if isOpposite(a, b) ! = 1 :
# If it is not then append the
# popped element to the stack
# again and also append the
# popped element of list
stack.append(a)
stack.append(b)
# Reverse the stack
stack.reverse()
# Return the stack
return stack
# Driver Code if __name__ = = "__main__" :
dir_list = [ "UP" , "Left" , "Right" , "Down" , "Right" , "UP" ]
res_list = reduceDir(dir_list)
if ( len (res_list) = = 0 ):
print ( - 1 )
else :
print (res_list)
|
using System;
using System.Collections.Generic;
class GFG
{ // Function to check if a and b is
// opposite or not
static bool IsOpposite( string a, string b)
{
if ((a == "UP" && b == "Down" )
|| (a == "Down" && b == "UP" ))
{
return true ;
}
if ((a == "Left" && b == "Right" )
|| (a == "Right" && b == "Left" ))
{
return true ;
}
return false ;
}
// Function to remove the opposite
// instructions
static List< string > ReduceDir(List< string > l)
{
// Create a stack and append the last
// element of list to the stack and
// pop it from list
Stack< string > st = new Stack< string >();
st.Push(l[l.Count - 1]);
l.RemoveAt(l.Count - 1);
// While list is not empty
while (l.Count > 0)
{
// When stack is empty
if (st.Count == 0)
{
st.Push(l[l.Count - 1]);
l.RemoveAt(l.Count - 1);
continue ;
}
// Find a and b
string a = st.Peek();
st.Pop();
string b = l[l.Count - 1];
l.RemoveAt(l.Count - 1);
// Check is a and b are opposite
// or not
if (!IsOpposite(a, b))
{
// If it is not then append the
// popped element to the stack
// again and also append the
// popped element of list
st.Push(a);
st.Push(b);
}
}
List< string > res = new List< string >();
while (st.Count > 0)
{
res.Add(st.Peek());
st.Pop();
}
// Return the stack
return res;
}
// Driver Code
static void Main()
{
List< string > dir_list = new List< string >
{
"UP" , "Left" , "Right" , "Down" , "Right" , "UP"
};
List< string > res_list = ReduceDir(dir_list);
if (res_list.Count == 0)
{
Console.WriteLine( "-1" );
}
else
{
foreach ( var i in res_list)
{
Console.Write(i + " " );
}
Console.WriteLine();
}
}
} |
// Function to check if a and b is // opposite or not function GFG(a, b) {
if ((a === "UP" && b === "Down" ) || (a === "Down" && b === "UP" )) {
return true ;
}
if ((a === "Left" && b === "Right" ) || (a === "Right" && b === "Left" )) {
return true ;
}
return false ;
} // Function to remove opposite instructions function reduceDir(dirList) {
// If the list is empty or has only a single element, return it as is
if (dirList.length === 0 || dirList.length === 1) {
return dirList;
}
const stack = [];
stack.push(dirList.pop());
// While the list is not empty
while (dirList.length !== 0) {
// When the stack is empty
if (stack.length === 0) {
stack.push(dirList.pop());
continue ;
}
// Find a and b
const a = stack.pop();
const b = dirList.pop();
// Check if a and b are opposite or not
if (!GFG(a, b)) {
// If they are not opposite
// push the popped elements back to the stack
stack.push(a);
stack.push(b);
}
}
// Reverse the stack to get the correct order
stack.reverse();
return stack;
} // Driver Code const dirList = [ "UP" , "Left" , "Right" , "Down" , "Right" , "UP" ];
const resList = reduceDir(dirList); // Check if the resulting list is // empty or not and print accordingly if (resList.length === 0) {
console.log(-1);
} else {
console.log(resList);
} |
['Right', 'UP']
Time Complexity: O(N)
Auxiliary Space: O(N)