무작위 변위 생성


30

도전 설명

시퀀스의 "정렬"은 요소가 원래 위치에 나타나지 않는 순열입니다. 예를 들어 ECABD의 derangement ABCDE이지만 CBEDA그렇지 않습니다.

ABCDE
 | |   <- B and D are in their orignal positions
CBEDA

시퀀스가 주어지면 무작위 배열을 생성하십시오.

노트

  • 문자열을 입력 또는 요소의 배열 / 목록 (정수, 문자, 객체 등)으로 사용할 수 있습니다.

  • 새 객체를 반환하는 대신 요소를 교체하여 기존 객체를 수정할 수 있습니다

  • 각 배열은 생성 될 확률이 동일해야합니다.

  • 시퀀스에 둘 이상의 요소가 있고 두 번 이상 나타나지 않는 것으로 가정 할 수 있습니다.



3
@VoteToClose : haha, 완전히 파열
shooqie

나는 이것에 대해 많이 알지 못하지만 이것은 고정 소수점 정리와 관련이 있습니다. 내가 틀렸지 만 누군가 나를
고쳐

요소가 고유하거나 중복 요소를 포함 할 수 있다는 보장이 있습니까?
Carcigenicate

1
@Carcigenicate : 설명에 바로 있습니다. 당신은 중복이 없다고 가정 할 수 있습니다
shooqie

답변:


12

CJam , 14 바이트

q:X{mr_X.=:|}g

온라인으로 사용해보십시오!

입력이 잘못 될 때까지 입력을 계속 섞습니다.

설명

q:X   e# Read input and store it in X.
{     e# While the condition at the end of the loop is truthy...
  mr  e#   Shuffle the string.
  _X  e#   Duplicate it and push the input.
  .=  e#   Element-wise equality check.
  :|  e#   Reduce OR over the list, gives something truthy if any character
      e#   remained in its original position.
}g

1
OP가 솔루션이 항상 완료되도록 보장해야한다고 지정했으면합니다.
John Dvorak

4
@JanDvorak 글쎄, 이것이 끝나지 않을 확률은 0입니다. 그러나 결정적인 러닝 타임을 요구하면 도전이 더 흥미로워 졌을 것입니다.
Martin Ender

확률은 실제로 0입니까? 셔플 작업이 완벽하지는 않습니다. 실제로 어떻게 작동합니까? 나는 이것이 아마도 OP가 요구 한 것에 대한 근사치라고 생각하지만 각 배열의 확률이 같은지 의심 스럽다.
아무도

3
@ 아무도 알고리즘을 사용하여 PRNG에서 완벽하게 균일 한 결과를 얻을 수 있을지 의심 됩니다. 그러나 셔플 자체가 균일하다고 가정하면 ( "모든 순열은 거의 동일한 가능성으로 발생합니다."를 Java 문서에서 보증합니다.) 각 기각이 하나의 순열이기 때문에 거부 기반 솔루션은 균일 한 변위를 생성합니다. 순열의 확률은 같습니다.
Martin Ender

1
@ 아무도 수학 대단하다. 성공 또는 실패 조건을 통계에서 Bernoulli 시행이라고합니다. 이는 첫 번째 성공을 위해 k 개의 시행이 필요할 확률이 (1-p) ^ (k-1) * p이며, 여기서 p는 성공적인 배열 해제 확률입니다. k가 커짐에 따라 k 개의 시행이 필요할 확률이 거의 없다는 것을 쉽게 알 수 있습니다. 그러므로 우리는 알고리즘이 확률 1 ( "거의 확실하게")로 정지한다고 말하지만 결코 멈추지 않는 것은 불가능하지 않습니다.
mavenant

9

젤리 , 6 바이트

Ẋ=³S$¿

온라인으로 사용해보십시오!

설명

Ẋ    ¿    Shuffle the given list while this is nonzero for it:
    $       A two-step process:
 =³           Element-wise equality of it and L (the original list)...
   S          Sum the ones in this binary array.

Jonathan Allan은 바이트를 저장했습니다.


5
그래서 당신은 미리 Winter Bash 모자를 가지고 있습니까? :-)
Luis Mendo

2
멋진 새 그림을 그릴 시간 Ẋ=³S$¿은 바이트를 절약합니다.
Jonathan Allan

2
허, 나는 그것에 대해 전혀 몰랐다 $. 감사!
Lynn

6 자이지만 6 바이트 이상입니다. Ẋ = ³S $ ¿ 바이트 길이는 312112입니다. 따라서 총 10 바이트입니다.
mxfh

6

파이썬, 85 바이트

전달 된 목록을 수정합니다 (메타 및 질문에서 허용됨).

