2014-02-07 6 views
1

내 조건에 맞는 임의의 시퀀스로 배열을 만들고 싶습니다.PHP 무작위 순서 생성기

  1. 시퀀스는 1-8의 8 가지 숫자로 구성되어야합니다.
  2. 처음 4 개 또는 마지막 4 개 숫자에는 2 개 이상의 연속 된 숫자가 없어야합니다. 예 : 1,2,3은 정렬이 잘못되어 (3,4,5) 연속되기 때문에 5,3,4도 좋지 않습니다.

이것은 좋은 예입니다 : 1,4,5,7, | 8,6,3,2

이것은 좋은 예는 아닙니다 : 1,3,2,6, | 그것은 생성을 위해 일하고

  $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); 

:이 만든

처음 4 자리 숫자 (1,2,3)을 분류하면 5,7,8,4 때문에 1,3,2 연속 숫자 그것의 일부이지만 연속적인 숫자를 포함하지 않는 연속열을 삽입하는 방법을 생각할 수는 없습니다. 이견있는 사람?

+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 연속 1의 어떤 시퀀스 나 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

어쩌면 그것은 내 질문에 처음에는 분명하지 않았지만 시퀀스는 처음 4 자리에서 연속적이거나 3 자리 숫자로 구성된 3 자리 숫자 집합을 포함 할 수 없습니다. 숫자가 서로 맞을 경우에도 적용해야합니다. 이것은 좋은 예입니다. 1,4,5,7,8,6,3,2 이것은 좋은 예가 아닙니다 : 1,3,2,6,5,7,8,4 1,2 , 3은 처음 네 자리 숫자에서 연속적입니다. – Wistar

+0

좋은 예'1,4,5,7,8,6,3,2'에서는 4,5가 연속되지만, 좋은 예라고 말했습니다. 연속적인 의미는 무엇입니까? –

+0

나는 첫 번째 4 자리 또는 마지막 4 자리에서 정렬되는 경우 연속되는 3 개의 숫자를 의미했습니다. 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);