perl logo Perl logo (Thanks to Olaf Alders)

The weekly challenge 324 - Task 2: Total XOR

 1 #!/usr/bin/env perl
 2 # https://theweeklychallenge.org/blog/perl-weekly-challenge-324/#TASK2
 3 #
 4 # Task 2: Total XOR
 5 # =================
 6 #
 7 # You are given an array of integers.
 8 #
 9 # Write a script to return the sum of total XOR for every subset of given
10 # array.
11 #
12 ## Example 1
13 ##
14 ## Input: @ints = (1, 3)
15 ## Output: 6
16 ##
17 ## Subset [1],    total XOR = 1
18 ## Subset [3],    total XOR = 3
19 ## Subset [1, 3], total XOR => 1 XOR 3 => 2
20 ##
21 ## Sum of total XOR => 1 + 3 + 2 => 6
22 #
23 #
24 ## Example 2
25 ##
26 ## Input: @ints = (5, 1, 6)
27 ## Output: 28
28 ##
29 ## Subset [5],       total XOR = 5
30 ## Subset [1],       total XOR = 1
31 ## Subset [6],       total XOR = 6
32 ## Subset [5, 1],    total XOR => 5 XOR 1 => 4
33 ## Subset [5, 6],    total XOR => 5 XOR 6 => 3
34 ## Subset [1, 6],    total XOR => 1 XOR 6 => 7
35 ## Subset [5, 1, 6], total XOR => 5 XOR 1 XOR 6 => 2
36 ##
37 ## Sum of total XOR => 5 + 1 + 6 + 4 + 3 + 7 + 2 => 28
38 #
39 #
40 ## Example 3
41 ##
42 ## Input: @ints = (3, 4, 5, 6, 7, 8)
43 ## Output: 480
44 #
45 ############################################################
46 ##
47 ## discussion
48 ##
49 ############################################################
50 #
51 # First, we make sure that we have a set of unique elements,
52 # eliminating duplicates using List::Util's uniq().
53 # Then we create all possible subsets using Algorithm::Combinatorics'
54 # subsets() - we use the iterator interface so we don't eat
55 # unnecessary memory.
56 # For each subset, we then calculate the xor of this subset. For
57 # that, we start with 0, then we xor each element of the array to
58 # the current value until there are no more elements. Then we add
59 # that result to our current total value.
60 #
61 
62 use v5.36;
63 use List::Util qw( uniq );
64 use Algorithm::Combinatorics qw( subsets );
65 
66 total_xor(1, 3);
67 total_xor(5, 1, 6);
68 total_xor(3, 4, 5, 6, 7, 8);
69 
70 sub total_xor( @ints ) {
71     say "Input: (" . join(", ", @ints) . ")";
72     my @set = uniq @ints;
73     my $iter = subsets( \@ints );
74     my $result = 0;
75     while ( my $set = $iter->next ) {
76         my $tmp = 0;
77         foreach my $elem (@$set) {
78             $tmp = $tmp ^ $elem;
79         }
80         $result += $tmp;
81     }
82     say "Output: $result";
83 }
84