Rasgele bir düzenleme oluşturun


30

Meydan açıklaması

Bir dizinin "bozulması", hiçbir öğenin orijinal konumunda görünmediği bir permütasyondur. Örneğin ECABD, bir düzenlemedir ABCDE, ancak CBEDAdeğildir:

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

Bir dizi göz önüne alındığında, bunun rastgele bir düzenlemesini oluşturun.

notlar

  • Girdi olarak bir dize ya da bir dizi / eleman listesi (tamsayılar, karakterler, nesneler ...) alabilir.

  • Yeni bir nesne döndürmek yerine, mevcut bir nesneyi öğelerini değiştirerek değiştirebilirsiniz.

  • Her düzenleme, eşit olarak üretilme olasılığına sahip olmalıdır.

  • Dizide birden fazla öğe olduğunu ve hiçbirinin bir defadan fazla görünmediğini varsayabilirsiniz.



3
@VoteToClose: haha, tamamen yakalandın
shooqie

Bütün bunlar hakkında pek bir şey bilmiyorum ama bu, her şeyin kendi pozisyonunda veya böyle bir şeyde sonuçlanacağına göre, sabit nokta teoremiyle ilgili herhangi bir şekilde mi? Bahse girerim yanıldım ama birisi lütfen beni düzeltin :)
Farhan Anam

Öğelerin benzersiz olacağına dair herhangi bir garanti var mı veya yinelemeler içerebilir mi?
Carcigenicate

1
@Carcigenicate: açıklamasında tam orada; Eğer hiçbir Yinelenen başka varsayabiliriz
shooqie

Yanıtlar:


12

CJam , 14 bayt

q:X{mr_X.=:|}g

Çevrimiçi deneyin!

Bir düzenlemeye kadar girişi karıştırmaya devam eder.

açıklama

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'nin, çözümlerin her zaman biteceğini garanti etmek zorunda kalacağını belirtmesini diliyorum.
John Dvorak

4
@JanDvorak Eh, bunun bitmemesi olasılığı 0'dır. Ancak, deterministik bir çalışma süresi gerektirmenin zorluğu daha ilginç hale getireceği konusunda haklısınız.
Martin Ender

Olasılık aslında 0 mı? Karıştırma işlemi mükemmel olmaz, gerçekte nasıl çalışır? Bunun OP'nin ne istediğinin iyi bir yaklaşımı olduğunu düşünüyorum, ancak her bir düzenlemenin olasılıklarının aynı olduğundan şüpheliyim (muhtemelen karıştırma işlemi tarafından kullanılan PRNG'nin bazı tohum değerlerine bağlıdır).
Hiç kimse

3
@ Hiç kimse, herhangi bir algoritmayı kullanarak herhangi bir algoritmayı kullanarak bir PRNG'den mükemmel bir şekilde tek tip sonuçlar alabileceğinden şüphem yok. Bununla birlikte, karışıklığın kendisinin homojen olduğunu varsayarak (Java, "Tüm izinler yaklaşık olarak eşit olasılıkla gerçekleşir" şeklinde bir garanti vermektedir), reddedilmeye dayalı bir çözüm aynı zamanda her düzenlemenin tek bir permütasyon olması nedeniyle aynı düzenlemeleri sağlayacaktır. permütasyon aynı olasılıkta.
Martin Ender

1
@ Kimse Math nerd burada. Başarılı olan veya başarısız olan bir duruma istatistikte Bernoulli denemesi denir. Bu, k denemelerine ihtiyaç duyma olasılığının ilk başarıya ulaşma ihtimalinin (1 - p) ^ (k - 1) * p olduğu, p'nin başarılı bir düzenlemenin olasılığı olduğu anlamına gelir. K büyüdükçe, k denemeye ihtiyaç duyma olasılığının ufak bir şekilde küçüldüğünü görmek kolaydır. Bu nedenle, algoritmanın 1 olasılıkla (“neredeyse kesin”) durduğunu söylüyoruz, ancak bunun asla durmaması imkansız değil.
usta

9

Jöle , 6 bayt

Ẋ=³S$¿

Çevrimiçi deneyin!

açıklama

Ẋ    ¿    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 bir bayt kurtardı.


5
Yani Winter Bash şapkasını vaktinden önce aldın mı? :-)
Luis Mendo

2
Güzel bir resim çizme zamanı, Ẋ=³S$¿bayttan tasarruf sağlar.
Jonathan Allan,

2
Huh, bunu hiç bilmiyordum $. Teşekkürler!
Lynn,

6 karakter ama 6 bayttan fazla. Ẋ = $S $ ¿bayt uzunluğu: 312112. Toplamda 10 bayt.
mxfh

6

Python, 85 bayt

Kendisine iletilen listeyi değiştirir (meta tarafından ve soruda izin verilir).

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

Burada çevrimiçi deneyin!


1
Python 2 belirtirseniz, sana yerini düşünüyorum def D(l):ile l=input()ve daha sonra (bir program yerine bir işlevi var bu yüzden) Aşağıdaki satırlarda girinti boşluk kaydedin. Ancak, aşağı oy vermedi!
mathmandan

