2014-02-07 78 views
1

我希望創建一個隨機序列對應我的條件的數組。Php隨機序列發生器

  1. 該序列應由1-8個不同的數字組成。
  2. 我不應該在前4個或後4個數字中有超過2個連續的數字。例如:1,2,3不好,也不和5,3,4,因爲如果排序它們是連續的(3,4,5)。

這是一個很好的例子:1,4,5,7,| | 8,6,3,2

這不是一個好例子:1,3,2,6,| 5,7,8,4因爲1,3,2是連續的號碼,如果在第4位

我做了這個排序(1,2,3):

  $sequences = array(); 
    while(count($sequences) < 100){ 

     //Random 8 numbers sequence from 1-8 
     $sequence = array(); 
    while(count($sequence) < 8){ 
      $rand = rand(1,8); 
     if(!in_array($rand, $sequence)){ 
      array_push($sequence, $rand); 
     } 
     } 

     //Insert if numbers are not successive. 
     //Struggling here 
     if(?????){ 
      array_push($sequences, $sequence); 
     } 
    } 
      print_r($sequences); 

它的工作的代其中的一部分,但我不知道如何插入不包含連續數字的序列。有什麼想法嗎?

+0

所以......你只是想爭搶1-8的名單? – JohnP

+0

@JohnP a進行了編輯。前4位或後4位數字不應以任何順序連續出現。所以它不僅被擾亂,因爲這個1,3,2,6,5,7,8,4將不起作用,因爲1,2,3在前4個數字中是連續的。 – Wistar

+0

在你的1,3,2,6,5,7,8,4「不好的例子」中 - 我沒有看到1,3,2是如何連續的。你連續的意思是什麼? –

回答

2

可以表示兩個組數字爲1或0,並挑選哪些元素中的每個設置去通過拾取具有四個1和0的8位二進制串中的一個,並沒有連續3個1S序列或0。由下列整數之一每個二進制字符串representes的:

43 45 51 53 54 75 77 83 85 86 89 90 101 102 105 106 108 
147 149 150 153 154 165 166 169 170 172 178 180 201 202 204 210 212 

下半年都是對稱的上半年,因此我們可以隨便挑,從上半年的一個數字,然後做一些處理挑整套:

$combinations = array(43,45,51,53,54,75,77,83,85,86,89,90,101,102,105,106,108); 

// Pick a random combination 
$combination = $combinations[array_rand($combinations)]; 
if (mt_rand() & 1) 
    $combination = 255 - $combination; 
$combination = str_split(str_pad(decbin($combination), 8, '0', STR_PAD_LEFT)); 

// Get the first four values 
$first = array_keys(array_filter($combination, function($x){ return $x == '0'; })); 
shuffle($first); // Permute them 

// Get the last four values 
$last = array_keys(array_filter($combination, function($x){ return $x == '1'; })); 
shuffle($last); // Permute them 

$result = array_map(function($x){ return $x + 1; }, array_merge($first, $last)); 

這將隨機序列與您的約束一致隨機,應該是相當有效的。一些示例輸出:

[6, 2, 3, 8, 1, 4, 5, 7] 
[1, 6, 2, 4, 3, 5, 8, 7] 
[6, 3, 1, 8, 2, 4, 5, 7] 
[5, 8, 4, 2, 7, 1, 6, 3] 
[5, 2, 8, 1, 3, 6, 7, 4] 
[8, 6, 2, 4, 7, 1, 3, 5] 
[7, 1, 5, 4, 8, 3, 2, 6] 
[5, 1, 3, 6, 2, 7, 8, 4] 
[1, 7, 2, 5, 3, 8, 4, 6] 
[5, 6, 3, 8, 2, 7, 4, 1] 
+0

這太棒了。學到了新東西! – Dave

+0

哇!這是比我想象的更加花哨的編碼。很好的答案,我印象深刻。謝謝。 – Wistar

+0

不客氣@Wistar。我回家時可能會添加更多解釋。你會發現有代碼可以生成所有具有這個約束的19584序列嗎? – Paulpro

0

這可能是一種無效的方式(資源方面),可能更多地被視爲黑客,但;

$sequence = array(1,2,4,5,8,9,5,7); 
    usort($sequence, function($a, $b) { 
     //if $a + 1 = $b, then $b + 1; 
     return ($a + 1) == $b ? $b = $b + 1 : 1; 
    }); 

print_r($sequence); 

這會返回;

Array ([0] => 5 [1] => 8 [2] => 2 [3] => 1 [4] => 4 [5] => 9 [6] => 5 [7] => 7) 
+0

也許在我的問題中一開始並不清楚,但是序列不能包含前四位或後位數字中連續的三組數字。這應該適用於即使數量正確的對方。 這是一個很好的例子:1,4,5,7,8,6,3,2 這不是一個好例子:1,3,2,6,5,7,8,4因爲1,2 ,3個連續的前4位 – Wistar

+0

在你的好例子中,1,4,5,7,8,6,3,2,4,5是連續的,但你說這是一個很好的例子。接連對你意味着什麼? –

+0

我的意思是三個數字,如果在前4位或後4位數字中排序,將會是連續的。 如果我排序1,4,5,7,8,6,3,2的前4位和後4位。我會有1,4,5,7和2,3,6,8。我在前4位和後4位都沒有連續3位數字 – Wistar

0

這不是一個真正漂亮的代碼,我可以縮短它,但仍然,它的工作。

$sequence = array(); 
    $sequences = array(); 
    $loops = 0; 

    while($loops < 10000){ 
     $loops++; 
     //Get a sequence 
     while(count($sequence) < 8){ 
      $rand = rand(1,8); 
      if(!in_array($rand, $sequence)){ 
       array_push($sequence, $rand); 
      } 
     } 

     //Checks if sequence meet requirements 
     //This part could be summarized in a function 
     $first = array($sequence[0], $sequence[1], $sequence[2],$sequence[3]); 
     $last = array($sequence[4], $sequence[5], $sequence[6],$sequence[7]); 

     sort($first); 
     sort($last); 

     if($first[1] != $first[0]+1 || $first[1] !=$first[2]-1){ 
      if($first[2] != $first[1]+1 || $first[2] !=$first[3]-1){ 
       if($last[1] != $last[0]+1 || $last[1] !=$last[2]-1){ 
        if($last[2] != $last[1]+1 || $last[2] !=$last[3]-1){ 

         $sequence = array_merge($first, $last); 
         if(!in_array($sequence, $sequences)){ 
          array_push($sequences, $sequence); 
         } 
        } 
       } 
      } 
     } 

     $sequence = array();   
    } 
    print_r($sequences);