보고 소트 구현


29

되어 스도쿠를 해결하기 너무 열심히? 심지어 무차별 대입 버전? 조금 더 쉬운 코딩 연습이 있습니다. 나는 희망. :-피

bogosort를 구현하는 가장 짧은 함수를 작성하십시오. 특히, 기능은 다음과 같아야합니다.

  • 입력으로 배열 (또는 귀하의 언어와 동등한 것)을 가져 가십시오.
  • 해당 요소가 정렬 된 순서인지 확인하십시오. 그렇다면 배열을 반환
  • 그렇지 않으면 요소를 섞고 다시 시작하십시오.

가장 짧은 참가작이 승리합니다. 동점의 경우, 커스텀 비교기 (및 / 또는 의사 난수 생성기)를 지원하는 기능이 선호됩니다. 남은 관계는 이전 제출을 선호하여 해결됩니다.


설명 : 물론 주문할 수있는 방법이 있다면 원하는 요소 유형을 사용할 수 있습니다. 또한 셔플 링은 균일해야합니다. 이 중 어느 것도 "단순히 분류해서 섞었다"고하지 않습니다. :-)


요소 유형은 무엇입니까? 정수 또는 문자열?
Alexandru

@Alexandru : 어느 쪽이든 괜찮습니다. 당신이 선택합니다.
Chris Jester-Young

사용자 지정 비교기를 추가하면 코드 길이가 증가하므로 당첨 된 항목에는 사용자 지정 비교기가 없습니다. 나는 넥타이를 깨는 것이 의미가 없다고 생각합니다.
Alexandru

1
의사 랜덤 생성기를 사용할 때이 알고리즘이 실패 할 수 있습니다. 예를 들어 목록의 길이가 2000을 초과하면 2000이 있습니다! prng의 인터 럴 상태 수를 초과 할 수있는 목록의 상태.
gnibbler

2
네, wikipedia의 관련 인용문 "그러나 의사 난수 생성기가 임의의 소스 대신에 사용되는 경우 장기 순환 동작을 나타 내기 때문에 절대 종료되지 않을 수 있습니다."
gnibbler

답변:


8

APL (Dyalog), 20

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

설명

(오른쪽) 인수입니다
⍵≡⍵[⍋⍵]: 정렬 자체가 같은지 확인 합니다
:⍵: 예이면, 다음을 반환하십시오
∇⍵[?⍨⍴⍵]: 그렇지 않으면 1에서 ⍴⍵(길이)의 배열을 무작위 순서로 생성하고 그 순서 에 따라 ( ⍵[...]) 에 따라 재정렬 하고 함수를 적용하십시오 ( )


갑자기이 문제를 다시 방문하고 ...

APL (Dyalog), 19

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

검사에서 배열을 정렬하는 것에 대해 생각하고 있었기 때문에 (Bogosort가 의미가 있다는 것을 말하지는 않지만) 더 정확한 구현이 ∧/2≤/⍵되고 문자 수를 줄입니다.


15

펄 6 : 23 자

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

1
이것은 perl의 함수입니까? 그것은 멋져 보인다 :)
Eelvex

1
당신이 모르는 경우, [<=]점검 목록이 분류되어있는 경우 : [<=] (1, 2, 3,) == (1 <= 2 <= 3) == (1 <= 2) and (2 <= 3)그리고 .pick(n)이 선택하는 N 목록에서 임의의 요소, 그리고 .pick(*)펄이 모든 요소를 선택할 수 있습니다. use.perl.org/~masak/journal/40459
Ming-Tang

이것은 펄 내가 본 적이 6.해야합니다 pick전에 사용하지, 혼자하자 [<=]. 문서의 어디에 있습니까?
Mr. Llama

@GigaWatt 이것은 Perl 6입니다 (Perl 5 아님). []대괄호 사이에 연산자를 사용하는 감소 연산자입니다. 예를 들어, [<=] 1, 2, 3is 1 <= 2 <= 3(그리고 네, Perl 6에서 이와 같은 범위를 수행합니다). 이 경우 요소가 순서대로 있는지 판별하는 데 사용됩니다. .pick(*)메소드는 목록을 섞습니다 (목록 에서 요소 pick(N)선택 N). .=메소드를 호출하고 결과를 변수에 지정합니다. 문서화에 관해서는, 현재로서는 Perl 6 사양 -feather.perl6.nl/syn 만 존재하지만 존재합니다.
Konrad Borowski