from random import*
def D(l):
 o=l[:]
 while any(x==y for x,y in zip(o,l)):shuffle(l)

온라인으로 해보십시오!


1
파이썬 2를 지정하면, 나는 당신이 대체 할 수있는 생각 def D(l):l=input()다음 (당신이 프로그램을 대신하는 기능을 가지고 있으므로) 다음 줄에 들여 쓰기 공간을 저장합니다. 그래도 공감하지 않았다!
mathmandan

@mathmandan 좋은 생각이지만 전체 프로그램 인 경우 더 많은 바이트가 필요한 경우 다시 인쇄해야합니다.
FlipTack

1
당신이 그렇게 말하면, 좋아. 나는 스펙이 당신이 결과를 출력하거나 반환 할 필요가 없다고 말한 것 같습니다. 그러나 "기존"을 "코드를 실행하기 전에 존재"로 읽는 것이 합리적입니다.이 경우 귀하에게 동의합니다. (아마도 이것에 대해 잘 알려진 합의가 있습니다.) :)
mathmandan

5

ES6 (자바 스크립트) 71, 69 바이트

입력 및 출력은 배열이며 "=="와 비교할 수있는 한 모든 요소 유형 (문자열, 숫자 등)에서 작동해야합니다.

골프

F=s=>(r=[...s]).sort(_=>Math.random()-.5).some((e,i)=>s[i]==e)?F(s):r

테스트

F=s=>(r=[...s]).sort(_=>Math.random()-.5).some((e,i)=>s[i]==e)?F(s):r

F(['A','B','C','D'])
Array [ "D", "C", "A", "B" ]

F(['A','B','C','D'])
Array [ "D", "A", "B", "C" ]

F(['A','B','C','D'])
Array [ "C", "D", "B", "A" ]

F(['A','B','C','D'])
Array [ "D", "C", "B", "A" ]

F(['A','B','C','D'])
Array [ "C", "D", "B", "A" ]

대화식 스 니펫

F=s=>(r=[...s]).sort(_=>Math.random()-.5).some((e,i)=>s[i]==e)?F(s):r

function G() {
    console.log(F(T.value.split``).join``); 
}
<input id=T value="ABCDEF"><button id=G onclick="G()">GENERATE</button>


5

펄 6 , 33 바이트

{first (*Zne$_).all,.pick(*)xx *}

정수 또는 문자 목록을 입력으로 받아서 새 목록을 반환하는 람다.

임의의 값 목록을 지원해야하는 경우 (+2 바이트) ne로 바꿔야 !eqv합니다.

( 온라인으로 시도하십시오. )

설명:

  • { }: 람다를 정의합니다.
  • .pick(*): 입력 목록의 임의 셔플을 생성합니다.
  • .pick(*) xx *: 이러한 셔플의 느린 무한 시퀀스를 만듭니다.
  • (* Zne $_).all: (음수 문자열 동등성) 연산자로 두 개의 목록 (인수 *및 외부 람다의 인수 $_) ne을 압축하여 부울 목록을 생성 한 다음 단일 부울 상태 로 접는 all접점 을 작성하는 람다 .
  • first PREDICATE, SEQUENCE: "정렬"테스트를 수행하는 무한 순열 순서에서 첫 번째 요소를 가져옵니다.


3

펄 6 , 45 바이트

{(@^a,{[.pick(*)]}...{none @a Zeqv@$_})[*-1]}
{(@^a,{[.pick(*)]}...{!sum @a Zeqv@$_})[*-1]}

시도 해봐

입력은 무엇이든 배열입니다.

넓히는:

{
  (

    @^a,          # declare parameter, and seed sequence generator

    {             # lambda with implicit parameter 「$_」
      [           # store into an array
        .pick(*)  # shuffle 「$_」
      ]
    }

    ...           # keep generating the sequence until

    {
      none        # none
      @a          # of the outer blocks input
      Z[eqv]      # is zip equivalent
      @$_         # with the current value being tested
    }

  )[ * - 1 ]      # return the last value
}

3

MATL, 7 바이트

이것은 내 옥타브 게시물의 번역입니다 (여기의 다른 제출물과 유사합니다). 어제 첫 번째 MATL 게시물 (CNR 균열)을 게시 했으므로 이것이 최적이지는 않지만 지금까지 얻은 것 중 최고입니다.

솔직히 말해서, 나는 t거기에 완전히 필요하다고 확신 하지는 않지만 이것이 작동하도록 할 수있는 유일한 방법입니다. 사용자 입력을 비교할 수 있도록 사용됩니다 (G )과 임의 순열을 . 나는 그것없이 둘을 비교할 수 있다고 생각하지만 ...?

