ランダムな混乱を生成する


30

チャレンジの説明

シーケンスの「混乱」とは、元の位置に要素が現れない順列です。たとえば、ECABDはの混乱ですがABCDE、そうでCBEDAはありません:

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

シーケンスを指定して、ランダムな混乱を生成します。

ノート

  • 入力として文字列、または要素(整数、文字、オブジェクトなど)の配列/リストを使用できます。

  • 新しいオブジェクトを返す代わりに、要素を交換することで既存のオブジェクトを変更できます

  • 各混乱は、生成される確率が等しくなければなりません

  • シーケンスに複数の要素があり、複数回出現する要素はないと想定できます。



3
ハハ、完全に逮捕:@VoteToClose
shooqie

私はこのすべてについてあまり知りませんが、これは不動点定理に何らかの形で関連していますか...それに従って、物事は常に自分の位置またはそのようなものになります...?私は間違っていると賭けますが、誰かが私を修正してください:)
ファーハンアナム

要素が一意であるという保証はありますか、または重複を含めることができますか?
発がん物質16

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が指定したことを願っています。
ジョンドヴォルザーク

4
@JanDvorakまあ、これが終了しない確率は0です。しかし、決定的な実行時間を要求することは、挑戦をより面白くするだろうということは正しいです。
マーティンエンダー

確率は実際には0ですか?シャッフル操作は完璧ではありませんが、実際にはどのように機能しますか?これはおそらくOPが求めたものの良い近似だと思いますが、各混乱の確率は同じだとは思いません(おそらくシャッフル操作で使用される可能性のあるPRNGのシード値に依存します)。
誰も

3
@Nobody アルゴリズムを使用してPRNGから完全に均一な結果を得ることができるとは思わない。ただし、シャッフル自体が均一であると仮定すると(Java docsでは「すべての順列がほぼ等しい尤度で発生する」という保証があります)、拒絶ベースのソリューションでは、それぞれの混乱が1つの順列であり、順列の確率は同じです。
マーティンエンダー

1
@Nobody Mathオタクはこちら。成功または失敗する条件は、統計ではベルヌーイ試行と呼ばれます。これは、最初の成功に必要なk回の試行の確率が(1-p)^(k-1)* pであることを意味します。ここで、pは混乱の成功の確率です。kが大きくなると、k回の試行が必要になる確率が非常に小さくなることがわかります。したがって、アルゴリズムは確率1(「ほぼ確実」)で停止しますが、停止しないことは不可能ではありません。
下僕16

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.

ジョナサンアランはバイトを節約しました。


5
あなたは事前にウィンターバッシュハットを手に入れましたか?:-)
ルイスメンドー

2
素敵な新しい絵を描く時間Ẋ=³S$¿は、バイトを節約します。
ジョナサンアラン

2
ええ、私はそれについて知りませんでした$。ありがとう!
リン

6文字ですが、6バイト以上です。Ẋ=³S$¿バイト長は312112です。合計10バイトです。
mxfh

6

Python、85バイト

渡されたリストを変更します(メタおよび質問で許可されます)。

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

こちらからオンラインでお試しください!


1
Python 2を指定した場合、次の行でインデントスペースを置き換えdef D(l):l=input()保存できると思います(関数の代わりにプログラムがあるため)。しかし、ダウン投票しませんでした!
mathmandan

@mathmandanの良いアイデアですが、それが完全なプログラムである場合、再度印刷する必要があります。
FlipTack 16

1
もし君がそういうならいいよ。私は仕様を印刷または結果を返す必要はないと言っているように思えます-[ユーザー入力から]リストを取得し、それをシャッフルすれば十分だと思います。しかし、「既存の」を「コードを実行する前に存在している」と読むのは合理的です。その場合、私はあなたに同意します。(たぶんこれについては十分に確立されたコンセンサスがあるでしょう。):)
mathmandan

5

ES6(Javascript)、 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

Perl 6、33バイト

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

入力として整数または文字のリストを受け取り、新しいリストを返すラムダ。

任意の値のリストをサポートする必要がある場合neは、!eqv(+ 2バイト)に置き換える必要があります。

オンラインで試してください。

説明:

  • { }:ラムダを定義します。
  • .pick(*):入力リストのランダムシャッフルを生成します。
  • .pick(*) xx *:このようなシャッフルのレイジー無限シーケンスを作成します。
  • (* Zne $_).all:2つのリスト(その引数*、および外側のラムダの引数$_)をne(負の文字列の等価性)演算子で圧縮し、ブールのリストを生成し、次にそれらを単一のブール状態に折りたたむallジャンクションを作成するラムダ。
  • first PREDICATE, SEQUENCE:「混乱」テストを満たす順列の無限シーケンスから最初の要素を取得します。