@mathmandan iyi bir fikir, ancak daha sonra, daha fazla bayt gerektiren tam bir programsa tekrar yazdırmam gerekir.
FlipTack

1
Öyle söylüyorsan tamam. Bana göre teknik özellik, sonucu yazdırmanız veya iade etmeniz gerekmediğini söylüyordu - [kullanıcı girişinden] bir liste alarak ve karıştırmanın yeterli olacağını söyledi. Ancak, "kodunuzu çalıştırmadan önce var olan" "mevcut" ifadesini okumak makul olur, bu durumda size katılıyorum. (Belki bu konuda sağlam bir fikir birliği vardır.) :)
mathmandan

5

ES6 (Javascript), 71, 69 bayt

Girdi ve çıktılar dizilerdir, "==" ile karşılaştırılabildikleri sürece herhangi bir öğe türüyle (dizeler, sayılar vb.) Çalışmalıdır.

golfed

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

Ölçek

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" ]

Etkileşimli Metin Parçacığı

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 bayt

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

Girdi olarak tam sayıların veya karakterlerin listesini alan ve yeni bir liste döndüren bir lambda.

Keyfi değer listelerini desteklemesi gerekiyorsa ne, !eqv(+2 bayt) ile değiştirilmesi gerekir .

( Çevrimiçi deneyin. )

Açıklama:

  • { }: Bir lambda tanımlar.
  • .pick(*): Giriş listesinin rastgele karıştırmasını oluşturur.
  • .pick(*) xx *: Bu tür karıştırmaların tembel bir sonsuz dizisini oluşturur.
  • (* Zne $_).all: İki listeyi (argümanı *ve dış lambda argümanı $_) ne(negatif dize eşitliği) işleci ile fermuarlayan , bir boole listesi veren ve ardından tek bir boole durumuna daraltmak için bir allkavşak oluşturan bir lambda .
  • first PREDICATE, SEQUENCE: İlk elemanı, "düzenleme" testini yerine getiren sınırsız permütasyon dizisinden alır.

4

Brachylog , 19 18 15 13 bayt

@~.:?z:#da;?&

Çevrimiçi deneyin!

açıklama

@~.                Output is a shuffle of the input
  .:?z             Zip the output with the input
      :#da         All couples of integers of the zip must be different
          ;      Or
           ?&      Call recursively this predicate with the same input

3

Perl 6 , 45 bayt

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

Dene

Giriş, her şeyin bir dizisidir.

Expanded:

