Bogosort Uygula


29

Is Sudoku çözme çok sert? Hatta kaba kuvvet sürümü? İşte biraz daha kolay bir kodlama alıştırması. Umuyorum. :-P

Bogosort'u uygulamak için en kısa işlevi yazın. Özel olarak, fonksiyonunuz:

  • Girdi olarak bir dizi (veya dilinizin eşdeğeri) alın
  • Öğelerinin sıralı sırada olup olmadığını kontrol edin; öyleyse diziyi döndür
  • Değilse, elemanları karıştırın ve yeniden başlayın

En kısa giriş kazanır. Bağlanma durumunda, özel bir karşılaştırıcıyı (ve / veya sözde rasgele sayı üretecini) destekleyen bir işlev tercih edilir. Geriye kalan tüm bağlar, önceki başvuruyu destekleyerek çözülür.


Açıklamalar: Elbette, onları sipariş etmenin bir yolu olduğu sürece istediğiniz herhangi bir eleman türünü kullanabilirsiniz. Ayrıca, karıştırmanın tek tip olması gerekir; Bunların hiçbiri "Sadece hızlıca pes ettireceğim ve karıştırıyorum" işi. :-)


Eleman tipleri nelerdir? int veya dizeleri?
Alexandru

@Alexandru: Her ikisi de iyidir. Sen seç.
Chris Jester-Young

Özel bir karşılaştırıcı eklemek kod uzunluğunu artıracak, böylece kazanan bir girişin özel bir karşılaştırıcısı olmayacak. Bence bağı kırmak bir anlam ifade etmiyor.
Alexandru

1
Sözde rasgele üreteç kullanılırken bu algoritma başarısız olabilir. örneğin, listenin uzunluğu 2000'i geçtiğinde, 2000 var! Prng'nin interal devlet sayısını aşabilecek liste için devletler.
gnibbler

2
Evet, wikipedia'dan yapılan söz konusu alıntı "Ancak, rastgele bir kaynak yerine sahte bir sayı üreteci kullanılıyorsa, bunlar uzun süreli döngüsel davranış sergiledikleri için asla sonlandırılamaz."
gnibbler

Yanıtlar:


8

APL (Dyalog), 20

{⍵≡⍵[⍋⍵]:⍵⋄∇⍵[?⍨⍴⍵]}

açıklama

(sağ) argümanı
⍵≡⍵[⍋⍵]: Sıralamanın kendisine eşit olup olmadığını kontrol eder
:⍵: Evet ise, o zaman geri dönün
∇⍵[?⍨⍴⍵]: Başka, rastgele sırayla 1'den ⍴⍵(uzunluğa kadar ) bir dizi oluşturun , buna göre yeniden sıralayın ⍵[...]ve işlevi ona uygulayın ( )


Birdenbire bu sorunu tekrar gözden geçirin ve ...

APL (Dyalog), 19

{∧/2≤/⍵:⍵⋄∇⍵[?⍨⍴⍵]}

