All possible combinations in array - recursion?

前端 未结 2 829
礼貌的吻别
礼貌的吻别 2020-12-11 10:44

I have a question that goes over my head, hope someone can help. I think it may have to be solved by recursion and/or permutations, but I am not good enough of a (PHP) progr

相关标签:
2条回答
  • 2020-12-11 11:15

    A recursive solution.

    <?php
    function combination($remaining, $current, $combinations) {
        $e = array_shift($remaining);
        $combinations[$current][] = $e;
    
        if(empty($remaining)) {
            print_r($combinations);
            return;
        }
    
        combination($remaining, $current, $combinations);
        // 6 Limit remove for all solutions
        if ($current < 6) {
            combination($remaining, $current + 1, $combinations);
        }
    }
    
    
    $remaining = range(0, 23);
    
    combination($remaining, 0, array());
    

    If you want to store all solutions for [0,23] you're gonna have a bad time.

    0 讨论(0)
  • 2020-12-11 11:16

    Since you want ranges of numbers, I simplified the question to a matter of permutations.

    Here is a shellscript (that executes from the terminal as a node.js script) that calculates the ranges you want:

    #!/usr/bin/env nodejs
    
    // Config
    var blocksTotal     = 3;    // 6
    var numbersTotal    = 6;    // 24
    var perms           = [];   // Permutations
    
    // Start the loop
    (function divideHours(numbersToGo, blocksToGo, arr) {
    
        // What block is this? [1 .. 3]
        var block = blocksTotal - --blocksToGo;
    
        // Divide numbers
        if (block < blocksTotal)
            for (var hour = 0; hour <= numbersToGo; hour++) {
                if (block == 1) var arr = [];
                arr[block-1] = hour;
                divideHours(numbersToGo-hour, blocksToGo, arr);
            }
        // Last block? Assign rest of numbers
        else {
            perms.push(arr.concat([numbersToGo]));
            console.log(arr.concat([numbersToGo]).toString());
        }
    })(numbersTotal, blocksTotal);
    

    Testing with a smaller set of ranges and numbers, you get the following permutations:

    0,0,6
    0,1,5
    0,2,4
    0,3,3
    0,4,2
    0,5,1
    0,6,0
    1,0,5
    1,1,4
    1,2,3
    1,3,2
    1,4,1
    1,5,0
    2,0,4
    2,1,3
    2,2,2
    2,3,1
    2,4,0
    3,0,3
    3,1,2
    3,2,1
    3,3,0
    4,0,2
    4,1,1
    4,2,0
    5,0,1
    5,1,0
    6,0,0

    Looks about right? Now try the bigger numbers, the resulting array is stored in perms.

    If you explicitly want every number mentioned in the array, you can use some counters and math to get that kind of array in stead. E.g.:
    3,1,2 -> [1,2,3],[4],[5,6]
    2,0,4 -> [1,2],[],[3,4,5,6]

    Here is a snippet using 6 blocks and 24 numbers:

    ...
    7,2,2,10,0,3
    7,2,2,10,1,2
    7,2,2,10,2,1
    7,2,2,10,3,0
    7,2,2,11,0,2
    7,2,2,11,1,1
    7,2,2,11,2,0
    7,2,2,12,0,1
    7,2,2,12,1,0
    7,2,2,13,0,0
    7,2,3,0,0,12
    7,2,3,0,1,11
    7,2,3,0,2,10
    ...

    ..but this list is endless.

    0 讨论(0)
提交回复
热议问题