어쨌든, 여기에 간다 :

`Z@tG=a

`          % Loop
 Z@        % Random permutation of input
   t       % Duplicating the stack
    G      % Paste from clipboard G (user input)
     =     % Comparing the random permutation with the input (retrieved from clipboard)
      a    % any(input == random permutation)
           % Implicit end and display

온라인으로 사용해보십시오!


개선 사항이 있습니까? 나는 정말로 t거기에 필요 합니까 아니면 그것을 제거 할 수 있습니까? 재미는 ... :) MATL 골프에 노력했다
스튜이 그리핀에게

:-) 나는 그것을 제거하는 방법을 보지 못합니다 t(또는 동등하게 다른 것 G) 당신은 다음 반복을 위해 또는 최종 결과로 스택에 무언가를 남겨 둘 필요가 있습니다
Luis Mendo

3

실제로 13 바이트

;;WX╚│♀=ΣWX)X

온라인으로 사용해보십시오!

설명:

;;WX╚│♀=ΣWX)X
;;             make two copies of input
  WX╚│♀=ΣW     while top of stack is truthy:
   X             discard top of stack
    ╚            shuffle array
     │           duplicate entire stack
      ♀=         compare corresponding elements in shuffled and original for equality
        Σ        sum (truthy if any elements are in the same position, else falsey)
          X)X  discard everything but the derangement

2

옥타브, 56 55 바이트

x=input('');while any(x==(y=x(randperm(nnz(x)))));end,y

input('')이것은 함수가 아니므 로 사용해야 합니다. 또한 입력을 문자열로 선택할 수 있으므로 트릭을 사용할 수 있습니다 nnz(x)==numel(x).

설명:

x=input('')            % Self-explanatory
while any(x==y)        % Loop until x==y has only 0s (i.e. no elements are equal)
y=x(randperm(nnz(x)))  % Continue to shuffle the indices and assign x(indices) to y
end                    % End loop
y                      % Display y

입력이 문자열 일 수 있다는 사실을 알아 낸 Luis에게 감사 하므로 2 바이트 nnznumel저장 하는 대신 사용할 수 있습니다 .


자기 자신에 대한 참고 사항 : 다음에 전체 질문을 읽으십시오 :) 감사합니다!
Stewie Griffin

1
그것은 항상 나에게 일어난다 :-)
Luis Mendo

2

MATL, 13 바이트

이것은 @LuisMendo와 저의 공동 노력입니다. 여기에있는 다른 많은 답변과 달리이 답변은 정렬이 해제 될 때까지 임의의 순열을 샘플링하지 않지만 모든 정렬을 생성하고 임의로 하나를 선택한다는 점에서 결정적입니다.

Y@tG-!Af1ZrY)

온라인으로 사용해보십시오!

설명

Y@tG-!Af1ZrY)
Y@             generate all permutatoins
  t            create a duplicate
   G-!A        find the (logical) indices of all valid derangements (where no character of the string is in the same position as the original string)
       f       convert logical to linear indices
        1Zr    choose one of those indices randomly
           Y)  get the derangement (from the ones we generated earlier) at this index

2

피스 -10 9 바이트

입력을 뒤섞는 동안 문자는 입력에서 색인의 문자와 같습니다.

.WsqVHQ.S

여기에서 온라인으로 사용해보십시오 .

.W           Iterate while
 s           Sum, this is works as any() on a boolean list
  qV         Vectorized equality
   H         The lambda variable for the check step
   Q         The input
 .S          Shuffle
  (Z)        Lambda variable, implicit
 (Q)         Start .W with input, implicit

설명을 추가해 주시겠습니까? 나는 pyth 답변을 쓰고 싶었다. 나는 그것에 대해 많이 모른다.
Gurupad Mamadapur

@GurupadMamadapur는 물론 행복합니다.
Maltysen

1
@GurupadMamadapur 님이 추가했습니다 우리는이 튜토리얼을 . 꽤 오래되었지만 기본 사항을 알려줍니다. pyth와 관련하여 도움이 필요하면 채팅에서 저를 ping하십시오.
Maltysen

2

매스 매 티카, 57 바이트

#/.x_:>RandomChoice@Select[Permutations@x,FreeQ[#-x,0]&]&

이름이없는 함수는 입력 항목으로 목록을 가져 와서 출력합니다. #input의 모든 순열 을 생성 한 후에 는 요소 별 차이 x집합 #-x0;을 포함하지 않는 것만 유지합니다 . 그런 다음 해당 세트에서 (균일하게) 무작위로 선택합니다.


1
좋은! #/.x_:>NestWhile[RandomSample[#,Length@#]&,#,Not@FreeQ[#-x,0]&]&긴 줄을 위해 실제로는 약간 더 길다
마틴