7

APL (22)

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

용법:

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

설명:

  • ⍋⍵: 수익 인덱스 때문에, 정렬 된 순서로 항목을 ⍋30 10 20제공합니다2 1 3
  • (⍳X←⍴⍵)≡⍋⍵:⍵입력 목록의 길이를 X에 저장하십시오. 범위 [1..X]가 정렬 된 색인 순서와 같으면 목록이 정렬되므로이를 리턴하십시오.
  • ⋄∇⍵[X?X]: 그렇지 않은 경우 셔플 배열로 반복하십시오.

7

루비-33 자

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

1 문자 이하 :g=proc{|l|0until l.sort==l.shuffle!}
AShelly

@AShelly, 버전이 작동하지 않습니다. 내 버전 (5 문자 이하) f=->l{l.sort!=l.shuffle!?redo:l}(루비 1.9)
Hauleth

누군가 고전적인 방법으로 redo작동 proc하지 않는 이유를 설명해 주 def...end시겠습니까? redo루프에서만 작동 한다고 생각 했습니까?
Patrick Oscity

1
괜찮아, 난 '루비 프로그래밍 언어'책에서 뭔가를 발견했다 :“ redo… 그것은 단순히 그런 식입니다.
Patrick Oscity

6

수학 , 40 37

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

공백으로 :

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

오류를 무시하면 다음과 같이 3 바이트를 저장할 수 있습니다.#//.l_/;Sort@l!=l:>RandomSample@l&
Martin Ender

Mthmca의 13sh 바이트.
Michael Stern

5

J- 34 27

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

예 :

f 5 4 1 3 2
1 2 3 4 5

f 'hello'
ehllo

? {~ ~ @ #의 부분은 입력을 섞는다 :

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

3

파이썬 61

제자리에 정렬합니다.

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

성공하면 함수가 배열을 반환하지 않습니다.
hallvabo

제자리에 정렬합니다. 전달 된 배열이 수정되었습니다.
Alexandru

문제는 기술적으로 결과를 얻는 데 필요하지 않더라도 함수가 배열을 반환한다고 가정합니다.
Jonathan M Davis

1
from random import*문자를 저장할 수 있습니다.
ugoren

1
(파이썬 랜덤 모듈 문서에서) : "작은 len (x)조차도, x의 총 순열 수는 대부분의 난수 생성기의주기보다 큽니다. 이것은 대부분의 순열을 의미합니다. 긴 시퀀스를 생성 할 수 없습니다. "
Matt

3

파이썬 94

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

다른 파이썬 답변은 random.shuffle ()을 사용합니다. 파이썬 임의 모듈의 설명서는 다음과 같습니다.

다소 작은 len (x)의 경우, x의 총 순열 수는 대부분의 난수 생성기 기간보다 큽니다. 이것은 긴 시퀀스의 대부분의 순열이 절대로 생성 될 수 없음을 의미합니다.


대신 람다를 수행하십시오. 나는 그것이 더 짧을 것이라고 생각합니다. 또한 return[x...와는 반대로 할 수 있습니다 return [x.... 동일 permutations(a) if할 수도 있습니다 permutations(a)if.
0WJYxW9FMN

lambda a: [x for x in __import__("itertools").permutations(a) if x==tuple(sorted(a))][0]88 바이트
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

파이썬 (69 자)

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

숫자 순서대로 정수를 정렬합니다. 재귀 솔루션은 다음과 같습니다.

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

파이썬은 꼬리 호출 최적화를 수행하지 않기 때문에 작은 입력 (예 : N> 5)에 대한 스택 오버플로로 인해 실패합니다.


2

맞춤 비교기가없는 D : 59 자

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

더보기 :

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

    return r;
}

사용자 지정 비교기가있는 D : 69 자

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

더보기 :

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

    return r;
}

2

스칼라 73 :

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

스칼라에서는 컴파일러가 테일 콜 최적화를 수행했는지 확인할 수 있습니다.

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

그리고 그렇습니다. 그러나 100 개 값의 짧은 목록의 경우 :

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

완료하는 데 거의 4 개월이 걸렸습니다. ;)


2

C # (184 자)

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();}

C #에서이 작업을 수행하는 것은 좋지 않습니다. 값과 참조 유형을 모두 지원하려면 제네릭을 지원해야합니다. 정렬 순서를 확인하는 배열 셔플 기능이 없습니다.