Sadece çek dizisindeki bir diziyi sıralamayı düşünmek, onu anlamsızlaştırıyor (Bogosort'un anlamlı olduğunu söylememek), daha doğru bir uygulama olurdu ∧/2≤/⍵ve bu da char sayısını düşürür.


15

Perl 6: 23 karakter

@s.=pick(*)until[<=] @s

1
Perl'de bu bir fonksiyon mu? Güzel görünüyor :)
Eelvex

1
Bilmiyorsanız, [<=]bir listenin sıralanıp sıralanmadığını kontrol eder: [<=] (1, 2, 3,) == (1 <= 2 <= 3) == (1 <= 2) and (2 <= 3)ve .pick(n)bir listeden n rastgele öğe seçer ve Perl'nin .pick(*)tüm öğeleri seçmesine izin verir. use.perl.org/~masak/journal/40459
Ming-Tang

Bu Perl 6 olmalı. Daha önce hiç pickkullanılmamış, tek başıma görmedim [<=]. Bunlar belgelerde nerede?
Bay Llama,

@GigaWatt Bu Perl 6 (Perl 5 değil). []köşeli parantezler arasında operatörü alan operatörü azaltır. Örneğin, [<=] 1, 2, 3bir 1 <= 2 <= 3(ve evet, Perl 6 böyle aralıkları yapmak). Bu durumda, elemanların sıralı olup olmadığını belirlemek için kullanılır. .pick(*)yöntemi listeyi karıştırır (listeden öğeleri pick(N)seçer N). .=Çağrılar yöntemi ve sonucu değişkene atar. Belgeleme gelince - iyi, şimdilik sadece Perl 6 özelliği var - feather.perl6.nl/syn , ancak var.
Konrad Borowski,

7

APL (22)

{(⍳X←⍴⍵)≡⍋⍵:⍵⋄∇⍵[X?X]}

Kullanımı:

    {(⍳X←⍴⍵)≡⍋⍵:⍵⋄∇⍵[X?X]} 3 2 1
1 2 3

Açıklama:

  • ⍋⍵: Maddelerin indekslerini sıralı sırada ⍋30 10 20verir,2 1 3
  • (⍳X←⍴⍵)≡⍋⍵:⍵Giriş listesinin uzunluğunu X olarak saklayın. Aralık [1..X], sıralanmış dizin sırasına eşitse, liste sıralanır, bu nedenle geri dönün.
  • ⋄∇⍵[X?X]: durum böyle değilse, karıştırılmış diziyle yineleyin.

7

Ruby - 33 karakter

g=->l{l.shuffle!!=l.sort ?redo:l}

1 char daha az:g=proc{|l|0until l.sort==l.shuffle!}
AShelly

@AShelly, sürümünüz çalışmıyor. Benim versiyonum (5 karakter daha az) f=->l{l.sort!=l.shuffle!?redo:l}(Yakut 1.9)
Hauleth,

Birisi bana neden klasik bir yöntemle değil de redoçalıştığını açıklayabilir mi? Sadece döngülerle çalıştığını mı düşündüm ? procdef...endredo
Patrick Oscity

1
Tamam, boşver, 'Ruby Programlama Dili' kitabında bir şey buldum: ” redo[…] kontrolü proc veya lambda“ nın başına geri götürür. Bu sadece böyle.
Patrick Oscity

6

Mathematica , 40 37

NestWhile[RandomSample,#,Sort@#!=#&]&

Boşluk ile:

NestWhile[RandomSample, #, Sort@# != # &] &

Hataları #//.l_/;Sort@l!=l:>RandomSample@l&
Martin Ender

Mthmca'da 13sh bayt.
Michael Stern

5

J - 34 27

f=:({~?~@#)^:(1-(-:/:~))^:_

Örneğin:

f 5 4 1 3 2
1 2 3 4 5

f 'hello'
ehllo

? {~ ~ @ # Parçası girişini karıştırır:

({~ ?~@#) 1 9 8 4
4 8 9 1
({~ ?~@#) 'abcd'
bdca

3

Python 61

Sıralar.

import random
def f(l):
 while l!=sorted(l):random.shuffle(l)

İşleviniz diziyi başarı ile döndürmüyor.
hallvabo

Sıralar. Geçen dizi değiştirildi.
Alexandru

Soru, işlevin diziyi döndürmesi gerektiğini söylüyor - sonucu elde etmek için teknik olarak gerekli olmasa bile.
Jonathan M Davis,

1
from random import*Bir char kaydedebilirsiniz.
ugoren

1
Bu her zaman işe yaramayabilir: (python rasgele modül dokümantasyonundan): "Küçük len (x) için bile, x'in toplam permütasyon sayısının çoğu rastgele sayı üreticisinin periyodundan daha büyük olduğuna dikkat edin; uzun bir dizi asla üretilemez. "
Matt,

3

Python 94

from itertools import*
def f(a):return [x for x in permutations(a) if x==tuple(sorted(a))][0]

Diğer python cevapları random.shuffle () işlevini kullanır. Python rasgele modülünün dokümantasyonu şunları belirtir:

Çok küçük len (x) için bile, x'in toplam permütasyon sayısının, rastgele sayı üreteçlerinin çoğundan daha büyük olduğunu unutmayın; bu, uzun bir sekansın permütasyonlarının çoğunun asla üretilemeyeceği anlamına gelir.


Bunun yerine bir lambda yapın; Daha kısa olacağını düşünüyorum. Ayrıca return[x...aksine yapabileceğinizi unutmayın return [x.... Aynı permutations(a) if- olabilir permutations(a)if.
0WJYxW9FMN

lambda a: [x for x in __import__("itertools").permutations(a) if x==tuple(sorted(a))][0]88 bayttır
famous1622

3

K, 31 25

{while[~x~x@<x;x:x@(-#x)?#x];x}

{x@(-#x)?#x}/[{~x~x@<x};]

.

k){x@(-#x)?#x}/[{~x~x@<x};] 3 9 5 6 7 9 1
`s#1 3 5 6 7 9 9

.

k){x@(-#x)?#x}/[{~x~x@<x};] "ascsasd"
`s#"aacdsss"

2

Python (69 karakter)

from random import*
def f(a):
 while a>sorted(a):shuffle(a)
 return a

Sayısal sırayı artırırken tam sayıları sıralar. Özyinelemeli çözümler gibi

from random import*;f=lambda a:a>sorted(a)and(shuffle(a)or f(a))or a

Python kuyruk çağrısı optimizasyonu yapmadığından, küçük girişlerde bile yığın taşması nedeniyle başarısız olur (N> 5 deyin).


2

Özel karşılaştırıcı olmadan D: 59 Karakter

R f(R)(R r){while(!isSorted(r))r.randomShuffle();return r;}

Daha okunaklı:

R f(R)(R r)
{
    while(!r.isSorted)
        r.randomShuffle();

    return r;
}

Özel karşılaştırıcı ile D: 69 Karakter

R f(alias p,R)(R r){while(!isSorted!p(r))r.randomShuffle();return r;}

Daha okunaklı:

R f(alias p, R)(R r)
{
    while(!isSorted!p(r))
        r.randomShuffle();

    return r;
}

2

Scala 73:

def s(l:Seq[Int]):Seq[Int]=if(l==l.sorted)l else s(util.Random.shuffle l)

Scala'da, derleyicinin kuyruk çağrısı optimizasyonu yapıp yapmadığını kontrol edebiliriz:

@annotation.tailrec
def s(l:Seq[Int]):Seq[Int]=if(l==l.sorted)l else s(util.Random shuffle l)

ve evet, yaptı. Ancak, 100 değerin kısa bir listesi için:

val rList = (1 to 100).map(x=>r.nextInt (500))
s(rList) 

tamamlamak için yaklaşık 4 ay sürdü. ;)


2

C # (184 karakter)

T[]S<T>(T[]i)where T:IComparable<T>{T l=default(T);while(!i.All(e=>{var r=e.CompareTo(l)>=0;l=e;return r;})){i=i.OrderBy(a=>Guid.NewGuid()).ToArray();l=default(T);}return i.ToArray();}

Bunu C # ile yapmak pek hoş değil. Hem değer hem de referans türlerini desteklemek için jenerikleri desteklemelisiniz. Bir şeyin sıralanıp sıralanmadığını kontrol etmek için herhangi bir dizi karıştırma fonksiyonu ya da fonksiyonu yoktur.

Bunu daha iyi hale getirmek için herhangi bir ipucu olan var mı?

Yalnızca int (134 karakter) sıralayan Sürümü Düzenle:

int[]S(int[]i){var l=0;while(!i.All(e=>{var r=e>=l;l=e;return r;})){i=i.OrderBy(a=>Guid.NewGuid()).ToArray();l=0;}return i.ToArray();}

2

GNU / BASH 65

b(){ IFS=$'\n';echo "$*"|sort -C&&echo "$*"||b $(shuf -e "$@");}

Bash işlevleri tam anlamıyla işaretsiz bir bayt döndüğü için dizi kuralını döndürmek için özel bir istisna alabilir miyim ?
kojiro

2

C ++ 11, 150 karakter

#include<deque>
#include<algorithm>
void B(std::deque &A){while(!std::is_sorted(A.begin(),A.end())std::random_shuffle(myvector.begin(),myvector.end());}

Sadece .. eğlence için yapılmış.


1
std :: random_shuffle tekdüze değildir. Açıklamalarda şu şekilde belirtilmiştir: "Ayrıca, karıştırmanın tek tip olması gerekir"
STDQ

Tamam ... üniforma olmadığını bilmiyordum.

Üniforma olmayan rand () 'a dayanır - bakınız open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3924.pdf . Çok fazla insan takip etmiyor gibi görünüyor, bu yüzden önemli değil.
STDQ

Yani srand (time (0)) kullanmak gibi tamamen rastgele bir tane kullanırsam o zaman sayılır mı?

Sorun şu ki rand, tekdüzelikten bağımsız olarak, rastgele sayıların iyi kalitede olmasını garanti etmiyor, bazıları rastgele olmayan düşük sıralı bitler üretiyor. Sanırım sonunda bunun önemi yok. Sadece std :: shuffle ve benzerleri ile tek tip bir distribütör kullanarak 8 bayt aldım, benim için yeterince iyi.
STDQ

2

Python - 61 karakter

Recursive

from random import*;f=lambda l:l==sorted(l)or shuffle(l)>f(l)

İşleviniz diziyi değil, Doğru veya Yanlış döndürür.
hallvabo

2
Ayrıca, özyinelemeli çözümlerin küçük girdiler için bile başarısızlığa mahkum olduğuna dikkat edin.
hallvabo

1
@hallvabo: Aslında Scheme'de yığınızı tüketmeyecek bir kuyruk özyinelemeli çözüm yazmak istiyorum, elbette.
Chris Jester-Young,

@hallvabo, Alexandru bariz Python çözümünü çoktan yapmıştı, bu yüzden burada sadece farklı bir şey için gidiyordum. Elbette özyinelemeli çözüm sadece eğlence için değil ciddi bir yarışmacı değil
gnibbler

from random import*daha kısa olabilir.
0WJYxW9FMN

2

PowerShell , 85 82 56 55 52 bayt

Mazzy'nin önerileri sayesinde -26 bayt; AdmBorkBork sayesinde
-1 bayt -3mazzy
sayesinde bayt.

for($l=$args;"$l"-ne($l|sort)){$l=$l|sort{random}}$l

Çevrimiçi deneyin!

PowerShell, bunları dizelere dönüştürerek ve karşılaştırarak nispeten ucuz bir dizi karşılaştırmasına sahiptir.


2
Senin Taşı paramsenin içine başlatma forbir byte kaydetmek için başlatma -for($l=$args;
AdmBorkBork

1
Güzel. -nesağdaki operatörü, soldaki operatörün skaler tipine çevirir. Böylece, birkaç bayt kaydedebilirsiniz: Çevrimiçi deneyin!
mazzy

1

Javascript 291 karakter

min

function f(e){var t=[].concat(e).sort();t.e=function(e){var n=true;t.forEach(function(t,r){if(t!=e[r])n=false});return n};while(!t.e(e.sort(function(){return Math.floor(Math.random()*2)?1:-1}))){console.log(e)}return e}

un dakika

function f(a) {
var b = [].concat(a).sort();
b.e = function (z) {
    var l = true;
    b.forEach(function (v, i) {
        if (v != z[i]) l = false;
    });
    return l
};
while (!b.e(a.sort(function () {
    return Math.floor(Math.random() * 2) ? 1 : -1;
}))) {
    console.log(a);
}
return a;
}

Bunu daha önce söylediğimi hissediyorum, ama hepsini kaldırabilirsiniz var. Bunların hepsini gizli globals yap, sadece kodu olabildiğince kısa yapmakla ilgili.
gcampbell

1

Matlab, 59 bayt

Nispeten dümdüz ileri yaklaşım:

x=input('');while~issorted(x);x=x(randperm(numel(x)));end;x

1

J, 22 bayt

$:@({~?~@#)`]@.(-:/:~)

Bu bir gündem kullanarak özyinelemeli, salak bir monad. İşte nasıl çalışıyor:

Let ybizim listesi olacak. Birincisi, gündemin sağındaki fiildir -:/:~. Bu nezaketle Leaky Nun tarafından sağlanan bir fiil . Monadik bir kanca kullanarak -:girişin sıralanıp sıralanmadığı ( /:~) ile eşleşir ( ) . ( (f g) y = y f (g y)) Buna göre bir veya sıfır döndürür. Gündemin sol tarafı iki fiilden oluşuyor: sağda kimlik fiili ], solda ise özyinelemenin gerçekleştiği yer. Gündemi seçer ya pozisyonunda fiil kimlik 1liste halinde olduğu pozisyonda uzun fiil sıralanır ve 0liste halinde değil sıralanmış.

$:@({~?~@#)çağrılar $:sonucu tepesinde (o bulunan en uzun fiil) {~?~@#üzerinde y. Bu, listedeki rasgele sıralanan endekslerin ?~@#uzunluğundaki değişimleri alır . , monadik bir kancada, dizinleri doğru arg olan listeyi döndürür . Bu karışık liste daha sonra tekrar gündemle birlikte çağrılır ve sıralanıncaya kadar tekrar eder.yy{~y


1

C ++ 14, 158 bayt

#include <algorithm>
#include <random>
[](int*a,int s){std::random_device r;for(std::knuth_b g(r());!std::is_sorted(a,a+s);std::shuffle(a,a+s,g));return a;};

1

Jöle , 6 byte, dil sonlandırma tarihi mücadelesi

ẊŒ¿’$¿

Çevrimiçi deneyin!

açıklama

ẊŒ¿’$¿
     ¿  While
 Œ¿’$     the input is not in its earliest possible permutation (i.e. sorted)
Ẋ       shuffle it

Œ¿bir listenin her permütasyonuna bir sayı atar; 1 sıralanır, 2 liste uzunluğunun faktörüne (tersi sıradaki listedir) kadar değiş tokuş edilen son iki elemana vb. Sahiptir. Bu nedenle, sıralı bir liste için, bu değer 1'dir ve bir süre döngü koşulunda bir Boole olarak kullanılabilen bir "sıralanmamış" test üretmek için kullanarak azaltabiliriz . $Durum bir grup olarak ayrıştırmak için neden olmaktır.


1

C ++, 166 bayt

Meh.

#import<algorithm>
#import<random>
#define r b.begin(),b.end()
template<class v>
v f(v b){auto a=std::mt19937();while(!std::is_sorted(r))std::shuffle(r,a);return b;}

Bu begin()ve sahip olan tüm STL kaplarında çalışmalıdır end().

Ungolfed:

#include <algorithm>
#include <random>
template <class v>
v f(v b) {
    auto a = std::mt19937();
    while (!std::is_sorted(b.begin(),b.end()))
        std::shuffle(b.begin(),b.end(),a);

    return b;
}


1

Brachylog , 5 bayt

∈&ṣ≤₁

Çevrimiçi deneyin!

Ais523'ün Brachylog cevabını ilk gördüğümde (Jelly'in cevabının aksine, çünkü yanılmıyorsam, kullanıcı 62131 de oydu), merak ettim, peki ya özyinelik yerine geri izleme kullandıysa? İlk başta denedim ṣ≤₁. Tesadüfen bir şeyi seçmek rastgele olmayan bir çıktı ürettiği için çok fazla çıktı üretmediği için, karışık belirti geri alınamaz, bu nedenle doğru şekilde karıştırmak için yeterince şanslı olmadığınız sürece, sadece başarısız olacak ilk denemede. Ondan sonra, pṣ≤₁çoğu zaman işe yarayan denedim , ancak son derece uzun bir listenin son derece sayıda permütasyonu olduğundan, bazen rastgele olarak başarısız oldu. Uzunluk azaltma hedefini bıraktıktan sonra nihayet şunu buldum:

         The input
∈        is an element of
         an unused implicit variable,
 &       and the input
  ṣ      shuffled randomly
   ≤₁    which is increasing
         is the output.

(Rastgeleliğin gösterilmesi)

Gerçekte biraz daha kısa olsa da G / Ç ile bazı özgürlükler alırsak ...

Brachylog , 4 bayt

⊆ṣ≤₁

Çevrimiçi deneyin!

Çıktının kullanışlı olması için, girişin herhangi bir yinelenen eleman içermemesi gerekir; çünkü girişi sıralamaya ek olarak, bu bogosort yordamı, rastgele sayıda yinelenen eleman ve sıfır ekler. (Varsayımsal olarak, herhangi bir şey ekleyebilir, ancak sadece bir şey yapmaz.) Normalde, doğru işleyişten çok uzak bir şeyden bahsetmekten zahmete girmezdim, ama zorluğun ruhunda olduğunu hissediyorum.

⊆        An ordered superset of the input
 ṣ       shuffled randomly
  ≤₁     which is increasing
         is the output.

1

Perl 6 , 28 bayt

{({.pick(*)}...~.sort).tail}

Çevrimiçi deneyin!

Sıralanana kadar listeyi karıştıran adsız kod bloğu. Listenin en az bir kez sıralanacağına dikkat edin. Ve hayır, {.pick(*)}değiştirilemez*.pick(*)


1

Pyth , 11 bayt

Wn=Q.SQSQ;Q

Bu oldukça mutlu, muhtemelen biraz daha golf olabilir

açıklama


Wn=Q.SQSQ;Q
W    While
  =Q.SQ    Variable Q (input variable) shuffled 
 n  Does not equal
       SQ    Variable Q sorted
             ;  Do nothing (loop ends)
              Q    And output variable Q

Çevrimiçi deneyin!


Sen kısaltabilir =Q.SQiçin =.SQiçin -1 byte (gibi çok diğer operatörler ile çalışır =QhQ-> =hQ)
ar4093

1

Japt , 11 9 bayt

_eZñ}a@öx

Dene

_eZñ}a@öx     :Implicit input of array U
_             :Function taking an array as argument via parameter Z
 e            :  Test Z for equality with
  Zñ          :  Z sorted
    }         :End function
     a        :Repeat and return the first result that returns true
      @       :Run this function each time and pass the result to the first function
       öx     :  Random permutation of U

1

Brachylog (v2), 5 bayt

≤₁|ṣ↰

Çevrimiçi deneyin!

İşlev sunumu. (TIO bağlantısı, bir işlevi otomatik olarak tam bir programa saracak bir komut satırı argümanı kullanır.)

açıklama

≤₁|ṣ↰
≤₁      Assert that {the input} is (nonstrictly) sorted in ascending order
  |     Output it
  |     Exception handler: if an assertion fails:
   ṣ      Randomly shuffle {the input}
    ↰     and run this function recursively on it, {outputting its output}

Prolog (Brachylog'un derlediği dil) kuyruk özyinelemelidir, bu nedenle bu işlev sıkı bir döngü halinde derlenir.


0

C (203 karakter, giriş döngüsü yok: yalnızca işlev)

#include <stdio.h>
#define P (int*a,int n){
#define F for(i=0;i<n;i++){
int i,j,v;s P F if(a[i]>a[i+1])return 0;}return 1;}void h P F v=a[i];a[i]=a[j=rand()%n];a[j]=v;}}void b P while(!s(a,n-1))h(a,n);}

Bu, stdin'den de dizi okuduğumuz ve sıralanmış diziyi yazdığımız aşağıdaki gibidir. Q işlevi değil tüm programı istediğinden beri ...

C (296 karakter)

#include <stdio.h>
#define P (int*a,int n){
#define F for(i=0;i<n;i++){
int i,j,n,v,x[999];s P F if(a[i]>a[i+1])return 0;}return 1;}void h P F j=rand()%n;v=a[i];a[i]=a[j];a[j]=v;}}void b P while(!s(a,n-1))h(a,n);}main(){while(scanf("%d",&v)==1)x[n++]=v;if(!s(x,n))b(x,n);F printf("%d\n",x[i]);}}

Derleme, uyarı verebilir (örtük beyanlar). Hardencoded dizi boyutu 999 elementlerin sınırı. Kırılgan.

Dizinin sıralanıp sıralanmadığını kontrol etmeye gerek yoksa, 284'te yapılabilir.

C (251 karakter, 284 idi)

#include <stdio.h>
#define F for(i=0;i<n;i++){
int i,j,n,v,a[999];s(int n){F if(a[i]>a[i+1])return 0;}return 1;}void h(){F v=a[i];a[i]=a[j=rand()%n];a[j]=v;}}void b(){while(!s(n-1))h();}main(){while(scanf("%d",&a[n++])>0);b();F printf("%d\n",a[i]);}}

(fonksiyon argüleri yerine globals kullanarak).

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.