3

Perl 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バイト

これは、Octaveの投稿の翻訳です(ここにある他の投稿のいくつかに似ています)。昨日、最初のMATL投稿(CNRクラック)を投稿したので、これは最適ではないと思いますが、これまでで最高です。

正直に言うtと、そこに必要なのかどうかは完全にはわかりませんが、これを機能させるための唯一の方法です。これは、ユーザー入力(で取得G)とランダム順列を比較できるようにするために使用されます。私はそれなしで2つを比較できると思いますが、...?

とにかく、ここに行きます:

`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でゴルフをしようとして楽しい... :)だった
Stewieグリフィン

:-)私はそれを取り除く方法を見ていませんt(または同等に別のG)次の反復のために、または最終結果としてスタックに何かを残す必要があります
ルイスメンドー

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節約する代わりに使用できます。


自己への注意:次回は質問全体を読んでください:)ありがとう!
グリフィン

1
それはいつも私に起こります:-)
ルイスメンドー

2

MATL、13バイト

これは@LuisMendoと私が共同で行った取り組みです。ここでの他の多くの答えとは対照的に、これは混乱を得るまでランダムな順列をサンプリングしないという意味で決定論的ですが、すべての混乱を生成し、ランダムに1つを選択します。

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

Pyth- 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

説明を追加してください。ピスの答えを書きたかった。私はそれについてあまり知りません。
グルパッドママダプール16

@GurupadMamadapur確かに、幸せにもなります。
マルティセン16

1
@GurupadMamadapurが追加されました。我々は持っているチュートリアルを。かなり時代遅れですが、基本を教えてくれます。pythに関連することで何か助けが必要な場合は、チャットで私にpingしてください。
マルティセン16

2

Mathematica、57バイト

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

名前のない関数のリストを入力として受け取り、リストを出力する関数。#入力のすべての順列を生成した後、要素ごとの違いのxセット#-xにaが含まれていない順列のみを保持し0ます。次に、そのセットから(均一に)ランダムな選択を行います。


1
いいね!少し長く#/.x_:>NestWhile[RandomSample[#,Length@#]&,#,Not@FreeQ[#-x,0]&]&、明らかに迅速に長い文字列のために実際に
マーティン・

待ってください、あなたはMathematicaに混乱のためのビルトインがないと言っていますか?:o
shooqie 16

私はビルトインを半分期待していた:)
グレッグマーティン

0

PHP、85バイト

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

文字列引数を2つの配列にコピーし、それらの差(要素のインデックスも比較)が他の配列と等しくなるまで、配列の1つをシャッフルします。で実行し-rます。


0

R、59バイト

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

要素のリストをSTDINに読み取り、リストの長さを取得して、順序付きリストと場所を共有しない要素が見つかるまで、1から長さの範囲のサンプリングを開始します。次に、そのリストを印刷します。


0

ワンダー、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
]

再帰関数ffの入力リストと、入力リストのシャッフルされたバージョンとの間で要素ごとの比較を行います。比較により等しい値が得られた場合、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

Clojure、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を破りました。

ブルートフォース法。無効なリストをシャッフルします。これは、重複試行を防ぐために何もしないブルートフォースメソッドであることを考慮して、愚かなことをすばやく終了します。1000要素の長いリストの1000個の障害が1秒未満で見つかりました。

ゴルフをしていない:

(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

Clojure、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))、falseのセット、trueのセット、またはtrueとfalseのセットのいずれかを返すことです。これは関数として使用できます。含まれているtrue場合、答えはtrue、そうでない場合はfalsy nilです。=2つの入力引数を使用して、何かでラップする必要はありません。

((set [false]) true)
nil

たぶん、値のいずれかが真であるかどうかを確認するより短い方法がありますか?


0

APL、11バイト。

正しい引数に文字列がある場合:

⍵[⍋(⍴⍵)?⍴⍵]

説明

ρ⍵ 正しい引数の長さ(または形状)を取得します。

?(⍴⍵)これらの数値のランダム配列を返します。

重複しないようにするために、それらの順序を返します。

⍵[..] このインデックスを使用した文字列のランダムな品揃えを表します。


PPCGへようこそ!すべてのエントリは有効な関数または完全なプログラムである必要があるため、答えは関数の引数または入力メソッドを介して入力する必要があります。
ETHproductions

今は要件に合うはずだと思います。正しい引数、またはを取ります
ジェイコブアトリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.