C++ | Recursion + Memoization | Descriptive Code | Bitmasks |  Subset Generation | Backtracking | 
Code
# Code
```cpp []
#include <bits/stdc++.h>
using namespace std;


template<class Fun> class y_combinator_result { Fun fun_;
public:
    template<class T> explicit y_combinator_result(T &&fun): fun_(std::forward<T>(fun)) {}
    template<class ...Args> decltype(auto) operator()(Args &&...args) { return fun_(std::ref(*this), std::forward<Args>(args)...); }
};
template<class Fun> decltype(auto) y_combinator(Fun &&fun) { return y_combinator_result<std::decay_t<Fun>>(std::forward<Fun>(fun)); }

class Solution {
private:
    const int INF = 2e9; 

    int pop_count(int mask) {
        return __builtin_popcount(mask);
    }

    bool cant_distribute(vector<int> &nums, int K) {
        unordered_map<int, int> counter;
        for(int num : nums)
            counter[num]++;
        
        for(auto [_, freq] : counter) {
            if(freq > K) return true;
        }
        return false;
    }
    
    // Returns list of masks, such that if mask[i] = Is i included in current take set ?
    // if prev_mask[i] = 1; index 'i' already taken, we cant take it
    // if prev_mask[i] = 0; we can take the index 
    vector<int> get_valid_masks(vector<int> &nums, int group_size, int prev_mask) {  
        int N = nums.size();        
        vector<int> masks;

        auto get_vals_mask = [&] (int mask) -> int {
            int vals_mask = 0;

            for(int index = 0; index < N; index++) {
                bool in_set = mask & (1 << index);
                if(in_set) {
                    int cur_val = nums[index];
                    vals_mask |= (1 << cur_val);
                }
            }

            return vals_mask;
        };
        
        auto generate_subsets = y_combinator([&] (auto generate_subsets, int ind, int cur_mask) -> void {      
            if(pop_count(cur_mask) == group_size) {
                masks.push_back(cur_mask);
                return;
            }
            if(ind >= N) return;
            
            int cur_val = nums[ind], took_vals_mask = get_vals_mask(cur_mask);

            bool is_duplicate_in_cur_set = (took_vals_mask & (1 << cur_val)); // We Can't Have duplicates in a group
            bool can_take_index = !(prev_mask & (1 << ind)); // We Can't take indices which have been previously taken already

            // take into current subset
            if(can_take_index && !is_duplicate_in_cur_set) 
                generate_subsets(ind + 1, cur_mask | (1 << ind));
            
            generate_subsets(ind + 1, cur_mask);

        });

        generate_subsets(0, 0);
                
        return masks;
    }
    
    int get_incompatibility(int subset_mask, vector<int> &nums) {
        int N = nums.size(), max_val = 0, min_val = INF;
        
        
        for(int index = 0; index < N; index++) {
            bool in_set = subset_mask & (1 << index);
            if(in_set) {
                int cur_val = nums[index];
                max_val = max(max_val, cur_val);
                min_val = min(min_val, cur_val);
            } 
        }
        
        return max_val - min_val;
    }
    
public:
    int minimumIncompatibility(vector<int>& nums, int K) {
        int N = nums.size();

        if(cant_distribute(nums, K)) return -1;
        if(N == K) return 0;

        int group_size = N / K; 

        int cache_size = 1 << N;
        vector<int> cache(cache_size, -1);
        
        auto solve = y_combinator([&] (auto solve, int mask) -> int {      
            int took_cnt = pop_count(mask);
            if(took_cnt >= N) return 0;
            if(cache[mask] != -1) return cache[mask];

            vector<int> subset_choices_masks = get_valid_masks(nums, group_size, mask);
            
            int res = INF;
            
            for(int cur_subset_mask : subset_choices_masks) {
                    
                int cur_incompatibility = get_incompatibility(cur_subset_mask, nums);                
                
                int new_mask = mask | cur_subset_mask;
                                
                int cur_incompatibility_sum = cur_incompatibility + solve(new_mask);
                
                res = min(res, cur_incompatibility_sum);
            }
            
            return cache[mask] = res;
        });
        
        int res = solve(0);
        
        return res;
              
    }
};
```
['Backtracking', 'Bit Manipulation', 'Recursion', 'Memoization', 'Bitmask', 'C++']