introduction
Les permutations lexicographiques d'une liste à n éléments peuvent être numérotées de 0 à n ! - 1. Par exemple, le 3! = 6 permutations (1,2,3)
seraient (1,2,3)
, (1,3,2)
, (2,1,3)
, (2,3,1)
, (3,1,2)
, (3,2,1)
.
Lorsqu'une permutation est appliquée à une liste, ses éléments sont ordonnés dans le même ordre que les nombres dans la permutation. Par exemple, appliquer la permutation (2,3,1)
aux l = (a,b,c)
rendements (l[2],l[3],l[1]) = (b,c,a)
.
L'inverse d'une permutation est défini comme la permutation qui inverse cette opération, c'est-à-dire que l'application d'une permutation et que son inverse (ou vice versa) ne modifie pas le tableau. Par exemple, l'inverse de (2,3,1)
est (3,1,2)
, car cela s'applique aux (b,c,a)
rendements (a,b,c)
.
De plus, l'inverse d'une permutation appliquée à la permutation elle-même donne les entiers 1… n . Par exemple, appliquer (3,1,2)
aux (2,3,1)
rendements (1,2,3)
.
Nous définissons maintenant la fonction revind ( x ) comme l'indice de la permutation inverse de la permutation d'indice x . (Ceci est A056019 , si vous êtes intéressé.)
Puisqu'une permutation d'indice i ne modifie que les k derniers éléments de la liste si sf 0 ≤ i < k !, Nous pouvons ajouter un nombre quelconque d'éléments au début de la liste sans affecter revind ( i ). Par conséquent, la longueur de la liste n'affecte pas le résultat.
Défi
Votre tâche consiste à implémenter revind ( x ). Vous écrirez un programme ou une fonction complète qui prend un seul entier non négatif x comme entrée / argument et génère / renvoie le résultat comme un seul entier non négatif.
L'entrée et la sortie peuvent être indexées 0 ou indexées 1, mais cela doit être cohérent entre elles.
Les builtins qui génèrent des permutations par index, renvoient l'index d'une permutation ou trouvent la permutation inverse sont interdits. (Les Builtins qui génèrent toutes les permutations ou la permutation suivante sont autorisés.)
Les règles de code-golf standard s'appliquent.
Exemples
Les exemples ci-dessous sont indexés 0.
Input Output
0 0
1 1
2 2
3 4
4 3
5 5
6 6
13 10
42 51
100 41
1000 3628
2000 3974
10000 30593
100000 303016
Implémentation de référence (Python 3)
def revind(n):
from math import factorial
from itertools import permutations, count
l = next(filter(lambda x: factorial(x) > n, count(1)))
pms = list(permutations(range(l)))
return [k for k in range(len(pms)) if tuple(pms[n][i] for i in pms[k]) == pms[0]][0]
la source
(a,b,c)
extrêmement peu clair. Veuillez inclure une explication appropriée de ce qu'est une permutation inverse.Ụ
(grade up) qui trie les indices d'un tableau par leurs valeurs correspondantes. Cela se produit pour inverser une permutation de 1,…, n , mais cela ne fonctionne pas pour les autres permutations. UnỤ
intégré est-il interdit?Réponses:
Gelée , 6 octets
Les E / S utilisent une indexation basée sur 1. Très lent et gourmand en mémoire.
Vérification
Tant que l'entrée ne dépasse pas 8! = 40320 , il suffit de considérer toutes les permutations du tableau [1,…, 8] . Pour le dernier cas de test, les permutations de [1,…, 9] suffisent.
Avec un code légèrement modifié qui ne prend en compte que les permutations des 8 ou 9 premiers entiers positifs, vous pouvez l' essayer en ligne! ou vérifiez tous les cas de test restants .
Comment ça fonctionne
Approche alternative, 6 octets (invalide)
Il est tout aussi long et utilise l' atome de qualité interdit
Ụ
, mais il est (sans doute) plus idiomatique.En ajoutant 8 (ou 9 pour le dernier cas de test), nous pouvons réellement l' essayer en ligne!
Comment ça fonctionne
la source
Mathematica, 74 octets
Utilise l'indexation 1. Très inefficace. (utilise ~ 11 Go de mémoire lorsque l'entrée est
11
)Explication
Générez une liste de 1 à N. Enregistrez-la dans
j
.Trouvez toutes les permutations de
j
. Conservez-le dansi
.Enregistrez la
Position
fonction dansk
. (pour réduire le nombre d'octets lors d'unePosition
nouvelle utilisation )Trouvez la permutation inverse de la N-ème permutation.
Trouvez le
k
(Position
) de la permutation inverse dansi
(toutes les permutations)À l'aide de intégrés,
4643 octets1 indexé.
la source
MATL , 15 octets
L'entrée et la sortie sont basées sur 1.
Similaire à la réponse CJam de @ MartinEnder , mais trouve la permutation inverse en composant toutes les permutations possibles avec celle spécifiée par l'entrée, et en voyant qui est devenue la permutation d'identité.
Il manque de mémoire dans le compilateur en ligne pour l'entrée
10
.Essayez-le en ligne!
Explication
la source
Pyth, 12 octets
Suite de tests
0 indexé.
Explication:
la source
05AB1E ,
1413 octetsMémoire très inefficace.Désormais encore plus de mémoire inefficace (mais 1 octet plus court).Plage basée sur 0.
Utilise l' encodage CP-1252 .
Essayez-le en ligne! ou en tant que suite de tests modifiée
Explication
la source
CJam , 16 octets
Les indices sont basés sur 0.
Essayez-le en ligne!
Je n'obtiens pas beaucoup plus inefficace que cela ... manque de mémoire avec les paramètres par défaut de Java pour les entrées supérieures à
8
(mais fonctionne en principe pour les entrées arbitraires étant donné un nombre suffisant d'univers de temps et de mémoire).Explication
la source
GAP , 108 octets
1 indexé. Les sauts de ligne ne sont pas comptés, ils ne sont pas nécessaires. Je n'ai pas vraiment besoin d'assigner la fonction finale à un nom, mais ...
h
est une fonction curry prenant une liste de permutations et un index dans cette liste et retournant l'indice de permutation inverse. Sans restrictions, je ferais justePosition(l,l[n]^-1)
.f
appelle cette fonction avec les permutations triées d'un groupe symétrique suffisamment grand et le donnén
.Je pourrais simplement écrire
SymmetricGroup(n)
, puis la fonction pourrait être calculée pour des valeurs allant jusqu'à 9. Puisqu'il existe déjà des solutions beaucoup plus petites, je préfère pouvoir faire ceci:Une solution indexée 0 vraiment efficace qui fonctionne pour des arguments inférieurs à 99! (et peut fonctionner pour des arguments inférieurs à 999! au prix d'un octet) est celui-ci:
Après avoir supprimé les espaces, cela a 255 octets.
la source
JavaScript (ES6),
163120110 octets0 indexé. Fonctionne en convertissant l'index en permutation, en l'inversant, puis en reconvertissant en index. Edit: économisé environ 25% en
f
inversant et inversant la permutation, puis eng
convertissant la permutation inversée en index. 10 octets supplémentaires enregistrés en combinant les deux appels récursifs en une seule fonction. Non golfé:la source
f
à inverser la permutation au lieu deg
...J,
5550 octetsBasé sur l'essai J sur l' indice de permutation .
Ce code ne nécessite que de la mémoire de l'ordre de
n
mais utilise plus de temps car il trie lesn
temps de liste et recherche lesn
temps pour chaque index.En utilisant la fonction intégrée
/:
qui est capable de trouver le grade d'une liste et l'inverse d'une permutation, il existe une solution de 42 octets plus efficace.Cette version ne nécessite que 44 secondes pour calculer le dernier cas de test par rapport à l'autre qui nécessite 105 secondes.
Usage
la source
Gelée ,
14 139 octets-4 octets grâce à @Dennis (qu'il a joué plus loin en utilisant le rapide
⁺
dans sa réponse )Une autre implémentation très lente.
L'indexation basée sur 1 est utilisée ici, donc les résultats attendus sont:
Inutile même de mettre en place un lien IDE en ligne, car TIO tue à une entrée de
10
. Résultats locaux (le dernier est très lent et a nécessité une tonne de mémoire!):Comment?
Remarque: pas besoin de trier les permutations car nous utilisons le même ordre pour trouver la permutation et l'inverse.
la source
ÇịịÇ$iR
?R
avantŒ!
est implicite, doncŒ!ịịŒ!$iR
devrait faire le travail.Python 2,
116114 octetsrepl.it
Basé sur 0. Lent et faim de mémoire mais peu d'octets.
Utiliser aucune fonction de permutation; à la fois mémoire et temps.
289285 octets-4 octets grâce à @Christian Sievers (permutation complète déjà formée)
Je sais que c'est du golf de code, mais je pense que @ Pietu1998 est également intéressé par des implémentations efficaces.
Voyez-le en action sur repl.it
Bien que cela utilise plus d'octets que l'implémentation de référence pour
n=5000000
:f
est la fonction d'index inverse.f
obtient d'abord la factorielle suivante cin
- dessus ,t
et l'entier dont la factorielle qui est,x
en appelanth(n)
, et définitg=range(x)
, les éléments qui constitueront la permutationo=g[:]
, et le titulaire de la permutation,r=[]
Ensuite, il construit la permutation à l'indice
n
enpop
ing les indices de la représentation de base factoriellen
à tour de rôle à partir des éléments,o
, et en les ajoutant àr
. La représentation de base factoriel se trouve par div et mod den
avect
oùt
est div'd parx
etx
décrémente jusqu'à1
.Enfin, il trouve l'indice de la permutation inverse en appelant
i
avec la permutation inverse,[r.index(v)for v in g]
h
est une fonction à double usage pour calculer une factorielle d'un entier non négatif ou pour calculer à la fois la factorielle suivante au-dessus d'un entier non négatif et l'entier qui rend cette factorielle.Dans son état par défaut
v=1
et il le fait en multipliantv
parx
(également initialement1
) et en incrémentantx
jusqu'à ce qu'iln
soit au moins aussi grand, puis il revientv
etx-1
dans un tuple.Pour calculer
n!
un appelh(n,0)
qui multipliex
(initialement1
) parn
et décroîtn
jusqu'àn
est0
quand il retournex
.i
fournit l'indice lexicographique d'une permutation,p
, des éléments[0,1,...n]
en additionnant les produits de la factoriel de la base factoriel de chaque indice,h(len(p)-j-1,0)
et le nombre d' éléments à droite de l'indice est inférieur à la valeur à cet indice,sum(k<p[j]for k in p[j+1:])
.la source
t/=x
.(r+o)
parr
.Python 2,
130129 octetsla source
En fait ,
1811 octetsCette réponse utilise l'algorithme de la réponse Jelly de Dennis mais est indexée sur 0. Suggestions de golf bienvenues! Essayez-le en ligne!
Ungolfing
la source