Open In App

Find the most honest person from given statements of truths and lies

Last Updated : 09 Mar, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a binary matrix of size N * N, mat[][]. Value at cell (i, j) indicates what ith person says about jth person. A person x is considered honest if he always tells the truth. If person x speaks lie sometimes and truth sometimes, then he is a liar.

  • If mat[i][j] = 0, then ith person says jth person is a liar.
  • If mat[i][j] = 1, then ith person says jth person is honest.
  • If mat[i][j] = 2, then ith person does not comment about jth person.

The task is to find maximum honest persons.

Examples:

Input: mat = {{2, 1, 2},  
                      {1, 2, 2},  
                      {2, 0, 2}}
Output: 2
Explanation: Each person makes a single statement.
Person 0 states that person 1 is honest.
Person 1 states that person 0 is honest.
Person 2 states that person 1 is liar.
Let’s take person 2 as the key.

  • Assuming that person 2 is honest:
    • Based on the statement made by person 2, person 1 is a liar.
    • Now person 1 is liar and person 2 is honest.
    • Based on the statement made by person 1, and since person 1 is liar, it could be:
      • true. There will be a contradiction in this case and this assumption is invalid.
      • lie. In this case, person 0 is also a liar and lied.
    • Following that person 2 is honest, there can be only one honest person.
  • Assuming that person 2 is liar:
    • Based on the statement made by person 2, and since person 2 is liar, it could be:
      • true. Following this scenario, person 0 and 1 are both liar as explained before.
      • Following that person 2 is liar but told the truth, there will be no honest person.
      • lying. In this case person 1 is honest.
    • Since person 1 is honest, person 0 is also honest.
    • Following that person 2 is liar and lied, there will be two honest persons.
  • At most 2 persons are honest in the best case.
  • So the answer is 2.

Input: mat = {{2, 0},  
                       {0, 2}}
Output: 1

 

Approach: There can be 2N combinations of the opinions among N persons. The idea is to consider 2N numbers and assume their binary representation as the possible order of persons’ reality. 0 bit represents the person is liar and 1 represents the person is honest. Traverse through all numbers, if a bit in the number is 1 then assume that the indexed person is honest and then confirm this assumption. To confirm the assumption verify all jth bits of the number with respect to this index and what he says about jth person in the matrix. Follow the steps mentioned below:

  • Get the size of the matrix i.e. N.
  • Compute the number of total combinations possible.
  • Iterate through all numbers from 0 to 2N. 
  • Detect the setbits (honest) in the binary format of this number (combination), and increment the counter.
  • Check if the given “1” bit implies an honest or a liar.
  • A person i is invalid if he lies.
    • If jth bit is 0 in combination number and person i says that j is honest.
    • if jth bit is 1 in combination number and person i says that j is a lair.
  • If person i is valid, then update the answer.

Below is the implementation of the above approach.

C++




// C++ program to implement the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Utility Function
bool Is_Good(int n, int index)
{
    return (n >> index) & 1;
}
 
// Function to count maximum honest persons
int MaximumHonest(vector<vector<int> >& mat)
{
    int N = mat.size();
    int ans = 0;
 
    // Getting all the possible combinations
    int comb = pow(2, N);
 
    // Loop to find maximum honest persons
    for (int i = 0; i < comb; i++) {
        bool isValid = true;
        int counter = 0;
        for (int person = 0; person < N;
             person++) {
 
            // If the person is a liar
            if (!Is_Good(i, person))
                continue;
            counter++;
 
            // Checking validity of "persons"
            // being honest and if "person"
            // is honest then total number
            // of honest persons
            for (int j = 0; j < N; j++) {
                if ((!Is_Good(i, j)
                     && mat[person][j] == 1)
                    || (Is_Good(i, j)
                        && mat[person][j]
                               == 0)) {
                    isValid = false;
                    break;
                }
            }
        }
        if (isValid)
            ans = max(ans, counter);
    }
    return ans;
}
 
// Driver code
int main()
{
    vector<vector<int> > mat{ { 2, 0 },
                              { 0, 2 } };
    int res = MaximumHonest(mat);
    cout << res;
    return 0;
}


Java




// Java program to implement the above approach
import java.util.*;
class GFG{
 
  // Utility Function
  static boolean Is_Good(int n, int index)
  {
    return ((n >> index) & 1) >0?true:false;
  }
 
