Classificação para Bozos

8

Introdução

Esse desafio é sobre três (ruins) algoritmos de classificação:, Bogosorte duas outras variantes que eu Bogoswapcriei (mas provavelmente já foram consideradas por outras pessoas em algum momento): (AKA Bozosort) e Bogosmart.

Bogosortfunciona embaralhando completamente a matriz aleatoriamente e verificando se ela é classificada (crescente). Caso contrário, repita.

Bogoswapfunciona selecionando dois elementos aleatoriamente e trocando-os. Repita até classificar (crescente).

Bogosmartfunciona selecionando dois elementos, aleatoriamente, e apenas trocando-os se aproximar a matriz da ordem (ascendente), ie. se o elemento com o índice mais baixo era originalmente maior que o elemento com o mais alto. Repita até classificar.

O desafio

Esse desafio explora a eficiência (ou falta de) de cada um desses três algoritmos de classificação. O código golfado será

  1. gere uma matriz embaralhada de 8 elementos dos números inteiros 1-8 inclusive (continue lendo para ver como você deve fazer isso);

  2. aplique cada algoritmo a essa matriz; e

  3. exibir a matriz original, seguida pelo número de cálculos necessários para cada algoritmo, separados por um espaço (espaço à direita ok), no formato <ARRAY> <BOGOSORT> <BOGOSWAP> <BOGOSMART>.

O programa produzirá 10 casos de teste; você pode gerar todos os dez no começo ou um de cada vez, qualquer que seja. Exemplo de saída abaixo.

Detalhes:

Pois Bogosort, ele deve registrar o número de vezes que a matriz foi embaralhada.

Pois Bogoswap, deve registrar o número de swaps realizados.

Pois Bogosmart, deve registrar o número de swaps realizados.

Exemplo de saída:

87654321 1000000 100 1
37485612 9050000 9000 10
12345678 0 0 0 
28746351 4344 5009 5
18437256 10000 523 25
15438762 10000 223 34
18763524 58924 23524 5
34652817 9283 21 445
78634512 5748 234 13
24567351 577 24 34

Eu inventei esses números; é claro, seu programa imprimirá resultados diferentes, mas no mesmo formato.

Regras

  • Toda aleatoriedade usada no seu programa deve vir de geradores de números pseudoaleatórios disponíveis para você e, caso contrário, não serão computados extensivamente por você. Você não precisa se preocupar com sementes.
  • Não há limite de tempo para os programas.
  • As matrizes devem ser classificadas de forma crescente.
  • Trailing espaços ou uma nova linha extra não é grande coisa.
  • Pois Bogosort, o array deve ser embaralhado usando qualquer algoritmo de embaralhamento imparcial, como Fisher-Yates ou Knuth Shuffling , explicitamente especificado em sua explicação. Métodos de embaralhamento internos não são permitidos. Gere suas matrizes de teste da mesma maneira.
  • Se depois de embaralhar ou trocar a matriz permanecer a mesma, ela ainda conta e deve ser incluída na contagem do programa. Por exemplo, embaralhar a matriz para si mesma por coincidência conta como uma ordem aleatória, e trocar um elemento consigo conta como uma troca, mesmo que nenhuma dessas operações altere a matriz.
  • Se minha memória me servir corretamente, uma matriz de 8 elementos não deve demorar muito para nenhum dos três algoritmos. Na verdade, acho que algumas vezes para uma matriz de 10 elementos, quando tentei, Bogoswapexigiu apenas alguns milhares (ou menos) de shuffles reais e bem menos de 10 segundos.
  • Seu código deve realmente classificar as matrizes, não apenas fornecer valores esperados ou cálculos matemáticos para uma resposta esperada.
  • Este é um desafio do código-golfe, pelo que vence o programa mais curto em bytes.

Aqui estão algumas etapas de exemplo para cada algoritmo de classificação:

BOGOSORT
56781234
37485612
28471653
46758123
46758123
12685734
27836451
12345678

BOGOSWAP
56781234
16785234
17685234
12685734
12685743
12685734
12485763
12385764
12385764
12345768
12345678

BOGOSMART
56781234
16785234
12785634
12785364
12785364
12385764
12385674
12345678

Nesse caso, o programa produziria 56781234 7 10 7e, em seguida, faria a mesma coisa 10 vezes. Você não precisa imprimir as matrizes durante a classificação, mas forneci as etapas de amostra acima para que você possa entender como cada algoritmo funciona e como contar os cálculos.

Faraz Masroor
fonte
2
Existem 8! = 40.320 pedidos possíveis para uma matriz de 8 elementos. Minha matemática não é boa o suficiente para traduzir isso no número esperado (médio) de etapas do bogosort. Mas, intuitivamente, deve estar pelo menos dentro de uma ordem de magnitude desse número. Minha teoria é que o bogosort e o bogoswap exigirão o mesmo número médio de etapas. Somente essa etapa do bogoswap é mais barata, portanto o tempo será menor.
Reto Koradi 4/15
Já fiz isso antes e, acredite, você ficará surpreso com a diferença entre seus pensamentos e a realidade. Você verá que, não surpreendentemente, o Bogosort tem o maior número de computações, então surpreendentemente o Bogoswap tem um menor e, é claro, o Bogosmart leva ainda menos. Você também será surpreendido pela forma como cálculos poucos bogosort precisa, bem abaixo 40320.
Faraz Masroor
Em suma, não espero que esse desafio arruine seu computador ou inundar sua memória.
Faraz Masroor
2
Relacionado. (Para o embaralhamento e bogosort parte.)
Martin Ender
Podemos apenas gerar o número de etapas da distribuição matematicamente correta sem fazer a classificação?
xnor