아무도 이것을 개선하기위한 팁을 얻었습니까?

int 만 정렬하는 버전 편집 (134 자) :

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 / 바시 65

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

흠, bash 함수가 문자 그대로 부호없는 바이트 만 반환 할 수 있기 때문에 배열 규칙을 반환 하는 데 특별한 예외가 생길 수 있습니까?
kojiro

2

C ++ 11, 150 자

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

그냥 .. 재미있게 만들었습니다.


1
std :: random_shuffle이 일정하지 않습니다. 설명에서 "또한 셔플 링은 균일해야합니다"
STDQ

알았어 ... 나는 그것이 균일하지 않다는 것을 몰랐다.

균일하지 않은 rand ()에 의존합니다 ( open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3924.pdf 참조) . 다른 많은 사람들이 따르지 않는 것 같습니다. 그래서 나는 그것이 큰 문제가 아니라고 생각합니다.
STDQ 2016

따라서 srand (time (0)) 사용과 같이 완전히 임의의 것을 사용하면 계산됩니까?

문제는 rand가 균일 성뿐만 아니라 난수의 좋은 품질을 보장하지 않는다는 것입니다. 나는 그것이 결국 중요하지 않다고 생각합니다. std :: shuffle 등의 균일 한 배포자를 사용하면 8 바이트가 더 필요합니다.
STDQ

2

파이썬-61 자

재귀

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

함수는 배열이 아닌 True 또는 False를 반환합니다.
hallvabo

2
또한 작은 입력의 경우에도 재귀 솔루션이 실패 할 수 있습니다.
hallvabo

1
@ hallvabo : 실제로 Scheme에서 꼬리 재귀 솔루션을 작성하고 싶습니다. 물론 스택을 고갈시키지 않습니다.
Chris Jester-Young

@hallvabo, Alexandru는 이미 명백한 Python 솔루션을 수행 했으므로 여기서 다른 것을 시도했습니다. 물론 재귀 솔루션은 재미를위한 것이며 심각한 경쟁자가 아닙니다
gnibbler

from random import*더 짧을 수도 있습니다.
0WJYxW9FMN

2

PowerShell , 85 82 56 55 52 바이트

mazzy의 제안 덕분에 -26 바이트 AdmBorkBork 덕분에
-1 바이트
-3 바이트

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

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

PowerShell은 문자열을 캐스팅하고 비교하여 비교적 저렴한 배열 비교를 제공합니다.


2
param초기화를 초기화로 이동하여 for바이트를 절약 하십시오.for($l=$args;
AdmBorkBork

1
좋은. -ne오른쪽 연산자를 스칼라 유형의 왼쪽 연산자로 캐스팅합니다. 따라서 몇 바이트를 절약 할 수 있습니다. 온라인으로 사용해보십시오!
17:07에 mazzy

1

자바 스크립트 291 자

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}

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

내가 전에 말한 느낌이 있지만 모든 vars를 제거 할 수 있습니다 . 그것들을 모두 암시 적 전역으로 만들면 가능한 한 코드를 짧게 만드는 것입니다.
gcampbell

1

Matlab, 59 바이트

비교적 직접적인 접근 방식 :

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

1

J, 22 바이트

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

이것은 의제를 사용하는 재귀적이고 암묵적인 모나드입니다. 작동 방식은 다음과 같습니다.

y우리의 목록으로 보자 . 우선, 의제 오른쪽에있는 동사는 -:/:~입니다. Leaky Nun이 은혜롭게 제공하는 동사 입니다. 모나 딕 후크를 사용하여 -:입력이 정렬되는지 ( ) 여부 와 일치합니다 ( ) /:~. ( (f g) y = y f (g y)) 이에 따라 1 또는 0을 반환합니다. 아젠다의 왼쪽은 두 동사로 구성됩니다. 오른쪽은 신원 동사 ]이고 왼쪽은 재귀가 발생하는 곳입니다. 아젠다는 1목록 정렬 된 경우 위치에서 ID 동사를 선택 하고 목록 정렬 되지 않은0 경우 위치에서 더 긴 동사를 선택 합니다.

