• + 6 comments

    We are dealing with a lot of numbers, and therefore we need to convert the tickets into something that is easier to compute. Now, each ticket has numbers between 0 & 9, and if we can just keep a database of the presence of these numbers, our work will be easier. The easiest way of doing it in my opinion is creating a string of 1's and 0's of 10 characters, where 1 signifies the presence and 0 signifies the absence of the number on whose index it sits.

    For example, 154879664841684464864 can be written as 0100111111 symbolizing the presence of 1, 4, 5, 6, 7, 8 & 9.

    We can conviniently convert these binary equivaents to an integer value and as the length of string is 10, the maximum integer value we can expect is 1023. Now if we take a pair of the above integer values, we can say the pair has every number present if the bitwise OR operation of the pair gives 1111111111, i.e. a string of 10 1's, whose decimal equivalent is 1023. This is because an OR operation gives a 0 only if there is a 0 at the place in both values. Therefore the bitwise OR operation will return 1023 when each number is present in either one of the 2 pairs.

    But systamatically comparing every number and increasing a counter variable on getting 1023 will take too much time. Therefore we can create an integer array of 1024 places and store the frequency of the occurence of each element from 0 to 1023 in the array. We can do this by increasing the value of the number by 1, which is present at the index which is equal to the number we get after conversion.

    Now, we can just systamtically compare pairs of values from 0 to 1023 and if the bitwise OR operation of 2 values, i & j is equals 1023, we can multiply the numbers at the index i & j and add the product to the counter variable, i.e. we multiply the frequency of both the numbers i & j and add them to the counter.

    But just that won't suffice. We need to take special care of the value of array at 1023, as the tickets who have that value can form pairs with themselves and create a valid pair. So we multiply the value with (value -1) and divide them by 2, and add it to the counter variable. The value*(value-1) means every combination of the numbers who convert to 1023, and as that creates mirror pairs, we divide it by 2.

    Some terms might be specific to JAVA as I only know that for now.

    Here's my solution in java that works on all testcases :

    import java.util.*;
    
    public class Play {
        public static int binaryEquivalent(String s) {
            String binaryBuilder;
            char[] bits = {'0','0','0','0','0','0','0','0','0','0'};
            char character;
            for (int i = 0; i < s.length(); i++) {
                character = s.charAt(i);
                bits[character-48] = '1';           //In ASCII, '0' = 48. 
                //Here if a number is present, we are putting a 1 in place of a 0 at that index.
            }
            binaryBuilder = ""+bits[0]+bits[1]+bits[2]+bits[3]+bits[4]+bits[5]+bits[6]+bits[7]+bits[8]+bits[9];
            return Integer.parseInt(binaryBuilder,2);
        }
    
        private static final Scanner scanner = new Scanner(System.in);
    
        public static void main(String[] args) {
            long[] frequency = new long[1024];
            int binary;
            int size = scanner.nextInt();
            scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");   //Only to solve an input related error of scanner.
            long  counter = 0l;
    
            for (int i = 0; i < size; i++) {
                String ticketsItem = scanner.nextLine();
                binary = binaryEquivalent(ticketsItem);
                frequency[binary] = frequency[binary] + 1l;
            }
            for (int i = 0; i < 1023; i++) {
                if(frequency[i]==0)
                    continue;
                for(int j=i+1;j<1024;j++) {
                    if((i|j)==1023)
                        counter += frequency[i]*frequency[j];
                }
            }
            counter += frequency[1023]*(frequency[1023]-1)/2;
            System.out.println(counter);
            scanner.close();
        }
    }