  // Function to count maximum honest persons
  static int MaximumHonest(int [][] mat)
  {
    int N = mat[0].length;
    int ans = 0;
 
    // Getting all the possible combinations
    int comb = (int) Math.pow(2, N);
 
    // Loop to find maximum honest persons
    for (int i = 0; i < comb; i++) {
      boolean isValid = true;
      int counter = 0;
      for (int person = 0; person < N;
           person++) {
 
        // If the person is a liar
        if (!Is_Good(i, person))
          continue;
        counter++;
 
        // Checking validity of "persons"
        // being honest and if "person"
        // is honest then total number
        // of honest persons
        for (int j = 0; j < N; j++) {
          if ((!Is_Good(i, j)
               && mat[person][j] == 1)
              || (Is_Good(i, j)
                  && mat[person][j]
                  == 0)) {
            isValid = false;
            break;
          }
        }
      }
      if (isValid)
        ans = Math.max(ans, counter);
    }
    return ans;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int [][]mat = { { 2, 0 },
                 { 0, 2 } };
    int res = MaximumHonest(mat);
    System.out.print(res);
  }
}
 
// This code is contributed by 29AjayKumar


Python3




# python3 program to implement the above approach
 
# Utility Function
def Is_Good(n, index):
 
    return (n >> index) & 1
 
# Function to count maximum honest persons
def MaximumHonest(mat):
 
    N = len(mat)
    ans = 0
 
    # Getting all the possible combinations
    comb = pow(2, N)
 
    # Loop to find maximum honest persons
    for i in range(0, comb):
        isValid = True
        counter = 0
        for person in range(0, N):
 
            # If the person is a liar
            if (not Is_Good(i, person)):
                continue
            counter += 1
 
            # Checking validity of "persons"
            # being honest and if "person"
            # is honest then total number
            # of honest persons
            for j in range(0, N):
                if ((not Is_Good(i, j)
                        and mat[person][j] == 1)
                        or (Is_Good(i, j)
                            and mat[person][j]
                            == 0)):
                    isValid = False
                    break
 
        if (isValid):
            ans = max(ans, counter)
 
    return ans
 
# Driver code
if __name__ == "__main__":
 
    mat = [[2, 0],
           [0, 2]]
    res = MaximumHonest(mat)
    print(res)
 
    # This code is contributed by rakeshsahni


Javascript




<script>
       // JavaScript code for the above approach
       // Utility Function
       function Is_Good(n, index) {
           return (n >> index) & 1;
       }
 
       // Function to count maximum honest persons
       function MaximumHonest(mat) {
           let N = mat.length;
           let ans = 0;
 
           // Getting all the possible combinations
           let comb = Math.pow(2, N);
 
           // Loop to find maximum honest persons
           for (let i = 0; i < comb; i++) {
               let isValid = true;
               let counter = 0;
               for (let person = 0; person < N;
                   person++) {
 
                   // If the person is a liar
                   if (!Is_Good(i, person))
                       continue;
                   counter++;
 
                   // Checking validity of "persons"
                   // being honest and if "person"
                   // is honest then total number
                   // of honest persons
                   for (let j = 0; j < N; j++) {
                       if ((!Is_Good(i, j)
                           && mat[person][j] == 1)
                           || (Is_Good(i, j)
                               && mat[person][j]
                               == 0)) {
                           isValid = false;
                           break;
                       }
                   }
               }
               if (isValid)
                   ans = Math.max(ans, counter);
           }
           return ans;
       }
 
       // Driver code
       let mat = [[2, 0],
       [0, 2]];
       let res = MaximumHonest(mat);
       document.write(res);
 
      // This code is contributed by Potta Lokesh
   </script>


C#




// C# program to implement the above approach
using System;
class GFG {
 
  // Utility Function
  static bool Is_Good(int n, int index)
  {
    return ((n >> index) & 1) == 1;
  }
 
  // Function to count maximum honest persons
  static int MaximumHonest(int[, ] mat)
  {
    int N = mat.GetLength(0);
    int ans = 0;
 
    // Getting all the possible combinations
    int comb = (int)Math.Pow(2, N);
 
    // Loop to find maximum honest persons
    for (int i = 0; i < comb; i++) {
      bool isValid = true;
      int counter = 0;
      for (int person = 0; person < N; person++) {
 
        // If the person is a liar
        if (!Is_Good(i, person))
          continue;
        counter++;
 
        // Checking validity of "persons"
        // being honest and if "person"
        // is honest then total number
        // of honest persons
        for (int j = 0; j < N; j++) {
          if ((!Is_Good(i, j)
               && mat[person, j] == 1)
              || (Is_Good(i, j)
                  && mat[person, j] == 0)) {
            isValid = false;
            break;
          }
        }
      }
      if (isValid)
        ans = Math.Max(ans, counter);
    }
    return ans;
  }
 
  // Driver code
  public static void Main()
  {
    int[, ] mat = { { 2, 0 }, { 0, 2 } };
    int res = MaximumHonest(mat);
    Console.Write(res);
  }
}
// This code is contributed by Samim Hossain Mondal.


 
 

Output

1

 

Time Complexity: O(2N * N * N)
Auxiliary Space: O(1)

 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads