Given an unsorted integer (positive values only) array of size ‘n’, we can form a group of two or three, the group should be such that the sum of all elements in that group is a multiple of 3. Count all possible number of groups that can be generated in this way.
Examples:
Input: arr[] = {3, 6, 7, 2, 9}
Output: 8
// Groups are {3,6}, {3,9}, {9,6}, {7,2}, {3,6,9},
// {3,7,2}, {7,2,6}, {7,2,9}
Input: arr[] = {2, 1, 3, 4}
Output: 4
// Groups are {2,1}, {2,4}, {2,1,3}, {2,4,3}
The idea is to see remainder of every element when divided by 3. A set of elements can form a group only if sum of their remainders is multiple of 3.
For example : 8, 4, 12. Now, the remainders are 2, 1, and 0 respectively. This means 8 is 2 distance away from 3s multiple (6), 4 is 1 distance away from 3s multiple(3), and 12 is 0 distance away. So, we can write the sum as 8 (can be written as 6+2), 4 (can be written as 3+1), and 12 (can be written as 12+0). Now the sum of 8, 4 and 12 can be written as 6+2+3+1+12+0. Now, 6+3+12 will always be divisible by 3 as all the terms are multiple of three. Now, we only need to check if 2+1+0 (remainders) is divisible by 3 or not which makes the complete sum divisible by 3.
Since the task is to enumerate groups, we count all elements with different remainders.
1. Hash all elements in a count array based on remainder, i.e,
for all elements a[i], do c[a[i]%3]++;
2. Now c[0] contains the number of elements which when divided
by 3 leave remainder 0 and similarly c[1] for remainder 1
and c[2] for 2.
3. Now for group of 2, we have 2 possibilities
a. 2 elements of remainder 0 group. Such possibilities are
c[0]*(c[0]-1)/2
b. 1 element of remainder 1 and 1 from remainder 2 group
Such groups are c[1]*c[2].
4. Now for group of 3,we have 4 possibilities
a. 3 elements from remainder group 0.
No. of such groups are c[0]C3
b. 3 elements from remainder group 1.
No. of such groups are c[1]C3
c. 3 elements from remainder group 2.
No. of such groups are c[2]C3
d. 1 element from each of 3 groups.
No. of such groups are c[0]*c[1]*c[2].
5. Add all the groups in steps 3 and 4 to obtain the result.
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
int findgroups( int arr[], int n)
{
int c[3] = {0}, i;
int res = 0;
for (i=0; i<n; i++)
c[arr[i]%3]++;
res += ((c[0]*(c[0]-1))>>1);
res += c[1] * c[2];
res += (c[0] * (c[0]-1) * (c[0]-2))/6;
res += (c[1] * (c[1]-1) * (c[1]-2))/6;
res += ((c[2]*(c[2]-1)*(c[2]-2))/6);
res += c[0]*c[1]*c[2];
return res;
}
int main()
{
int arr[] = {3, 6, 7, 2, 9};
int n = sizeof (arr)/ sizeof (arr[0]);
cout << "Required number of groups are "
<< findgroups(arr,n) << endl;
return 0;
}
|
C
#include<stdio.h>
int findgroups( int arr[], int n)
{
int c[3] = {0}, i;
int res = 0;
for (i=0; i<n; i++)
c[arr[i]%3]++;
res += ((c[0]*(c[0]-1))>>1);
res += c[1] * c[2];
res += (c[0] * (c[0]-1) * (c[0]-2))/6;
res += (c[1] * (c[1]-1) * (c[1]-2))/6;
res += ((c[2]*(c[2]-1)*(c[2]-2))/6);
res += c[0]*c[1]*c[2];
return res;
}
int main()
{
int arr[] = {3, 6, 7, 2, 9};
int n = sizeof (arr)/ sizeof (arr[0]);
printf ( "Required number of groups are %d\n" , findgroups(arr,n));
return 0;
}
|
Java
class FindGroups
{
int findgroups( int arr[], int n)
{
int c[] = new int []{ 0 , 0 , 0 };
int i;
int res = 0 ;
for (i = 0 ; i < n; i++)
c[arr[i] % 3 ]++;
res += ((c[ 0 ] * (c[ 0 ] - 1 )) >> 1 );
res += c[ 1 ] * c[ 2 ];
res += (c[ 0 ] * (c[ 0 ] - 1 ) * (c[ 0 ] - 2 )) / 6 ;
res += (c[ 1 ] * (c[ 1 ] - 1 ) * (c[ 1 ] - 2 )) / 6 ;
res += ((c[ 2 ] * (c[ 2 ] - 1 ) * (c[ 2 ] - 2 )) / 6 );
res += c[ 0 ] * c[ 1 ] * c[ 2 ];
return res;
}
public static void main(String[] args)
{
FindGroups groups = new FindGroups();
int arr[] = { 3 , 6 , 7 , 2 , 9 };
int n = arr.length;
System.out.println( "Required number of groups are "
+ groups.findgroups(arr, n));
}
}
|
Python3
def findgroups(arr, n):
c = [ 0 , 0 , 0 ]
res = 0
for i in range ( 0 , n):
c[arr[i] % 3 ] + = 1
res + = ((c[ 0 ] * (c[ 0 ] - 1 )) >> 1 )
res + = c[ 1 ] * c[ 2 ]
res + = (c[ 0 ] * (c[ 0 ] - 1 ) * (c[ 0 ] - 2 )) / 6
res + = (c[ 1 ] * (c[ 1 ] - 1 ) * (c[ 1 ] - 2 )) / 6
res + = ((c[ 2 ] * (c[ 2 ] - 1 ) * (c[ 2 ] - 2 )) / 6 )
res + = c[ 0 ] * c[ 1 ] * c[ 2 ]
return res
arr = [ 3 , 6 , 7 , 2 , 9 ]
n = len (arr)
print ( "Required number of groups are" ,
int (findgroups(arr, n)))
|
C#
using System;
class FindGroups
{
int findgroups( int []arr, int n)
{
int [] c= new int []{0, 0, 0};
int i;
int res = 0;
for (i = 0; i < n; i++)
c[arr[i] % 3]++;
res += ((c[0] * (c[0] - 1)) >> 1);
res += c[1] * c[2];
res += (c[0] * (c[0] - 1) *
(c[0] - 2)) / 6;
res += (c[1] * (c[1] - 1) *
(c[1] - 2)) / 6;
res += ((c[2] * (c[2] - 1) *
(c[2] - 2)) / 6);
res += c[0] * c[1] * c[2];
return res;
}
public static void Main()
{
FindGroups groups = new FindGroups();
int []arr = {3, 6, 7, 2, 9};
int n = arr.Length;
Console.Write( "Required number of groups are "
+ groups.findgroups(arr, n));
}
}
|
PHP
<?php
function findgroups( $arr , $n )
{
$c = array (0, 0, 0);
$res = 0;
for ( $i = 0; $i < $n ; $i ++)
$c [ $arr [ $i ] % 3] += 1;
$res += (( $c [0] * ( $c [0] - 1)) >> 1);
$res += $c [1] * $c [2];
$res += ( $c [0] * ( $c [0] - 1) *
( $c [0] - 2)) / 6;
$res += ( $c [1] * ( $c [1] - 1) *
( $c [1] - 2)) / 6;
$res += (( $c [2] * ( $c [2] - 1) *
( $c [2] - 2)) / 6);
$res += $c [0] * $c [1] * $c [2];
return $res ;
}
$arr = array (3, 6, 7, 2, 9);
$n = count ( $arr );
echo "Required number of groups are " .
(int)(findgroups( $arr , $n ));
?>
|
Javascript
<script>
function findgroups(arr, n){
let c = [0,0,0];
let i;
let res = 0;
for (i=0; i<n; i++)
c[arr[i]%3]++;
res += ((c[0]*(c[0]-1))>>1);
res += c[1] * c[2];
res += (c[0] * (c[0]-1) * Math.floor((c[0]-2))/6);
res += (c[1] * (c[1]-1) * Math.floor((c[1]-2))/6);
res += (Math.floor(c[2]*(c[2]-1)*(c[2]-2))/6);
res += c[0]*c[1]*c[2];
return res;
}
let arr = [3, 6, 7, 2, 9];
let n = arr.length;
document.write( "Required number of groups are " + findgroups(arr,n));
</script>
|
OutputRequired number of groups are 8
Time Complexity: O(n)
Auxiliary Space: O(1)