Sum of All Subset XOR Totals

Problem

The XOR total of an array is defined as the bitwise XOR of all its elements, or 0 if the array is empty.

  • For example, the XOR total of the array [2,5,6] is 2 XOR 5 XOR 6 = 1.

Given an array nums, return the sum of all XOR totals for every subset of nums.

Note: Subsets with the same elements should be counted multiple times.

An array a is a subset of an array b if a can be obtained from b by deleting some (possibly zero) elements of b.

Example 1:

Input: nums = [1,3]
Output: 6
Explanation: The 4 subsets of [1,3] are:

- The empty subset has an XOR total of 0.
- [1] has an XOR total of 1.
- [3] has an XOR total of 3.
- [1,3] has an XOR total of 1 XOR 3 = 2.
0 + 1 + 3 + 2 = 6

Example 2:

Input: nums = [5,1,6]
Output: 28
Explanation: The 8 subsets of [5,1,6] are:

- The empty subset has an XOR total of 0.
- [5] has an XOR total of 5.
- [1] has an XOR total of 1.
- [6] has an XOR total of 6.
- [5,1] has an XOR total of 5 XOR 1 = 4.
- [5,6] has an XOR total of 5 XOR 6 = 3.
- [1,6] has an XOR total of 1 XOR 6 = 7.
- [5,1,6] has an XOR total of 5 XOR 1 XOR 6 = 2.
0 + 5 + 1 + 6 + 4 + 3 + 7 + 2 = 28

Example 3:

Input: nums = [3,4,5,6,7,8]
Output: 480
Explanation: The sum of all XOR totals for every subset is 480.

Constraints:

  • 1 <= nums.length <= 12
  • 1 <= nums[i] <= 20

Solution

class Solution {
    public int subsetXORSum(int[] nums) {
        var subsets = new ArrayList<List<Integer>>();
        subsets(nums, 0, List.of(), subsets);
        // for each subset, compute the XOR total
        return subsets.stream().map((subset) -> {
            var total = 0;
            for (var i : subset) {
                total = total ^ i;
            }
            return total;
        }).reduce(Integer::sum).orElseThrow();
    }

    public void subsets(int[] nums, int i, List<Integer> curr, List<List<Integer>> subsets) {
        // at each step, we can choose to add nums[i] to curr or not
        if (i == nums.length) {
            // for sanity
            if (!curr.isEmpty()) {
                subsets.add(curr);
            }
            return;
        }
        // choose to not add
        subsets(nums, i + 1, curr, subsets);
        // choose to add
        var copy = new ArrayList<>(curr);
        copy.add(nums[i]);
        subsets(nums, i + 1, copy, subsets);
    }
}

Recent posts from blogs that I like

going fast and slow

on novel logic

via bookbear express

They really do think AI might kill everyone

A recent resignation tweet from an Anthropic researcher has everyone talking about the AI apocalypse again. Among other things, he said:

The people building AI earnestly believe that it could kill us all by the end of the decade.

Many people found it hard to believe that AI researchers think this ...

via Sean Goedecke

Brushstrokes: Lovis Corinth’s narratives

His style evolved from a mildly painterly realism in 1890, steadily loosened in the early 1900s, then broke up into brushstrokes and marks by the early 1920s. But continued to tell stories effectively.

via The Eclectic Light Company