Respostas:

3

Pitão, 62 60 bytes

VTjd[jkKJ=boO0=ZS8fqZ=KoO0K0fqZ=XJO.CJ2)0fqZ=Xb*>F=NO.Cb2N)0

Isso foi bem divertido. Não tenho certeza se isso é válido, provavelmente estou usando algumas brechas não escritas.

Uma saída de amostra seria:

23187456 22604 23251 110
42561378 125642 115505 105
62715843 10448 35799 69
72645183 7554 53439 30
61357428 66265 6568 77
62348571 1997 105762 171
78345162 96931 88866 241
17385246 51703 7880 80
74136582 36925 19875 100
26381475 83126 2432 25

Explicação:

Minha função de reprodução aleatória usa a função incorporada order-by. Basicamente, atribuo a cada elemento da lista um número aleatório do intervalo [0-1)e ordeno a lista por eles. Isso me dá uma aleatória aleatória imparcial.

Laço externo

O VTno início repete o seguinte código 10 vezes.

Preparação

jkKJ=boO0=ZS8
           S8        create the list [1, 2, 3, 4, 5, 6, 7, 8]
         =Z          and store in Z
      oO0            shuffle
    =b               and store in b
   J                 and store in J
  K                  and store in K (3 copies of the same shuffled array)
jkK                  join K with ""

Bogosort

fqZ=KoO0K0 
     oO0K            shuffle K
   =K                and store the result in K
f        0           repeat ^ until:
 qZ K                  Z == K
                     and give the number of repeats

Bogoswap

fqZ=XJO.CJ2)0  
       .CJ2          give all possible pairs of elements of J
      O              take a random one
    XJ     )         swap these two elements in J
   =                 and store the result in J
f           0        repeat ^ until:
 qZ K                  Z == K
                     and give the number of repeats

Bogosmart

fqZ=Xb*>F=NO.Cb2N)0
            .Cb2     give all possible pairs of elements of b
           O         take a random one
         =N          assign it to N
       >F N          check if N[0] > N[1]
      *         N    multiply the boolean with N
    Xb           )   swap the two (or zero) values in b
   =                 and assign to b
f                 0  repeat ^ until:
 qZ                    Z == b
                     and give the number of repeats

Impressão

jd[
  [                  put all 4 values in a list
jd                    join by spaces and print
Jakube
fonte
=JXJO.cJ2)é o mesmo que =XJO.cJ2)atribuição aumentada. O mesmo vale para =bXbmais tarde. Além disso, acho swaps são supostamente é suposto ter os pares escolhidos com substituição ( .C)
isaacg
@isaacg Obrigado, corrigiu as coisas. Não tenho certeza se é permitido .cou .Cnão. Por exemplo .C[3 1 2)2, não retorna o par [2, 1]. Que é uma propriedade que estou explorando no meu algoritmo.
Jakube 4/15
talvez *JJentão? É também um personagem mais curto, o que é legal.
Isaacg
2

JavaScript ( ES6 ), 319 345

Sem surpresa, isso é bastante longo.

Para aleatório aleatório, créditos para @ core1024 (melhor que o meu para o mesmo chellenge)

Teste a execução do snippet (Firefox apenas como de costume)

// FOR TEST : redefine console
var console = { log: (...p)=>O.innerHTML += p.join(' ')+'\n' }
// END 

// Solution
R=n=>Math.random()*n|0, 
S=a=>(a.map((c,i)=>(a[i]=a[j=R(++i)],a[j]=c)),a), // shuffle
T=f=>{for(a=[...z];a.join('')!=s;)f(a)}, // apply sort 'f'  algorithm until sorted

s='12345678';
for(i=0;i<10;i++)
  z=S([...s]),
  n=l=m=0,
  T(a=>S(a,++n)),
  T(a=>(t=a[k=R(8)],a[k]=a[j=R(8)],a[j]=t,++m)),
  T(a=>(t=a[k=R(8)],u=a[j=R(8)],(t<u?j<k:k<j)&&(a[k]=u,a[j]=t,++l))),
  console.log(z.join(''),n,m,l)
<pre id=O></pre>

edc65
fonte
O link "Executar trecho de código" não funciona para mim. Não tenho certeza se é o meu navegador / sistema, mas os links dos trechos funcionaram para mim no passado.
Reto Koradi 4/15
Mesmo, o trecho de código não funciona no meu navegador
Faraz Masroor
2
@Reto e outros EcmaScript 6: execute apenas no Firefox.
edc65 4/06/15