Number of pairs with Pandigital Concatenation
A pair of strings when concatenated is said to be a ‘Pandigital Concatenation’ if their concatenation consists of all digits from (0 – 9) in any order at least once.The task is, given N strings, compute the number of pairs resulting in a ‘Pandigital Concatenation’.
Examples:
Input : num[] = {"123567", "098234", "14765", "19804"}
Output : 3
The pairs, 1st and 2nd giving
(123567098234),1st and 4rd giving(12356719804) and
2nd and 3rd giving (09823414765),
on concatenation result in Pandigital Concatenations.
Input : num[] = {"56789", "098345", "1234"}
Output : 0
None of the pairs on concatenation result in Pandigital
Concatenations.
Method 1 (Brute Force): A possible brute-force solution is to form all possible concatenations by forming all pairs in O(n2 and using a frequency array for digits (0 – 9), we check if each digit exists at least once in each concatenation formed for every pair.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
bool isPanDigital(string s)
{
bool digits[10] = { false };
for ( int i = 0; i < s.length(); i++)
digits[s[i] - '0' ] = true ;
for ( int i = 0; i <= 9; i++)
if (digits[i] == false )
return false ;
return true ;
}
int countPandigitalPairs(vector<string> &v)
{
int pairs = 0;
for ( int i = 0; i < v.size(); i++)
for ( int j = i + 1; j < v.size(); j++)
if (isPanDigital(v[i] + v[j]))
pairs++;
return pairs;
}
int main()
{
vector<string> v = { "123567" , "098234" ,
"14765" , "19804" };
cout << countPandigitalPairs(v) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static ArrayList<String> v =
new ArrayList<String>();
static int isPanDigital(String s)
{
int digits[] = new int [ 10 ];
for ( int i = 0 ; i < s.length(); i++)
digits[s.charAt(i) -
( int ) '0' ] = 1 ;
for ( int i = 0 ; i <= 9 ; i++)
if (digits[i] == 0 )
return 0 ;
return 1 ;
}
static int countPandigitalPairs()
{
int pairs = 0 ;
for ( int i = 0 ; i < v.size(); i++)
for ( int j = i + 1 ;
j < v.size(); j++)
if (isPanDigital(v.get(i) +
v.get(j)) == 1 )
pairs++;
return pairs;
}
public static void main(String args[])
{
v.add( "123567" );
v.add( "098234" );
v.add( "14765" );
v.add( "19804" );
System.out.print(countPandigitalPairs());
}
}
|
Python3
def isPanDigital(s) :
digits = [ False ] * 10 ;
for i in range ( 0 , len (s)) :
digits[ int (s[i]) -
int ( '0' )] = True
for i in range ( 0 , 10 ) :
if (digits[i] = = False ) :
return False
return True
def countPandigitalPairs(v) :
pairs = 0
for i in range ( 0 , len (v)) :
for j in range (i + 1 ,
len (v)) :
if (isPanDigital(v[i] +
v[j])) :
pairs = pairs + 1
return pairs
v = [ "123567" , "098234" ,
"14765" , "19804" ]
print (countPandigitalPairs(v))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int isPanDigital( string s)
{
int []digits = new int [10];
Array.Clear(digits, 0, 10);
for ( int i = 0; i < s.Length; i++)
digits[s[i] - ( int ) '0' ] = 1;
for ( int i = 0; i <= 9; i++)
if (digits[i] == 0)
return 0;
return 1;
}
static int countPandigitalPairs( ref List< string > v)
{
int pairs = 0;
for ( int i = 0; i < v.Count; i++)
for ( int j = i + 1; j < v.Count; j++)
if (isPanDigital(v[i] + v[j]) == 1)
pairs++;
return pairs;
}
static void Main()
{
List< string > v = new List< string >{ "123567" , "098234" ,
"14765" , "19804" };
Console.WriteLine(countPandigitalPairs( ref v));
}
}
|
PHP
<?php
function isPanDigital( $s )
{
$digits = array ();
$digits = array_fill (0, 10, false);
for ( $i = 0; $i < strlen ( $s ); $i ++)
$digits [ord( $s [ $i ]) -
ord( '0' )] = true;
for ( $i = 0; $i <= 9; $i ++)
if ( $digits [ $i ] == false)
return false;
return true;
}
function countPandigitalPairs(& $v )
{
$pairs = 0;
for ( $i = 0;
$i < count ( $v ); $i ++)
{
for ( $j = $i + 1;
$j < count ( $v ); $j ++)
{
if (isPanDigital( $v [ $i ]. $v [ $j ]))
{
$pairs ++;
}
}
}
return $pairs ;
}
$v = array ( "123567" , "098234" ,
"14765" , "19804" );
echo (countPandigitalPairs( $v ));
?>
|
Javascript
<script>
function isPanDigital(s)
{
let digits = new Array(10).fill( false );
for (let i = 0; i < s.length; i++)
digits[s[i].charCodeAt(0) -
'0' .charCodeAt(0)] = true ;
for (let i = 0; i <= 9; i++)
if (digits[i] == false )
return false ;
return true ;
}
function countPandigitalPairs(v)
{
let pairs = 0;
for (let i = 0; i < v.length; i++)
{
for (let j = i + 1;
j < v.length; j++)
{
if (isPanDigital(v[i] + v[j]))
{
pairs++;
}
}
}
return pairs;
}
let v = [ "123567" , "098234" ,
"14765" , "19804" ];
document.write(countPandigitalPairs(v));
</script>
|
Time Complexity : The time complexity of the given program is O(n^2 * k), where n is the number of strings in the input vector and k is the length of the longest string in the vector. This is because the program has nested loops that iterate over all pairs of strings in the input vector, and the isPanDigital function has a loop that iterates over each character in the concatenated string, which takes O(k) time. Therefore, the overall time complexity is O(n^2 * k).
Space Complexity: The space complexity of the program is O(1), as it uses a constant amount of additional space regardless of the size of the input vector or the length of the strings. This is because it uses a fixed-size boolean array of size 10 to keep track of the presence of digits in a string.
Method 2 (Efficient):
Now we look for something better than the brute-force discussed above. Careful analysis suggests that, for every digit 0 – 9 to be present we have a mask as 1111111111 (i.e. all numbers 0-9 exist in the array of numbers
Digits - 0 1 2 3 4 5 6 7 8 9
| | | | | | | | | |
Mask - 1 1 1 1 1 1 1 1 1 1
Here 1 denotes that the corresponding digits
exists at-least once thus for all such Pandigital
Concatenations, this relationship should hold.
So we can represent 11...11 as a valid mask for
pandigital concatenations.
So now the approach is to represent every string as a mask of 10 bits where the ith bit is set if the ith digit exists in the string.
E.g., "11405" can be represented as
Digits - 0 1 2 3 4 5 6 7 8 9
| | | | | | | | | |
Mask for 11405 - 1 1 0 0 1 1 0 0 0 0
The approach though may look complete is still not efficient as we still have to iterate over all pairs and check if the OR of these two strings results in the mask of a valid Pandigital Concatenation.
If we analyze the possible masks of all possible strings we can understand that every single string would be only comprised of digits 0 – 9, so every number can at max contain all digits 0 to 9 at least once thus the mask of such a number would be 1111111111 (1023 in decimal). Thus, in the decimal system all masks exit in (0 – 1023].
Now we just have to maintain a frequency array to store the number of times a mask exists in the array of strings.
Let two masks be i and j with frequencies freqi and freqj respectively,
If (i OR j) = Maskpandigital concatenation
Then,
Number of Pairs = freqi * freqj
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
const int pandigitalMask = ((1 << 10) - 1);
void computeMaskFrequencies(vector<string> v, map< int ,
int >& freq)
{
for ( int i = 0; i < v.size(); i++) {
int mask = 0;
unordered_set< int > digits;
for ( int j = 0; j < v[i].size(); j++)
digits.insert(v[i][j] - '0' );
for ( auto it = digits.begin(); it != digits.end(); it++) {
int digit = (*it);
mask += (1 << digit);
}
freq[mask]++;
}
}
int pandigitalConcatenations(map< int , int > freq)
{
int ans = 0;
for ( int i = 1; i <= 1023; i++) {
for ( int j = 1; j <= 1023; j++) {
if ((i | j) == pandigitalMask) {
if (i == j)
ans += (freq[i] * (freq[i] - 1));
else
ans += (freq[i] * freq[j]);
}
}
}
return ans/2;
}
int countPandigitalPairs(vector<string> v)
{
map< int , int > freq;
computeMaskFrequencies(v, freq);
return pandigitalConcatenations(freq);
}
int main()
{
vector<string> v = { "123567" , "098234" , "14765" , "19804" };
cout << countPandigitalPairs(v) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int pandigitalMask = (( 1 << 10 ) - 1 );
static void computeMaskFrequencies(Vector<String> v,
HashMap<Integer, Integer> freq)
{
for ( int i = 0 ; i < v.size(); i++)
{
int mask = 0 ;
HashSet<Integer> digits = new HashSet<>();
for ( int j = 0 ; j < v.get(i).length(); j++)
digits.add(v.get(i).charAt(j) - '0' );
for ( int it :digits)
{
int digit = (it);
mask += ( 1 << digit);
}
if (freq.containsKey(mask))
{
freq.put(mask, freq.get(mask) + 1 );
}
else
{
freq.put(mask, 1 );
}
}
}
static int pandigitalConcatenations(
HashMap<Integer, Integer> freq)
{
int ans = 0 ;
for ( int i = 1 ; i <= 1023 ; i++)
{
for ( int j = 1 ; j <= 1023 ; j++)
{
if ((i | j) == pandigitalMask &&
freq.containsKey(j) &&
freq.containsKey(i))
{
if (i == j)
ans += (freq.get(i) *
(freq.get(i) - 1 ));
else
ans += (freq.get(i) *
freq.get(j));
}
}
}
return ans / 2 ;
}
static int countPandigitalPairs(Vector<String> v)
{
HashMap<Integer,Integer> freq = new HashMap<>();
computeMaskFrequencies(v, freq);
return pandigitalConcatenations(freq);
}
public static void main(String[] args)
{
Vector<String> v = new Vector<>();
v.add( "123567" );
v.add( "098234" );
v.add( "14765" );
v.add( "19804" );
System.out.print(countPandigitalPairs(v) + "\n" );
}
}
|
Python3
pandigitalMask = (( 1 << 10 ) - 1 )
freq = dict ()
def computeMaskFrequencies(v):
global freq
for i in range ( len (v)):
mask = 0
digits = set ()
for j in range ( len (v[i])):
digits.add( int (v[i][j]))
for it in digits:
digit = it
mask + = ( 1 << digit)
if mask in freq:
freq[mask] + = 1
else :
freq[mask] = 1
def pandigitalConcatenations():
global freq
ans = 0
for i in range ( 1 , 1024 ):
for j in range ( 1 , 1024 ):
if ((i | j) = = pandigitalMask and
i in freq and j in freq):
if (i = = j):
ans + = (freq[i] * (freq[i] - 1 ))
else :
ans + = (freq[i] * freq[j])
return ans / / 2
def countPandigitalPairs(v):
computeMaskFrequencies(v)
return pandigitalConcatenations()
v = [ "123567" , "098234" , "14765" , "19804" ]
print (countPandigitalPairs(v))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int pandigitalMask =
((1 << 10) - 1);
static void computeMaskFrequencies(List<String> v,
Dictionary< int ,
int > freq)
{
for ( int i = 0; i < v.Count; i++)
{
int mask = 0;
HashSet< int > digits = new HashSet< int >();
for ( int j = 0; j < v[i].Length; j++)
digits.Add(v[i][j] - '0' );
foreach ( int it in digits)
{
int digit = (it);
mask += (1 << digit);
}
if (freq.ContainsKey(mask))
{
freq[mask]++;
}
else
{
freq.Add(mask, 1);
}
}
}
static int pandigitalConcatenations(Dictionary< int ,
int > freq)
{
int ans = 0;
for ( int i = 1; i <= 1023; i++)
{
for ( int j = 1; j <= 1023; j++)
{
if ((i | j) == pandigitalMask &&
freq.ContainsKey(j) &&
freq.ContainsKey(i))
{
if (i == j)
ans += (freq[i] *
(freq[i] - 1));
else
ans += (freq[i] *
freq[j]);
}
}
}
return ans / 2;
}
static int countPandigitalPairs(List<String> v)
{
Dictionary< int ,
int > freq = new Dictionary< int ,
int >();
computeMaskFrequencies(v, freq);
return pandigitalConcatenations(freq);
}
public static void Main(String[] args)
{
List<String> v = new List<String>();
v.Add( "123567" );
v.Add( "098234" );
v.Add( "14765" );
v.Add( "19804" );
Console.Write(countPandigitalPairs(v) + "\n" );
}
}
|
Javascript
<script>
const pandigitalMask = ((1 << 10) - 1);
function computeMaskFrequencies(v, freq)
{
for (let i = 0; i < v.length; i++)
{
let mask = 0;
let digits = new Set();
for (let j = 0; j < v[i].length; j++)
digits.add((v[i][j]).charCodeAt(0) -
'0' .charCodeAt(0));
for (let it of digits)
{
let digit = it;
mask += (1 << digit);
}
if (freq.has(mask))
{
freq.set(mask, freq.get(mask) + 1)
}
else
{
freq.set(mask, 1)
}
}
}
function pandigitalConcatenations(freq)
{
let ans = 0;
for (let i = 1; i <= 1023; i++)
{
for (let j = 1; j <= 1023; j++)
{
if ((i | j) == pandigitalMask &&
freq.has(i) && freq.has(j))
{
if (i == j)
ans += (freq.get(i) *
(freq.get(i) - 1));
else
ans += (freq.get(i) *
freq.get(j));
}
}
}
return Math.floor(ans / 2);
}
function countPandigitalPairs(v)
{
let freq = new Map();
computeMaskFrequencies(v, freq);
return pandigitalConcatenations(freq);
}
let v = [ "123567" , "098234" , "14765" , "19804" ];
document.write(countPandigitalPairs(v) + "<br>" );
</script>
|
Complexity : O(N * |s| + 1023 * 1023) where |s| gives length of strings in the array.
Last Updated :
03 May, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...