Open In App

Check whether the structure of given Graph is same as the game of Rock-Paper-Scissor

Last Updated : 17 Feb, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of N pairs of strings representing a directed graph, where each pair of the strings represents an edge between the nodes represented by the pair of strings, the task is to check whether the structure of the given directed graph is the same as that of the game of Rock-Paper-Scissor. If found true, then print “Yes“. Otherwise, print “No“.

Note:

In the real game of Rock-Paper-Scissor, the rock dominates over the scissor, scissor dominates over the paper and paper dominates over the rock.The game can be modelled using a directed graph as below, in which the directed edge (a, b) shows that a dominates over b.

Examples:

Input: arr[] = {{“Snake”, “Water”}, {“Water”, “Gun”}, {“Gun”, “Snake”}}
Output: Yes
Explanation: 

Therefore, from the above image it can be seen that the given graph structure is similar to Rock-Paper-Scissor.

Input: arr[]={{“Snake”, “Water”}, {“Water”, “Gun”}, {“Gun”, “Gun”}}
Output: No
 

 

Approach: The problem can be solved by using the indegree and outdegree of the graphs based on the observation that in the directed graph Rock-Paper-Scissor there are only three nodes and indegree and outdegree of each node is one. Follow the steps below to solve the problem.

  • Initialize two maps of {strings, int} say inDegree and outDegree, to store the indegree and outdegree of each node in these maps.
  • Initialize a set of strings say st and insert all the nodes i.e. strings in this set.
  • Check if the size of any map is not equal to 3 or the size of the set st of nodes is not equal to 3, then print “No“.
  • Iterate over both the maps and check if the second value of any entry map is not 1, then, print “No” and break.
  • Finally, if none of the above cases satisfy, then print “Yes“.

Below is the implementation of the above approach:       

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if the given directed
// graph has same structure to Rock-Paper-Scissor
string similarGame(vector<vector<string> > arr)
{
 
    // Stores indegree of each node
    unordered_map<string, int> indegree;
 
    // Stores outdegree of each node
    unordered_map<string, int> outdegree;
 
    // Stores all nodes
    set<string> st;
 
    // Traverse through the edges
    for (int i = 0; i < arr.size(); i++) {
 
        // Check presence of self loop
        if (arr[i][0] == arr[i][1])
            return "No";
 
        // Insert the node arr[i][0] and arr[i][1]
        // into the set
        st.insert(arr[i][0]);
        st.insert(arr[i][1]);
 
        // Increment the outdegree and indegree of
        // nodes arr[i][0] and arr[i][1]
 
        outdegree[arr[i][0]]++;
        indegree[arr[i][1]]++;
    }
 
    // Check base conditions
    if (outdegree.size() != 3 || indegree.size() != 3
        || st.size() != 3)
        return "No";
 
    // Traverse the array outdegree
    for (auto it : outdegree) {
        if (it.second != 1)
            return "No";
    }
 
    // Traverse the array indegree
    for (auto it : indegree) {
        if (it.second != 1)
            return "No";
    }
 
    // Return
    return "Yes";
}
 
// Driver Code
int main()
{
 
    // Given Input
    vector<vector<string> > arr = { { "Snake", "Water" },
                                    { "Water", "Gun" },
                                    { "Gun", "Snake" } };
 
    // Function Call
    cout << similarGame(arr);
 
    return 0;
}


Python3




# Python 3 program for the above approach
 
# Function to check if the given directed
# graph has same structure to Rock-Paper-Scissor
def similarGame(arr):
    # Stores indegree of each node
    indegree = {}
 
    # Stores outdegree of each node
    outdegree = {}
 
    # Stores all nodes
    st = set()
 
    # Traverse through the edges
    for i in range(len(arr)):
        # Check presence of self loop
        if (arr[i][0] == arr[i][1]):
            return "No"
 
        # Insert the node arr[i][0] and arr[i][1]
        # into the set
        st.add(arr[i][0])
        st.add(arr[i][1])
 
        # Increment the outdegree and indegree of
        # nodes arr[i][0] and arr[i][1]
        if arr[i][0] in outdegree:
            outdegree[arr[i][0]] += 1
        else:
            outdegree[arr[i][0]] = 0
        if arr[i][1] in indegree:
            indegree[arr[i][1]] += 1
        else:
            indegree[arr[i][1]] = 0
 
    # Check base conditions
    if (len(outdegree) != 3 and len(indegree) != 3 and len(st) != 3):
        return "No";
 
    # Traverse the array outdegree
    for key,value in outdegree.items():
        if (value == 1):
            return "No"
 
    # Traverse the array indegree
    for key,value in indegree.items():
        if (value == 1):
            return "No"
 
    # Return
    return "Yes"
 
# Driver Code
if __name__ == '__main__':
    # Given Input
    arr = [["Snake", "Water"],["Water", "Gun"],["Gun", "Snake"]]
 
    # Function Call
    print(similarGame(arr))
     
    # This code is contributed by SURENDRA_GANGWAR.


Javascript




<script>
 
// JavaScript program for the above approach
 
 
// Function to check if the given directed
// graph has same structure to Rock-Paper-Scissor
function similarGame(arr)
{
 
    // Stores indegree of each node
    let indegree = new Map();
 
    // Stores outdegree of each node
    let outdegree = new Map();
 
    // Stores all nodes
    let st = new Set();
 
    // Traverse through the edges
    for (let i = 0; i < arr.length; i++) {
 
        // Check presence of self loop
        if (arr[i][0] == arr[i][1])
            return "No";
 
        // add the node arr[i][0] and arr[i][1]
        // into the set
        st.add(arr[i][0]);
        st.add(arr[i][1]);
 
        // Increment the outdegree and indegree of
        // nodes arr[i][0] and arr[i][1]
 
        if(outdegree.has(arr[i][0]) == true)outdegree.set(arr[i][0],outdegree.get(arr[i][0])+1);
        else outdegree.set(arr[i][0],1);
 
        if(indegree.has(arr[i][1]) == true)indegree.set(arr[i][1],indegree.get(arr[i][1])+1);
        else indegree.set(arr[i][1],1);
    }
 
    // Check base conditions
 
    if (outdegree.size != 3 || indegree.size != 3
        || st.size != 3)
        return "No";
 
    // Traverse the array outdegree
    for (let [key,value] in outdegree) {
        if (value != 1)
            return "No";
    }
 
    // Traverse the array indegree
    for (let [key,value] in indegree) {
        if (value != 1)
            return "No";
    }
 
    // Return
    return "Yes";
}
 
// Driver Code
 
// Given Input
let arr = [ [ "Snake", "Water" ],
                                    [ "Water", "Gun" ],
                                    [ "Gun", "Snake" ] ];
 
// Function Call
document.write(similarGame(arr),"</br>");
 
// This code is contributed by shinjanpatra.
</script>


Java




/*package whatever //do not write package name here */
 
import java.io.*;
import java.util.*;
 
class GFG {
    // Java program for the above approach
 
// Function to check if the given directed
// graph has same structure to Rock-Paper-Scissor
static String similarGame(String[][] arr)
{
 
    // Stores indegree of each node
    HashMap<String,Integer> indegree = new HashMap<>();
 
    // Stores outdegree of each node
    HashMap<String,Integer> outdegree = new HashMap<>();
 
    // Stores all nodes
    TreeSet<String> st = new TreeSet<>();
 
    // Traverse through the edges
    for (int i = 0; i < arr.length; i++) {
 
        // Check presence of self loop
        if (arr[i][0] == arr[i][1])
            return "No";
 
        // Insert the node arr[i][0] and arr[i][1]
        // into the set
        st.add(arr[i][0]);
        st.add(arr[i][1]);
 
        // Increment the outdegree and indegree of
        // nodes arr[i][0] and arr[i][1]
 
        if(outdegree.containsKey(arr[i][0])){
            outdegree.put(arr[i][0],outdegree.get(arr[i][0])+1);
        }
        else outdegree.put(arr[i][0],1);
        if(indegree.containsKey(arr[i][0])){
            indegree.put(arr[i][0],indegree.get(arr[i][0])+1);
        }
        else indegree.put(arr[i][0],1);
    }
 
    // Check base conditions
    if (outdegree.size() != 3 || indegree.size() != 3
        || st.size() != 3)
        return "No";
 
    // Traverse the array outdegree
    for (Map.Entry it : outdegree.entrySet()) {
        if ((int)it.getValue() != 1)
            return "No";
    }
 
    // Traverse the array indegree
    for (Map.Entry it : indegree.entrySet()) {
        if ((int)it.getValue() != 1)
            return "No";
    }
 
    // Return
    return "Yes";
}
 
/* Driver program to test above function*/
public static void main(String args[])
{
    // Given Input
    String[][] arr = { { "Snake", "Water" },{ "Water", "Gun" },{ "Gun", "Snake" } };
 
    // Function Call
    System.out.println(similarGame(arr));
}
 
}
 
// This Solution is contributed by shinjanpatra.


C#




// C# program for the equivalent code
using System;
using System.Collections.Generic;
 
class GFG {
    // Function to check if the given directed
    // graph has same structure to Rock-Paper-Scissor
    static string SimilarGame(string[, ] arr)
    {
        // Stores indegree of each node
        Dictionary<string, int> indegree
            = new Dictionary<string, int>();
 
        // Stores outdegree of each node
        Dictionary<string, int> outdegree
            = new Dictionary<string, int>();
 
        // Stores all nodes
        SortedSet<string> st = new SortedSet<string>();
 
        // Traverse through the edges
        for (int i = 0; i < arr.GetLength(0); i++) {
            // Check presence of self loop
            if (arr[i, 0] == arr[i, 1])
                return "No";
 
            // Insert the node arr[i][0] and arr[i][1]
            // into the set
            st.Add(arr[i, 0]);
            st.Add(arr[i, 1]);
 
            // Increment the outdegree and indegree of
            // nodes arr[i][0] and arr[i][1]
            if (outdegree.ContainsKey(arr[i, 0])) {
                outdegree[arr[i, 0]]++;
            }
            else
                outdegree.Add(arr[i, 0], 1);
            if (indegree.ContainsKey(arr[i, 0])) {
                indegree[arr[i, 0]]++;
            }
            else
                indegree.Add(arr[i, 0], 1);
        }
 
        // Check base conditions
        if (outdegree.Count != 3 || indegree.Count != 3
            || st.Count != 3)
            return "No";
 
        // Traverse the array outdegree
        foreach(KeyValuePair<string, int> it in outdegree)
        {
            if (it.Value != 1)
                return "No";
        }
 
        // Traverse the array indegree
        foreach(KeyValuePair<string, int> it in indegree)
        {
            if (it.Value != 1)
                return "No";
        }
 
        // Return
        return "Yes";
    }
 
    // Driver program to test above function
    public static void Main(string[] args)
    {
        // Given Input
        string[, ] arr = { { "Snake", "Water" },
                           { "Water", "Gun" },
                           { "Gun", "Snake" } };
 
        // Function Call
        Console.WriteLine(SimilarGame(arr));
    }
}


Output

Yes

Time Complexity: O(N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads