Golang & JavaScript [Bitmask+DP+DFS]
go\ntype indicesAndIndex struct {\n    indices []int\n    index int\n}\n\nfunc minimumIncompatibility(nums []int, k int) int {\n    // do some easy O(n) checks 
```go\ntype indicesAndIndex struct {\n    indices []int\n    index int\n}\n\nfunc minimumIncompatibility(nums []int, k int) int {\n    // do some easy O(n) checks to see if we can return before the\n    // major computation\n    length := len(nums)\n    \n    // if there is only 1 number in each subset, we know the result is 0\n    if length == k {\n        return 0\n    }\n    \n    // if the count of a value is more than the number of subsets\n    // we know there will be repeating numbers in a subset so we return -1\n    freqCount := make(map[int]int)\n    for _, num := range nums {\n        if count, ok := freqCount[num]; ok {\n            if count == k {\n                return -1\n            } else {\n                freqCount[num] = count + 1\n            }\n        } else {\n            freqCount[num] = 1\n        }\n    }    \n    \n    // (aka memo, dp, /*python*/ @lru_cache)\n    cache := make(map[int]int)\n    numberOfElementsInBucket := length / k\n    \n    /* \n    BITWISE\n    to store the number of elements used, we use bitwise which has a 0 or 1 value\n    1 - means index was used\n    0 - means index was not used\n    */    \n    // create a mask to indicate all indexes in `nums` were used\n    allIndicesUsedMask := (1 << length) - 1\n    // create a mask to indicate no indexes in `nums` were used\n    currentUsedIndicesMask := 0\n    \n    return dfs(currentUsedIndicesMask, allIndicesUsedMask, numberOfElementsInBucket, &nums, &cache)\n}\n\nfunc dfs(currentUsedIndicesMask, allIndicesUsedMask, numberOfElementsInBucket int, nums *[]int, cache *map[int]int) int {\n    // if we used all the values in nums, return 0\n    if currentUsedIndicesMask == allIndicesUsedMask {\n        return 0\n    }\n    \n    // if the indicies used and unused is the same as a previous\n    // DFS call, return the previous call because\n    // we know we already have calculated the minimum incompatibility cost\n    if val, ok := (*cache)[currentUsedIndicesMask]; ok {\n        return val\n    }\n    \n    // we add all indices to a slice for indicies that have not been used yet\n    // and \'values\' have not been used/seen (we only want unique values)\n    // *note: we don\'t care which index of a value we get just as long as no 2 indices have the same value\n    valsToIndices := make(map[int]bool)\n    indices := make([]int, 0)\n    for idx, val := range *nums {\n        // if we already used the indices, skip this index\n        if (currentUsedIndicesMask & (1 << idx)) != 0 {\n            continue\n        }\n        // if we have not seen this value before, add it to the indices slice\n        if _, ok := valsToIndices[val]; !ok {\n            valsToIndices[val] = true\n            indices = append(indices, idx)\n        }\n    }\n\n    // create all different combinations of indices\n    // *note: this is different from "permutations"\n    combinations := createCombinations(&indices, numberOfElementsInBucket)\n    \n    // create a variable to store the minimum incompatibility cose\n    // 99999 is just a place holder, you can replace this with MAX_INT\n    minIncompatibilityCost := 99999\n    \n    /*\n    for every combination\n    - create a new mask by adding a 1 to every position of index\n    - caculate the incompatibility cost by finding the max and min value\n    - then call DFS again while adding the incompatibility cost to the returned value\n    - compare the minimum of all the different costs\n    */\n    for i, _ := range combinations {\n        indices := combinations[i]\n        nextUsedIndicesMask := currentUsedIndicesMask\n        minVal, maxVal := 9999, -9999 // values are from 0-16\n        for _, index := range indices {\n            val := (*nums)[index]\n            minVal = minInt(minVal, val)\n            maxVal = maxInt(maxVal, val)\n            nextUsedIndicesMask = nextUsedIndicesMask | (1 << index)\n        }\n        incompatibilityCost := maxVal - minVal\n        minIncompatibilityCost = minInt(minIncompatibilityCost,\n                                        dfs(nextUsedIndicesMask, \n                                            allIndicesUsedMask, \n                                            numberOfElementsInBucket, \n                                            nums, \n                                            cache) + incompatibilityCost)\n    }\n    \n    // store the cost into the cache so we don\'t need to compute this\n    // state again\n    (*cache)[currentUsedIndicesMask] = minIncompatibilityCost\n    \n    // return the cost\n    return minIncompatibilityCost\n}\n\nfunc createCombinations(indices *[]int, combinationLen int) [][]int {\n    n := len(*indices)\n    combinations := make([][]int, 0)\n    if n < combinationLen {\n        return combinations\n    }\n    stack := []indicesAndIndex { { indices: []int{}, index: 0 } }\n    m := 1\n    for ; m > 0; m = len(stack) {\n        idxsAndidx := stack[m - 1]\n        stack = stack[:m - 1]\n        idxs, i := idxsAndidx.indices, idxsAndidx.index\n        o := len(idxs)\n        for ; i < n; i++ {\n            combination := make([]int, o, o + 1)\n            copy(combination, idxs)\n            combination = append(combination, (*indices)[i])\n            if combinationLen == len(combination) {\n                combinations = append(combinations, combination)\n            } else {\n                stack = append(stack, indicesAndIndex{ indices: combination, index: i + 1 })\n            }\n        }\n    }\n    return combinations\n}\n\nfunc minInt(a, b int) int {\n    if a < b {\n        return a\n    }\n    return b\n}\n\nfunc maxInt(a, b int) int {\n    if a < b {\n        return b\n    }\n    return a\n}\n```\n\n```javascript\n////////////////////////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////\n////////////////////////////////////////////////////////////////////////////////////////////\n\n\nvar minimumIncompatibility = function(nums, k) {\n\t////// FROM HERE TO\n    if (nums.length === k) return 0;\n    \n    const maxInBucket = nums.length / k;\n    const freqCount = {};\n    for (const n of nums) {\n        if (freqCount[n]) {\n            if (freqCount[n] === k) {\n                return -1\n            } else {\n                freqCount[n]++\n            }\n        } else {\n            freqCount[n] = 1\n        }\n    }\n\t/////// HERE is just saving time\n    \n\t// create a cache (aka memo, dp, dynamic programming, momoization)\n    const cache = {}\n\t// create a mask to know when all the indicies are used\n    const allIndiciesUsedMask = 2 ** nums.length - 1;\n    \n    const dfs = (usedIndicesBitMask) => {\n\t    // if we have used all the indicies then we return 0\n        if (usedIndicesBitMask === allIndiciesUsedMask) {\n            return 0;\n        }\n\t\t// if we have seen this combination before, return the\n\t\t// result that was calculated before\n\t\t// otherwise do the hard work LOL\n        if (cache[usedIndicesBitMask]) {\n            return cache[usedIndicesBitMask];\n        }\n        \n\t\t// find all the indicies that are available to be used\n\t\t// skip duplicate values\n        const valsToIndices = {};\n        for (let i = 0; i < nums.length; i++) {\n            const indexMask = 1 << i;\n            if (usedIndicesBitMask & indexMask) continue;\n            const value = nums[i];\n            if (!valsToIndices.hasOwnProperty(value)) {\n                valsToIndices[value] = i;\n            }\n        }\n        const indicesAvailable = Object.values(valsToIndices);\n\n        // this is hard to explain but it\'s basically calculating the minimum\n\t\t// cost while marking the indicies that are going to be used for each\n\t\t// combination\n        let minIncompatibilityCost = Infinity;\n        const combinations = createCombinations(indicesAvailable, maxInBucket);\n        for (const indices of combinations) {\n            let nextMask = usedIndicesBitMask;\n            let minVal = Infinity;\n            let maxVal = -Infinity;\n            for (const index of indices) {\n                minVal = Math.min(minVal, nums[index]);\n                maxVal = Math.max(maxVal, nums[index]);\n                nextMask = nextMask | (1 << index);\n            }\n            const incompatibilityCost = maxVal - minVal;\n            minIncompatibilityCost = \n                Math.min(minIncompatibilityCost, dfs(nextMask) + incompatibilityCost);\n        }\n        return cache[usedIndicesBitMask] = minIncompatibilityCost;\n    }\n    return dfs(0);\n};\n\nfunction createCombinations(indices, len) {\n    const combinations = [];\n    \n    if (indices.length < len) {\n        return combinations;\n    }\n    \n    const stack = [[[], 0]];\n    while (stack.length > 0) {\n        let [combi, i] = stack.pop();\n        for (; i < indices.length; i++) {\n            const combination = [...combi, indices[i]];\n            if (combination.length === len) {\n                combinations.push(combination);\n            } else {\n                stack.push([combination, i + 1]);\n            }\n        }\n    }\n    \n    return combinations;\n}\n```
['Dynamic Programming', 'Bit Manipulation', 'Go', 'JavaScript']