introduction
Supposons que l'on vous remette une permutation aléatoire d' n
objets. La permutation est scellée dans une boîte, vous n'avez donc aucune idée de celle qui est n!
possible. Si vous parveniez à appliquer la permutation à n
des objets distincts, vous pourriez immédiatement en déduire son identité. Cependant, vous n'êtes autorisé à appliquer la permutation qu'aux n
vecteurs binaires de longueur , ce qui signifie que vous devrez l'appliquer plusieurs fois pour la reconnaître. Clairement, l'appliquer aux n
vecteurs avec un seul 1
fait le travail, mais si vous êtes intelligent, vous pouvez le faire avec des log(n)
applications. Le code de cette méthode sera cependant plus long ...
Il s'agit d'un défi expérimental où votre score est une combinaison de longueur de code et de complexité de requête , c'est-à-dire le nombre d'appels à une procédure auxiliaire. La spécification est un peu longue, alors restez avec moi.
La tâche
Votre tâche consiste à écrire une fonction nommée (ou son équivalent le plus proche) f
qui prend en entrée un entier positif n
et une permutation p
des premiers n
entiers, en utilisant une indexation basée sur 0 ou 1. Sa sortie est la permutation p
. Cependant, vous n'êtes pas autorisé à accéder p
directement à la permutation . La seule chose que vous pouvez en faire est de l'appliquer à n'importe quel vecteur de n
bits. À cet effet, vous devez utiliser une fonction auxiliaire P
qui prend une permutation p
et un vecteur de bits v
, et renvoie le vecteur permuté dont p[i]
la coordonnée e contient le bit v[i]
. Par exemple:
P([1,2,3,4,0], [1,1,0,0,0]) == [0,1,1,0,0]
Vous pouvez remplacer les "bits" par deux valeurs distinctes, telles que 3
et -4
, ou 'a'
et 'b'
, et elles n'ont pas besoin d'être fixées, vous pouvez donc appeler P
avec les deux [-4,3,3,-4]
et [2,2,2,1]
dans le même appel à f
. La définition de P
n'est pas prise en compte dans votre score.
Notation
La complexité de la requête de votre solution sur une entrée donnée est le nombre d'appels qu'elle fait à la fonction auxiliaire P
. Pour rendre cette mesure sans ambiguïté, votre solution doit être déterministe. Vous pouvez utiliser des nombres générés de manière pseudo-aléatoire, mais vous devez également corriger une graine initiale pour le générateur.
Dans ce référentiel, vous trouverez un fichier appelé permutations.txt
qui contient 505 permutations, 5 de chaque longueur entre 50 et 150 inclus, en utilisant une indexation basée sur 0 (incrémentez chaque nombre dans le cas basé sur 1). Chaque permutation est sur sa propre ligne et ses nombres sont séparés par des espaces. Votre score est un nombre d'octets de f
+ complexité de requête moyenne sur ces entrées . Le score le plus bas l'emporte.
Règles supplémentaires
Un code avec des explications est préférable et les failles standard ne sont pas autorisées. En particulier, les bits individuels sont indiscernables (vous ne pouvez donc pas donner un vecteur d' Integer
objets à P
et comparer leurs identités), et la fonction P
renvoie toujours un nouveau vecteur au lieu de réorganiser son entrée. Vous pouvez modifier librement les noms de f
et P
, et l'ordre dans lequel ils prennent leurs arguments.
Si vous êtes la première personne à répondre dans votre langage de programmation, vous êtes fortement encouragé à inclure un harnais de test, y compris une implémentation de la fonction P
qui compte également le nombre de fois où elle a été appelée. À titre d'exemple, voici le harnais pour Python 3.
def f(n,p):
pass # Your submission goes here
num_calls = 0
def P(permutation, bit_vector):
global num_calls
num_calls += 1
permuted_vector = [0]*len(bit_vector)
for i in range(len(bit_vector)):
permuted_vector[permutation[i]] = bit_vector[i]
return permuted_vector
num_lines = 0
file_stream = open("permutations.txt")
for line in file_stream:
num_lines += 1
perm = [int(n) for n in line.split()]
guess = f(len(perm), perm)
if guess != perm:
print("Wrong output\n %s\n given for input\n %s"%(str(guess), str(perm)))
break
else:
print("Done. Average query complexity: %g"%(num_calls/num_lines,))
file_stream.close()
Dans certaines langues, il est impossible d'écrire un tel harnais. Plus particulièrement, Haskell ne permet pas à la fonction pure P
d'enregistrer le nombre de fois où elle est appelée. Pour cette raison, vous êtes autorisé à réimplémenter votre solution de manière à ce qu'elle calcule également la complexité de sa requête et à l'utiliser dans le faisceau.
abaaabababaa
et-4 3 3 3 -4 3
serait un vecteur de bits.