Neste desafio de otimização, você escreverá um programa que classifica uma única matriz comparando apenas os elementos, solicitando ao usuário no stdout que insira resultados de comparação no stdin.
O protocolo abaixo é baseado em linhas; portanto, toda vez que você imprime em stdout ou lê em stdin, assume-se uma nova linha. Ao longo da pergunta abaixo, supõe-se que o usuário (leia-se: o programa de pontuação) tenha uma matriz que deseja classificar em uma matriz indexada baseada em 0 chamada array
. Por razões técnicas, sugiro a descarga após cada impressão para ser robusta.
- Como seu primeiro passo, seu programa deve ler o tamanho
n
da matriz em stdin. - Então, quantas vezes quiser, você pode imprimir
a < b
em stdout, com dois números inteiros0 <= a, b < n
. Em seguida, o usuário entrará1
em stdin ifarray[a] < array[b]
e de0
outra forma. Finalmente, uma vez que seu programa está convencido de que deduziu corretamente a ordem da matriz, ele deve imprimir
a ...
em stdout, onde...
há uma lista separada por espaços de números inteiros indicando a ordem. Portanto, se o seu programa produzira 3 0 1 4 2
, significa que ele deduziuarray[3] <= array[0] <= array[1] <= array[4] <= array[2]
Observe que seu programa nunca conheceu o conteúdo
array
e nunca saberá.
Você só pode solicitar <
no stdin para classificar a matriz. Você pode obter outras operações de comparação por estas equivalências:
a > b b < a
a <= b !(b < a)
a >= b !(a < b)
a != b (a < b) || (b < a)
a == b !(a < b) && !(b < a)
Por fim, como seu programa interage com o programa de pontuação no stdout, imprima as informações de depuração no stderr.
Seu programa será pontuado usando o seguinte programa Python:
from __future__ import print_function
from subprocess import Popen, PIPE
import sys, random
def sort_test(size):
array = [random.randrange(0, size) for _ in range(size)]
pipe = Popen(sys.argv[1:], stdin=PIPE, stdout=PIPE, bufsize=0, universal_newlines=True)
print(str(size), file=pipe.stdin); pipe.stdin.flush()
num_comparisons = 0
while True:
args = pipe.stdout.readline().strip().split()
if args and args[0] == "a":
answer_array = [array[int(n)] for n in args[1:]]
if list(sorted(array)) != answer_array:
raise RuntimeError("incorrect sort for size {}, array was {}".format(size, array))
return num_comparisons
elif len(args) == 3 and args[1] == "<":
a, b = int(args[0]), int(args[2])
print(int(array[a] < array[b]), file=pipe.stdin); pipe.stdin.flush()
num_comparisons += 1
else:
raise RuntimeError("unknown command")
random.seed(0)
total = 0
for i in range(101):
num_comparisons = sort_test(i)
print(i, num_comparisons)
total += num_comparisons
print("total", total)
Você pontua seu programa digitando python score.py yourprogram
. A pontuação é feita com o programa ordenando uma matriz aleatória de cada tamanho de 0 a 100 e contando a quantidade de comparações solicitadas pelo programa. Essas matrizes aleatórias podem ter duplicatas , seu algoritmo deve ser capaz de lidar com elementos iguais. No caso de haver duplicatas, não há requisitos na ordem dos elementos iguais. Portanto, se a matriz estiver [0, 0]
, não importa se você produz a 0 1
ou a 1 0
.
Você não pode otimizar especificamente para as matrizes específicas que o programa de pontuação gera. Eu posso mudar a semente RNG a qualquer momento. É permitido que as respostas que utilizam algoritmos de classificação internos sejam publicadas por interesse, mas não sejam concorrentes.
Programa com menor pontuação ganha.
Respostas:
Python, pontuação 23069
Isso usa o algoritmo de classificação de inserção de mesclagem Ford-Johnson.
fonte
Pontuação do Python 3, 28462
Ordenação rápida. O pivô é o item mais à esquerda.
A pontuação é esperada, porque:
Pontuações para cada tamanho testado:
fonte
Python 2 (não concorrente), pontuação 23471
Pontuações para cada tamanho testado:
fonte
Pontuação do Python, 333300
Este é um programa de exemplo, implementando a forma mais simples de bolhas, sempre fazendo
n*(n-1)
comparações por matriz.Marquei este programa salvando-o como
sort.py
e digitandopython score.py python sort.py
.fonte
print
parecendo uma função.