roflwaffle
roflwaffle

Reputation: 30656

Finding a sequence of numbers in an array

I'm making a Yahtzee game and I need a way to calculate a small straight (a sequence of 4 numbers in order). So valid ones would be: 1,2,3,4 | 2,3,4,5 | 3,4,5,6.

I have an array of 5 numbers and I need to figure out if one of those 3 combinations is in that array.

For those not familiar with Yahtzee, there are 5 dice (the five numbers in the array) that can be from 1-6.

Upvotes: 1

Views: 3011

Answers (4)

MikeNZ
MikeNZ

Reputation:

Here's another idea, Use a generic isStraight() method and use it to test the two array slices.

$tests = array(
            array(1,2,3,4,5),
            array(1,1,2,3,4),
            array(4,3,2,1,4),
            array(3,4,5,6,1)
        );
foreach($tests as $test) {
    print_r($test);
    echo "Straight: "; 
    var_dump(isStraight($test));
    echo "Short Straight: "; 
    var_dump(isShortStraight($test));
    echo "\n";
}

function isShortStraight($hand) {
    return isStraight(array_slice($hand, 0, 4)) || 
           isStraight(array_slice($hand, 1, 4));
}

function isStraight($hand) {
    $unique = array_unique($hand);
    if (count($hand) != count($unique)) {
        /* Has Duplicates, not a straight */
        return false;
    }

    sort($unique);
    if ($unique != $hand) {
        /* Sort order changed, not a straight */
        return false;
    }
    return true;
}

Upvotes: 0

Paolo Bergantino
Paolo Bergantino

Reputation: 488444

function isStraight($hand) {
    $straights = array(range(1, 4), range(2, 5), range(3, 6));
    foreach($straights as $solution) {
        if(array_intersect($solution, $hand) == $solution) {
            return $solution;
        }
    }
    return false;
}

$hand = array(1,5,2,4,3);

var_dump(isStraight($hand));

Not sure about the rules of the game, but that should do it.

The function is going to return the first solution it finds - in this case [1,2,3,4]. It is going to return the boolean false if it doesn't find any straights in the hand. Hope this helps.

Upvotes: 6

cgp
cgp

Reputation: 41381

More precisely:

  function array_match($array, $target_array) {
  $offset = 0;
  $maxoffset = sizeof($target_array) - sizeof($array);
  for($y=0;$y<$maxoffset;$y++) {
    $result = true;
    for($x=0;$x<sizeof($array);$x++) {
      if ($array[$x] != $target_array[$x+$y] ) {
         $result = false;
         continue;
      }
    }
    if ($result)
       return "true";
  }
  return "false";
}
echo array_match(array(1,2,3), array(1,2,3,4,5)); //true
echo array_match(array(1,2,3), array(4,1,2,3,5)); //true
echo array_match(array(1,2,3), array(4,2,2,1,2)); //false

Upvotes: 0

gnarf
gnarf

Reputation: 106352

Perhaps something like this: --- warning --- air coding

function findSequenceLength(array $array)
{
  // Filter duplicates out - and sort the array.
  $sorted = array_unique($array, SORT_NUMERIC);

  $lastValue = null;
  $thisSeq = 0;
  $longestSeq = 0;
  foreach ($sorted as $value)
  {
    if ( ( $lastValue !== null ) && $value == $lastValue + 1)
    {
      // our value is exactly one above the last entry
      // increase the counter
      $thisSeq++;
    } else {
      // sequence ended - save the value
      $longestSeq = max($longestSeq, $thisSeq);
      $thisSeq = 1;
    }
    $lastValue = $value;
  }
  return max($longestSeq, $thisSeq);
}

$sequence = array(1,2,4,5,4,6);
echo findSequenceLength($sequence);  // should return 3 [4,5,6]

You could then test that the "sequence length" is >= 4 to test for your "small straight"

Upvotes: 1

Related Questions