生成随机的"模式锁定"数字序列

Anu*_*g3r 6 php random math

今天我的朋友提出了一个我仍然无法解决的挑战:"在PHP中生成随机数字序列"

数字排列为拨号盘/模式锁,包括3行3列的1-9个键:

 ---------------------------
|                           |
|     1       2      3      |
|                           |
|     4       5      6      |
|                           |
|     7       8      9      |
|                           |
 ---------------------------
Run Code Online (Sandbox Code Playgroud)

现在,给定一个长度,我们必须使用以下标准生成所提供长度的随机,非重复数字序列:

  1. 生成的序列应遵循仅通过相邻数字(可能是对角线)的特定方向/模式,例如(长度:8),12569874:

     1  2
          
     4    5  6
             
     7  8  9 
    
    Run Code Online (Sandbox Code Playgroud)
  2. 第一行的数字永远不应该跟第三行的数字相反,反之亦然.列也一样.例如,1后面不能跟8,而6后面不能跟4.

  3. 可以从android模式锁系统中轻松猜出更多标准

以下是长度为9的一些示例生成序列:12369874/5,142536987等,长度= 6:987532等

我尝试这样做rand():

  $chars = "123456789";
  $length = 9;
  $clen   = strlen( $chars )-1;
  $id  = '';

  for ($i = 0; $i < $length; $i++) {
      $id .= $chars[mt_rand(0,$clen)];
  }
  return ($id);
Run Code Online (Sandbox Code Playgroud)

但是,仍然没有运气......

我该如何解决这个问题?

Wra*_*orn 3

有一些限制,但这需要您自己解决。我只有在得到报酬时才会处理头痛:)。

<pre>
<?php

// Keypad
$grid = [
    ['1', '2', '3'],
    ['4', '5', '6'],
    ['7', '8', '9'],
];

// Sequence Target Length
$target_length = 5;

// Place to store the Keypad sequence
$points = [];

// Starting Point
$x = rand(0, 2);
$y = rand(0, 2);

// Run through the process until we have the sequence at the desired length
while (count($points) < $target_length):

    // Check if the grid keypad entry has been used
    if ($grid[$x][$y]):
        // Hasn't been used, so stire it
        $points[] = $grid[$x][$y]; 
        // Mark it used 
        $grid[$x][$y] = NULL;
    endif;

    // Sanity Check, imagine if you will,.... target length of 9, and you hit 6 5 2 1,  You'll vault off into the twilight zone without this
    if ((!$grid[$x + 1][$y]) && (!$grid[$x][$y + 1]) && (!$grid[$x - 1][$y]) && (!$grid[$x][$y - 1])):
        // We have no where to go
        break;
    endif;

    // Start looking for possible values 
    do {
        $test_x = $x;
        $test_y = $y;
        $dir = rand(0, 3);

        switch ($dir):
            case (0):
                $test_y--; // Up
                break;
            case (1):
                $test_x++; // Right
                break;
            case (2):
                $test_y++; // Down
                break;
            case (3):
                $test_x--; // Left
                break;
        endswitch;
        // Optional Gibberish 
        echo "Moving from {$x}, {$y} to {$test_x}, {$test_y} --> " . (($grid[$test_x][$test_y] === NULL) ? 'FAILED' : 'OK!') . '<br>';

        // Keep going until we find a valid direction
    } while ($grid[$test_x][$test_y] === NULL);

    // assign the new coords
    $x = $test_x;
    $y = $test_y;

    // repeat
endwhile;

// report
echo implode('-', $points) . "\n";

?>
</pre>
Run Code Online (Sandbox Code Playgroud)