$:@({~?~@#)on $:의 결과 위에 호출 (포함 된 가장 긴 동사) . 의 길이에 대한 순열을 취하여 임의로 정렬 된 지수 인 목록을 섞습니다 . 모나 딕 후크에서 인덱스가 올바른 인수 인 목록을 반환합니다 . 그런 다음이 순서 섞은 목록은 의제와 함께 다시 호출되고 정렬 될 때까지 반복됩니다.{~?~@#y?~@#yy{~y


1

C ++ 14, 158 바이트

#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

젤리 , 6 바이트, 언어 날짜 도전 과제

ẊŒ¿’$¿

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

설명

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

Œ¿리스트의 각 순열에 숫자를 할당합니다. 1은 정렬되고 2는 마지막 두 요소 등이 목록 길이 (역순 목록)의 계승까지 교환됩니다. 따라서 정렬 된 목록의 경우 값이 1이며 while 루프 조건에서 부울로 사용할 수있는 "정렬되지 않은"테스트를 생성하기 위해 값을 줄일 수 있습니다 . 는 $조건이 그룹으로 구문 분석하는 원인이다.


1

Brachylog (v2), 5 바이트, 언어 게시 날짜 문제

≤₁|ṣ↰

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

기능 제출. TIO 링크는 함수를 전체 프로그램으로 자동 래핑하는 명령 줄 인수를 사용합니다.

설명

≤₁|ṣ↰
≤₁      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}

프롤로그 (Brachylog가 컴파일하는 언어)는 꼬리 재귀이므로이 함수는 엄격한 루프로 컴파일됩니다.


1

C ++, 166 바이트

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

이 모두 STL 컨테이너에서 작동해야 begin()하고 end().

언 골프 드 :

#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 바이트

∈&ṣ≤₁

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

내가 ais523의 Brachylog 답변을 처음 보았을 때 (그의 젤리 답변과 달리, 사용자 62131도 그를 잘못 생각하지 않았기 때문에) 재귀 대신 역 추적을 사용하면 어떨까요? 그래서 처음에는 시도했습니다 ṣ≤₁. 무작위로 무언가를 선택해도 결정적으로 하나의 출력을 생성하기 때문에 여러 출력을 생성하지 않기 때문에 셔플 술어 를 역 추적 할 수 없으므로 올바르게 셔플 할 수 없다면 운이 좋으면 실행이 실패합니다 첫 번째 시도에서. 그 후, 나는 pṣ≤₁대부분의 시간 동안 일한을 시도했지만 유한하게 긴 목록에는 무한한 순열이 있기 때문에 때로는 무작위로 실패했습니다. 길이 단축이라는 목표를 포기한 후 마침내 나는 이것을 생각해 냈습니다.

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

(임의의 데모)

비록 우리가 I / O로 자유를 얻는다면 실제로는 조금 더 짧을 수 있지만 ...

Brachylog , 4 바이트

⊆ṣ≤₁

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

출력을 유용하게하려면 입력을 정렬하는 것 외에도이 bogosort 술어는 임의의 수의 중복 요소와 0을 추가하므로 입력에 중복 요소가 없어야합니다. (가설 적으로, 그것은 무엇이든 추가 할 수는 있지만, 전혀 그렇지 않습니다.) 일반적으로 나는 제대로 작동하지 않는 것을 언급하지는 않지만 도전의 정신에 있다고 느낍니다.

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

1

펄 6 , 28 바이트

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

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

정렬 될 때까지 목록을 섞는 익명의 코드 블록입니다. 목록을 한 번 이상 정렬하면 허용됩니다. 그리고 아니요, {.pick(*)}로 대체 할 수 없습니다*.pick(*)


1

Pyth , 11 바이트

Wn=Q.SQSQ;Q

이것에 꽤 만족합니다. 아마도 조금 더 골프를 칠 수 있습니다.

설명


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

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


1

Japt , 11 9 바이트

_eZñ}a@öx

시도 해봐

_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

0

C (203 자, 입력 루프 없음 : 기능 만)

#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);}

이것은 stdin에서 배열을 읽고 정렬 된 배열을 작성하는 다음과 같습니다. Q가 전체 프로그램이 아닌 기능을 요청했기 때문에 ...

C (296 자)

#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]);}}

컴파일하면 경고가 발생할 수 있습니다 (암시 적 선언). 999 개의 요소로 강화 된 배열 크기 제한. 깨지기 쉬운.

배열이 정렬되어 있는지 미리 확인할 필요가 없으면 284에서 수행 할 수 있습니다.

C (251 자, 284 자)

#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]);}}

(함수 인수 대신 전역을 사용).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.