잠깐만 요, 당신은 Mathematica에 내장을위한 내장이 없다고 말하고 있습니까? : o
shooqie

나는 내 자신을 반쯤 기대했다 :)
Greg Martin

0

PHP, 85 바이트

for($a=$b=str_split($argv[1]);array_diff_assoc($a,$b)!=$a;)shuffle($b);echo join($b);

문자열 인수를 두 배열에 복사하고, 요소의 인덱스를 비교하는 차이가 다른 배열과 같아 질 때까지 그 중 하나를 섞습니다. 로 실행하십시오 -r.


0

R, 59 바이트

z=x=1:length(y<-scan(,""));while(any(x==z))z=sample(x);y[z]

STDIN으로 요소 목록을 읽고 목록의 길이를 가져와 순서 목록과 장소를 공유하지 않는 요소를 찾을 때까지 1에서 길이까지 샘플링 범위를 시작합니다. 그런 다음 해당 목록을 인쇄합니다.


0

Wonder , 32 바이트

f\@[/>#I zip#=[#0a\shuf#0]?f a?a

용법:

f\@[/>#I zip#=[#0a\shuf#0]?f a?a];f[1 2 3 4 5]

설명

더 읽기 쉬운 :

f\@[
  some #I zip #= [#0; a\ shuf #0]
    ? f a
    ? a
]

재귀 함수 f. f의 입력 목록과 섞인 버전의 입력 목록을 요소 단위로 비교 합니다. 비교가 동일한 값을 생성 f하면 셔플 된 목록에서 호출됩니다. 그렇지 않으면 셔플 된 목록을 반환합니다.


0

루비, 67 바이트

def f a
while (a.zip(o=a.shuffle).map{|x,y|x-y}.index 0);end
o
end

0

옥타브, 54 53 바이트

@(a)((p=perms(a))(L=!any(p==a,2),:))(randi(sum(L)),:)

의 모든 순열을 생성하고 a와 공통 요소가없는 행을 임의로 선택하십시오 a.

참고 : 실수로 @flawr MATL 답변과 동일합니다!


0

클로저, 94 90 79 바이트

#(let[s(shuffle %)](if(not(some(fn[[x y]](= x y))(map vector % s)))s(recur %)))

축소 내부의 조건부를로 변경 and하고 인라인 하여 -4 바이트done? .

축소를로 변환하여 -11 바이트 some.

우와! PHP를 이길.

무차별 강제 방법. 유효하지 않은 목록을 섞습니다. 이것은 중복 시도를 방지하기 위해 아무것도하지 않는 무차별 강제 방법이라는 점을 고려할 때 어리석게 빨리 끝납니다. 1 초 안에 1000 개의 요소로 구성된 1000 개의 분리 된 목록을 발견했습니다.

언 골프 드 :

(defn dearang [ls]
  (let [s (shuffle ls)
        bad? (some (fn [[x y]] (= x y))
                (map vector ls s))]
    (if (not bad?) s (recur ls))))

0

클로저, 56 바이트

#(let[s(shuffle %)](if((set(map = % s))true)(recur %)s))

문자열은 섞을 수 없으며, seq또는vec .

원래 시도 #(first(remove(fn[s]((set(map = % s))true))(iterate shuffle %)))했지만 recur접근 방식이 실제로보다 짧습니다.iterate .

마술은 (set(map = % s))거짓 집합, 참 집합 또는 참과 거짓 집합 을 반환 한다는 것 입니다. 함수로 사용할 수 있습니다. 함수에 포함되어 있으면 true답은입니다 true. 그렇지 않으면 거짓 nil입니다. =두 개의 입력 인수를 취하면 기쁘지 않습니다.

((set [false]) true)
nil

어쩌면 어떤 값이 참인지 확인하는 더 짧은 방법이 있습니까?


0

APL, 11 바이트

올바른 인수의 문자열로 :

⍵[⍋(⍴⍵)?⍴⍵]

설명

ρ⍵ 올바른 인수의 길이 (또는 모양)를 가져옵니다.

? 의 무작위 배열을 반환 (⍴⍵)이 숫자 합니다.

중복되지 않도록 순서를 반환합니다.

⍵[..] 이 인덱스를 사용하여 문자열의 무작위 구색을 나타냅니다.


PPCG에 오신 것을 환영합니다! 모든 항목이 유효한 함수 또는 전체 프로그램이어야하므로 답은 함수 인수 또는 입력 방법을 통해 입력해야합니다.
ETHproductions

지금은 요구 사항에 맞아야한다고 생각합니다. 올바른 주장을 취하거나 .
Jacob Utley
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.