{
  (

    @^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 bayt

Bu, Octave gönderimin bir çevirisidir (ve buradaki diğer gönderilerden bazılarına benzer). Dün ilk MATL yazımı gönderdim (CNR çatlağı), bu yüzden bu en uygun değil, fakat şimdiye kadar sahip olduğum en iyisi.

Dürüst olmak gerekirse, torada kesinlikle gerekli olduğundan emin değilim , ancak bunu işe almamın tek yolu bu. Bu, kullanıcı girdisini (alınan G) rastgele permütasyonla karşılaştırabilmem için kullanılır. İkisini onsuz karşılaştırabileceğimi düşünürdüm, ama ...?

Her neyse, işte gidiyor:

`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

Çevrimiçi deneyin!


Herhangi bir gelişme var mı? Gerçekten toraya ihtiyacım var mı yoksa ondan kurtulabilir miyim? MATL'de golf oynamak eğlenceliydi ... :)
Stewie Griffin

:-) Bundan nasıl kurtulacağımı bilemiyorum t(ya da eşdeğerde bir başka G) Bir sonraki tekrarlama için ya da nihai sonuç olarak yığında bir şey
bırakmanız gerekir

3

Aslında , 13 bayt

;;WX╚│♀=ΣWX)X

Çevrimiçi deneyin!

Açıklama:

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

Octave, 56 55 bayt

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

input('')Bu bir işlev olmadığından kullanmak zorundayız . Ayrıca, girdiyi string olarak seçmeyi seçtiğimden dolayı, bu numarayı kullanabiliriz nnz(x)==numel(x).

Açıklama:

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

Girişin bir dize olabileceğini fark ettiği için Luis'e teşekkür ederim, böylece iki bayt kaydetmek nnzyerine kullanabilirim numel.


Kendime not: Bir dahaki sefere tüm soruyu oku :) Teşekkürler!
Stewie Griffin,

1
Bu her zaman başıma geliyor :-)
Luis Mendo

2

MATL, 13 bayt

Bu @LuisMendo ve benim ortak çabam. Buradaki pek çok cevabın aksine, bu, bir düzenlemeye girinceye kadar rastgele permütasyonları örneklemediği, ancak tüm düzenlemeleri ürettiği ve rastgele seçtiği için belirleyicidir.

Y@tG-!Af1ZrY)

Çevrimiçi Deneyin!

açıklama

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 bayt

Bu, karakterlerden herhangi biri girişteki dizindeki karakterlere eşitken, girişi karıştırmaya devam eder.

.WsqVHQ.S

Burada çevrimiçi deneyin .

.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

Lütfen bir açıklama ekler misiniz? Bir pyth cevap yazmak istedim. Bunun hakkında fazla bir şey bilmiyorum.
Gurupad Mamadapur

@ GurupadMamadapur emin, de mutlu olurdu.
Maltysen

1
@GurupadMamadapur eklendi. Bir eğiticimiz var . Oldukça güncel değil, ama size temelleri öğretecek. Eğer pyth ile ilgili herhangi bir konuda yardıma ihtiyacınız olursa, sohbette beni ping etmekten çekinmeyin.
Maltysen

2

Mathematica, 57 bayt

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

Adsız işlev, girdi olarak nelerin listesini alarak ve bir listenin çıktısını alır. Girdideki tüm permütasyonları #oluşturduktan sonra x, sadece #-xelement-element farklılıkları kümesinin içermediği şeyleri tutarız 0; sonra o kümeden (tek tip) rastgele bir seçim yaparız.


1
Güzel! #/.x_:>NestWhile[RandomSample[#,Length@#]&,#,Not@FreeQ[#-x,0]&]&Uzun dizeler için pratikte biraz daha uzun bir süre daha hızlı
martin 21

Bekle, bana Mathematica’da yapılacak bir anlaşmazlık yok mu? : o
shooqie

Yarım kendimi bir yerleşik bekliyordum :)
Greg Martin

0

PHP, 85 bayt

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

String argümanını iki diziye kopyalar, aralarındaki fark (elemanların indekslerini karşılaştırırken) diğerine eşit olana kadar bunlardan birini karıştırır. İle koş -r.


0

R, 59 bayt

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

Öğelerin bir listesini STDIN'e okur, listenin uzunluğunu alır ve 1 ile uzunluk arasındaki örnekleme aralıklarını sıralamaya başlar, sıralı listeyle hiçbir yeri paylaşmayan birini bulana kadar başlar. Sonra o listeyi yazdırır.


0

Wonder , 32 bayt

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

Kullanımı:

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

açıklama

Daha okunabilir:

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

Özyinelemeli işlevi f. fGiriş listesi ile giriş listesinin karıştırılmış bir sürümü arasında eleman şeklinde bir karşılaştırma yapar . Karşılaştırma herhangi bir eşit değer verirse, fkarıştırılmış listede denir. Aksi takdirde, karıştırılan listeyi geri göndeririz.



0

Octave, 54 53 bayt

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

Tüm permütasyonlarını üret ave ortak bir unsuru olmayan bir satır rastgele seça .

not: Yanlışlıkla @flawr MATL cevabı ile aynı!


0

Clojure, 94 90 79 bayt

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

-4 bayt azaltma içinde koşullu bir değiştirerek andve satır içi değiştirerekdone? .

-11 bayt azaltma dönüştürerek some.

WOOT! PHP'yi yendi.

Kaba kuvvet yöntemi. Geçersizken listeyi karıştırır. Bu, yinelenen denemeleri engellemek için hiçbir şey yapmayan kaba bir kuvvet yöntemi olduğu düşünüldüğünde aptalca hızlı bir şekilde bitiyor. 1000 element uzunluğundaki listenin 1000 ayarını bir saniyeden kısa sürede buldu.

Ungolfed:

(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 bayt

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

Bir dizenin karıştırılamayacağını, seqveya içinden geçirilmesi gerektiğini unutmayın vec.

Başlangıçta denedim #(first(remove(fn[s]((set(map = % s))true))(iterate shuffle %)))ama recuryaklaşım gerçekten daha kısaiterate .

Sihir, (set(map = % s))yanlış, yanlış, doğru veya yanlış olarak döndürür. Bu, bir işlev olarak kullanılabilir, eğer öyleyse truecevap true, aksi takdirde sahte olur nil. =iki girdi argümanını almaktan mutluluk duyar, bir şeye sarmaya gerek yoktur.

((set [false]) true)
nil

Belki de değerlerden herhangi birinin doğru olup olmadığını kontrol etmenin daha kısa bir yolu vardır?


0

APL, 11 bayt.

Doğru argümanda dize ile:

⍵[⍋(⍴⍵)?⍴⍵]

açıklama

ρ⍵ doğru argümanın uzunluğunu (veya şeklini) alır.

? rastgele bir dizi döndürür (⍴⍵)bu sayıların .

yinelenenlerin olmamasını sağlamak için sırasını döndürür.

⍵[..] Bu indeksi kullanan dizgenin rastgele çeşitliliğini temsil eder.


PPCG'ye Hoşgeldiniz! Tüm girişlerin geçerli işlevler veya tam programlar olmasını istiyoruz, bu nedenle cevabınızın bir işlev argümanı veya giriş yöntemi yoluyla girdi alması gerekir.
ETHProductions,

Bence şimdi bu şartlara uymalı. Doğru argümanda alır veya .
Jacob Utley
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.