Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

finding all series within an array

How do I find number of all the series (combinations of an array that have at least 3 consecutive values, like [7,8,9]) and have the longest number of values?

from [3,4,1,2,2] it would be 2 - ([1,2,3,4] twice, but ignore [1,2,3]*2 and [2,3,4]*2)

from [9,6,7,5,8] it would be 1 - ([5,6,7,8,9])

from [1,2,3,1,2] it would be 4 ([1,2,3] * 3)

Thanks


edit

the point of this is to count runs in a crib hand. It doesn't matter what order the array has the series in, as long as the series counted don't overlap all cards.


edit 1

var $cards:Array = [9, 4, 3, 2, 2];
var $ranks:Array = [];
var $c:int;
for each ($c in $cards) {
    if ($ranks[$c] == null) {
        $ranks[$c] = 1;
    }else {
        $ranks[$c] ++;
    }
}

this will create an array ($ranks) that will have these values [2:2, 3:1, 4:1, 9:1]

from this I will be able to multiply the values under 2,3 ad4 4 and multiply them by 3, so I would get 2*1*1 * 3

I'm trying to figure out now how to find the consecutive values, and ignore ones that aren't (like the 9)

like image 288
Daniel Avatar asked Jan 02 '11 07:01

Daniel


2 Answers

You want to order your values and replace all duplicates with an array of themselves. ie.

//Order values and group matches
[3,4,1,2,2] = [1,[2,2],3,4]
[9,6,7,5,8] = [5,6,7,8,9]
[1,2,3,1,2] = [[1,1],[2,2],3]

Then you will want to find the largest consecutive sequence and remove violations.

//remove violations (6,7,8)... which I guess you also want to count separately.
[1,[2,2],3,4,6,7,8] = [1,[2,2],3,4]

Then it will be a matter of multiplying the length of all of your arrays to find your score.

Once you have cleaned your array, you can think of the formula like this.

array2 = [2,2];
array1 = [1, array2, 3, 4];
score = array1.length * array2.length = 8;

array3 = [3,3,3];
array2 = [2,2];
array1 = [1, array2, array3, 4];
score = array1.length * array2.length * array3.length = 24;

It should be pretty fun figuring out how to write this in code.

like image 78
Nicholas Avatar answered Nov 15 '22 06:11

Nicholas


this works: it's using casalib for min/max, but there are other ways around it. this onlu finds the largest set of consecutive numbers though, as it is meant to count a crib hand which has a max of 5 cards, thus no two simultaneous series are possible (like 2,3,4 and 9,10,11)

private function countRuns($cards:Array):int {
    var $ranks:Array = [];
    var $c:int;

    for each ($c in $cards) {
        if ($ranks[$c] == null) {
            $ranks[$c] = 1;
        }else {
            $ranks[$c] ++;
        }
    }

    var $highest:int = ArrayUtil.getHighestValue($cards);
    var $lowest:int = ArrayUtil.getLowestValue($cards);
    var $seq:Array = [];
    var $longest:Array = [];
    for (var i:int = $lowest; i <= $highest; i++) {
        if ($ranks[i] != null) {
            $seq.push($ranks[i]);
            if ($seq.length > $longest.length && $seq.length > 2) {
                $longest = $seq.concat();
            }
        }else {
            $seq = [];
        }
    }

    var $total:int = $longest.length;
    for each ($c in $longest) {
        $total *= $c;
    }
    trace($total, $cards);
    return $total;
}

I found the consecutive numbers through the $seq array, by pushing values whenever the $ranks[i] has a value, if the length is greater than 3 and grater than the $longest array, copy the array over (with concat()!), if there is no value, $seq gets reset.

it's so simple once you know...


edit I noticed I had a typo in the code

if ($seq.length > $longest.length || $seq.length >= 2)

should have been

if ($seq.length > $longest.length && $seq.length > 2)

like image 34
Daniel Avatar answered Nov 15 '22 05:11

Daniel