Aqui está um padrão bastante comum para ordenar algoritmos:
def sort(l):
while not is_sorted(l):
choose indices i, j
assert i < j
if l[i] > l[j]:
l[i], l[j] = l[j], l[i]
Esses algoritmos funcionam bem porque os índices i
e j
são escolhidos com cuidado, com base no estado da lista l
.
No entanto, e se não pudéssemos ver l
, e apenas tivéssemos que escolher cegamente? Quão rápido poderíamos classificar a lista então?
Seu desafio é escrever uma função que produza um par aleatório de índices, considerando apenas o comprimento de l
. Especificamente, você deve gerar dois índices,, i, j
com 0 <= i < j < len(l)
. Sua função deve funcionar em qualquer comprimento da lista, mas será pontuada em uma lista de comprimento 100.
Sua pontuação é o número médio de opções de índice necessárias para classificar uma lista aleatoriamente aleatória e uniforme de acordo com o padrão acima, onde os índices são escolhidos de acordo com a sua função.
Eu pontuarei as submissões, considerando o número médio de opções de índice em mais de 1000 tentativas, em uma lista aleatoriamente aleatória e aleatória, de tamanho 100, sem entradas repetidas.
Reservo-me o direito de executar menos testes se a inscrição for claramente não competitiva ou não terminar, e executarei mais testes para diferenciar os principais concorrentes e encontrar um único vencedor. Se vários envios principais permanecerem dentro da margem de erro no limite de meus recursos computacionais, declararei o envio anterior como vencedor, até que outros recursos computacionais possam ser utilizados.
Aqui está um exemplo de programa de pontuação, em Python:
import random
def is_sorted(l):
for x in range(len(l)-1):
if l[x] > l[x+1]:
return False
return True
def score(length, index_chooser):
steps = 0
l = list(range(length))
random.shuffle(l)
while not is_sorted(l):
i, j = index_chooser(length)
assert (i < j)
if l[i] > l[j]:
l[i], l[j] = l[j], l[i]
steps += 1
return steps
Sua função pode não manter nenhum estado mutável, interagir com variáveis globais, afetar a lista l
, etc. A única entrada da sua função deve ser o comprimento da lista l
e deve gerar um par ordenado de números inteiros no intervalo [0, len(l)-1]
(ou apropriado para o idioma). indexação de lista). Fique à vontade para perguntar se algo é permitido nos comentários.
Os envios podem estar em qualquer idioma de uso gratuito. Inclua um equipamento de pontuação, se ainda não tiver sido publicado no seu idioma. Você pode postar uma pontuação provisória, mas vou deixar um comentário com a pontuação oficial.
A pontuação é o número médio de etapas para uma lista classificada em uma lista aleatoriamente aleatória e aleatória, de comprimento 100. Boa sorte.
fonte
Respostas:
Python, pontuação = 4508
Half-Life 3 confirmado.
Python, pontuação = 11009
Aparentemente, uma classificação aleatória de bolhas não é muito pior do que uma classificação normal de bolhas.
Distribuições ideais para pequenos comprimentos
Não há como isso estender para o comprimento 100, mas é interessante olhar de qualquer maneira. Calculei distribuições ótimas para casos pequenos (comprimento ≤ 7) usando descida gradiente e muita álgebra matricial. A coluna k mostra a probabilidade de cada troca na distância k .
fonte
h
é a distância entre os elementos trocados; não representa a frente nem as costas.Pontuação: 4627
Experimente online!
Gera índices aleatórios cuja distância é escolhida uniformemente
[1,1,4,16]
. A idéia é ter uma mistura de swaps de uma etapa com swaps em escalas maiores.Ajustei manualmente esses valores para listas de comprimento 100, e eles provavelmente estão longe de ser o ideal. Algumas pesquisas de máquinas provavelmente poderiam otimizar a distribuição por distâncias para a estratégia de par aleatório com distância escolhida.
fonte
Pontuação: 28493
Experimente online!
Essa solução apenas seleciona valores distintos para
x
ey
aleatoriamente do intervalo e os retorna na ordem de classificação. Tanto quanto eu posso dizer, isso tem um desempenho melhor do que escolher ex
depois escolhery
entre os valores restantes.fonte
Python, pontuação: 39525
Experimente online.
fonte
Python, pontuação ≈ 5000
Tentado com um monte de valores epsilon, 0,25 parece ser o melhor.
Pontuação ≈ 8881
Uma abordagem diferente. Não é tão bom e morre horrivelmente com o comprimento não divisível pelo número de segmentos, mas ainda assim divertido de construir.
fonte
Pontuação: 4583
Experimente online!
Não faço ideia do porquê. Eu apenas tentei seqüências listadas na wikipedia artical para shellsort . E este parece funcionar melhor. Ele obtém pontuação semelhante à do xnor publicado .
fonte
candidates
sair da função como variável global deve funcionar.Python 2 , 4871
Experimente online!
fonte