Tri par insertion inverse


19

Objectif

Générez la liste brouillée d'origine, à partir des mouvements qu'un tri d'insertion ferait pour le trier. La liste d'origine aura tous les nombres de 0à N-1(inclus) où Nest la taille de l'entrée.

Contribution

Une liste contenant les mouvements nécessaires pour trier la liste. Chaque valeur représente le nombre d'emplacements déplacés par le numéro d'origine (brouillé) pour se trouver dans sa bonne position, gardez à l'esprit que ce processus se déroule de gauche à droite.
La valeur à la position (indexée 0) idans la liste d'entrée sera comprise entre 0et iinclusive.
Vous n'avez pas besoin de gérer des entrées invalides, tout comportement est acceptable dans ce cas (crash, boucle infinie, etc.).

Production

La liste brouillée

Pas à pas pour générer les mouvements

Scrambled List | Moves to sort
[4,0,2,1,3,5]  | [0, , , , , ] #4 stay in place
[4,0,2,1,3,5]  | [0,1, , , , ] #0 is moved 1 slot to the left
[0,4,2,1,3,5]  | [0,1,1, , , ] #2 is moved 1 slot
[0,2,4,1,3,5]  | [0,1,1,2, , ] #1 is moved 2 slot
[0,1,2,4,3,5]  | [0,1,1,2,1, ] #3 is moved 1 slot
[0,1,2,3,4,5]  | [0,1,1,2,1,0] #5 is in the right place already
[0,1,2,3,4,5]

Donc, pour l'entrée que [0,1,1,2,1,0]votre programme doit produire [4,0,2,1,3,5].
Gardez à l'esprit que les mouvements ne sont pas à la position dans la liste triée (finale), mais dans le segment trié (la section en gras)

Cas de test

[0,0,0] -> [0,1,2]
[0,1,0,1] -> [1,0,3,2]
[0,0,0,0,0,5] -> [1,2,3,4,5,0]
[0,1,2,3] -> [3,2,1,0]
[0,1,1,1] -> [3,0,1,2]
[0,1,1,2,1,0] -> [4,0,2,1,3,5]

Gagnant

C'est le , donc la réponse la plus courte l'emporte.

code-golf  array-manipulation  code-golf  code-golf  animation  code-golf  restricted-source  code-golf  java  code-golf  decision-problem  graph-theory  code-golf  conversion  electrical-engineering  code-golf  ascii-art  code-golf  string  substitution  code-golf  math  code-golf  string  set-theory  code-golf  code-golf  compile-time  code-golf  kolmogorov-complexity  binary  code-golf  sequence  cops-and-robbers  code-golf  subsequence  card-games  code-golf  sequence  primes  code-golf  code-golf  number  graphical-output  music  code-golf  ascii-art  code-golf  string  lambda-calculus  code-golf  string  code-generation  code-golf  unicode  code-golf  math  combinatorics  code-golf  balanced-string  code-golf  sequence  cops-and-robbers  code-golf  sequence  cops-and-robbers  code-challenge  fastest-code  chess  code-golf  math  graphical-output  code-golf  string  hello-world  animation  code-golf  number  arithmetic  code-golf  integer  code-golf  code-golf  combinatorics  code-golf  kolmogorov-complexity  graphical-output  code-golf  string  code-golf  code-golf  game  code-golf  math  combinatorics  code-golf  ascii-art  popularity-contest  random  code-golf  arithmetic  number-theory  integer  code-golf  tips  underload  code-golf  math  sequence  primes  code-golf  math  path-finding  code-golf  ascii-art  primes  code-golf  kolmogorov-complexity  alphabet 

1
Le programme peut-il également prendre la longueur de la liste en entrée?
mbomb007

@ mbomb007 non.
Rod

Pouvons-nous utiliser des étapes (n-1) à la place? Le premier est inutile, car il est toujours nul.
GB

@GB bien sûr, tant que la sortie est correcte, vous pouvez utiliser n'importe quel algorithme
Rod

Réponses:


14

Gelée , 12 octets

L!_UÆ¡$œ?J’U

Essayez-le en ligne!

Explication

Nous pouvons essentiellement voir les deux listes (l'entrée et la sortie) comme encodant un entier; l'entrée code un entier en base factorielle et la sortie code un entier en permutation. Heureusement, Jelly a des intrinsèques qui sont déjà très proches de ces deux encodages, il s'agit donc simplement d'écrire de petits morceaux de code à convertir en un entier, puis de revenir à l'autre encodage.

L!_UÆ¡$œ?J’U
   U           Reverse {the input}
    Æ¡         and convert from base factorial to integer;
  _   $        subtract that from
L!             the factorial of the length of {the input};
       œ?      then take the nth permutation of
         J     [1,2,...,l], where l is the length of {the input},
          ’    subtract 1 from every elevent,
           U   and reverse it

Dans le cas de la factorielle de base, on peut observer que le premier élément de la liste doit être 0, le second peut être 0 ou 1, le troisième doit être 0/1/2, etc. Ainsi, nous devons inverser l'entrée afin de placer ses éléments dans l'ordre d'écriture normal pour la conversion de base.

De plus, pour que les ordres relatifs de la conversion factorielle et de la conversion de permutation correspondent à l'opération utilisée par le tri par insertion, nous devons effectuer deux ajustements: inverser la séquence des permutations et inverser l'ordre de la liste de sortie. Inverser la liste de sortie est assez facile, ne nécessitant qu'un Uà la fin du programme. Pour inverser la séquence des permutations, nous soustrayons de la factorielle de la longueur d'entrée (cela fonctionne parce que la factorielle de base produit un nombre compris entre 0 et (longueur! -1), tandis que les permutations sont numérotées par Jelly de 1 à la longueur! , produisant un off-by-one implicite qui annule le off-by-one que vous obtenez normalement en soustrayant un indice de permutation d'une factorielle).

Jelly , 9 octets, en collaboration avec @JonathanAllan

UÆ¡Nœ?J’U

Cette version du programme est très similaire, mais utilise une méthode différente pour inverser la séquence des permutations; il suffit de nier l'entrée avec Npour faire œ?traiter l'ordre à l'envers. En dehors de cela, il fonctionne de manière identique au programme précédent.

Essayez-le en ligne!


4
O_O De quelle sorcellerie s'agit- il?
DLosc

Oh bien - je savais que mes atomes Æ¡et moi œ?fonctionneraient pour cela (j'avais déjà commencé à essayer de les utiliser pour ce défi plus tôt - j'étais si proche, j'avais juste besoin de ça L!).
Jonathan Allan

Excellent code!
Greg Martin

1
En fait, vous pouvez le faire en 9 octets avec UÆ¡Nœ?L’Uparce que j'ai implémenté œ?(et similaire) pour agir de manière modulaire (comme s'ils utilisaient des listes Jelly). Le Njuste indexe avec la valeur négative. Remarque: j'ai changé Jpour L- c'est simplement parce que, étant donné un certain nombre, cela fait une gamme sous le capot de toute façon).
Jonathan Allan

6

Mathematica, 92 octets

Permute[Range[l=Length@#]-1,(c=Cycles@{#}&)@{}©##&@@c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]&

Fonction pure prenant une liste d'entiers non négatifs en entrée et renvoyant une liste d'entiers non négatifs. Le code ci-dessus contient un ©, ce qui est incorrect: c'est un espace réservé pour le symbole à 3 octets U + F3DE, que Mathematica représente par un cercle avec un point dedans, et qui représente la composition des permutations.

c=Cycles@{#}&définit une fonction qui convertit une liste d'entiers en un Cyclesobjet représentant une permutation; par exemple, c[{3,4}]est la transposition des éléments d'échange 3 et 4 d'une liste. c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]prend la liste d'entrée et génère les permutations nécessaires pour annuler le tri par insertion. Ensuite, c@{}©##&@@compose toutes ces permutations ensemble, en commençant par la permutation d'identité c@{}. Enfin, Permute[Range[l=Length@#]-1,...]applique cette permutation à la liste indexée 0 de longueur appropriée.


1
Qu'est-ce pas intégré?! Sûrement ...
Jonathan Allan

3
@{#}&)@{}©##&@@est effrayant.
Yytsi

6

Python 2, 79 68 octets

Merci à Krazor pour avoir économisé 10 octets

Merci à TuukkaX pour avoir économisé 1 octet

a=input();b=range(len(a));print[b.pop(j-a[j])for j in b[::-1]][::-1]

Fonctionne en générant les mouvements à l'envers


2
Faites ça 66 ! Que diriez - vous: a=input();b=range(len(a));print[b.pop(j-a[j]) for j in b[::-1]][::-1]. Liste des compréhensions ftw!
FMaz

1
@Krazor Vous avez un espace qui pourrait être supprimé auparavant for, alors faites-en 65 je suppose: D
Yytsi

@Krazor Il s'avère que la compréhension de la liste n'a pas tout à fait fonctionné, mais j'ai aimé l'idée d'utiliser b [:: - 1]!
math junkie

En aucune façon? J'ai commenté avec le mobile, j'ai peut-être mal écrit quelque chose. Quelle partie ne fonctionne pas? Pour moi, il a interprété correctement et rempli tous les cas de test.
FMaz

@Krazor Oh whoops, non vous avez raison. Je suis celui qui l'a mal tapé lors des tests.
math junkie

5

JavaScript (ES6), 69 65 63 octets

a=>a.reverse(b=[...a.keys()]).map(o=>+b.splice(~o,1)).reverse()

De manière ennuyeuse, l'entrée et la sortie sont dans le mauvais ordre. Edit: 4 octets enregistrés grâce à @Arnauld. Enregistré 2 octets grâce à @ETHproductions.


J'essayais toujours de trouver un meilleur moyen mais tu étais beaucoup plus rapide. Joli!
Arnauld

1
Vous n'avez pas besoin i, n'est -ce pas?
Arnauld

@Arnauld Apparemment non. J'ai commencé par essayer de comprendre la réponse Python, et je viens juste de remarquer qu'elle n'utilise pas réellement i...
Neil

1
Easy -2:o=>+b.splice(~o,1)
ETHproductions

3

JavaScript (ES6), 73 71 octets

Sauvegardé 2 octets grâce à ETHproductions

m=>(a=m.map((_,i)=>j=i)).map(_=>a.splice(j,0,+a.splice(j-m[j--],1)))&&a

Cas de test


Belle façon d'obtenir la longueur et la portée en même temps. J'allais suggérer a=m.map(_=>j++,j=0), mais c'est la même longueur et je suis sûr que vous l'avez déjà essayé.
ETHproductions

@ETHproductions Vous avez raison: je l'ai également essayé. :-) (Il est intéressant de noter que ce ne sont pas équivalentes: ce fixerait jà a.lengthplutôt que a.length-1et nécessiterait a.splice(--j,0,a.splice(j-m[j],1)[0]))
Arnauld

Hé, j'y ai pensé aussi, mais je ne pensais pas que ça valait la peine d'être mentionné parce que c'est la même longueur
ETHproductions

1
Easy -2:+a.splice(j-m[j--],1)
ETHproductions

2

Haskell , 85 octets

f x|n<-length x-1=reverse x#[n,n-1..0]
(n:r)#l=r#(take n l++drop(n+1)l)++[l!!n]
x#l=x

Essayez-le en ligne! Exemple d'utilisation: f [0,1,1,2,1,0]rendements [4,0,2,1,3,5].

f xappelle la fonction #avec liste xinversée et une liste [length x - 1, length x - 2, ... , 0]. (n:r)#leffectue le tri par insertion inverse en retirant récursivement le nth élément l, où l!!nrenvoie le nth élément et take n l++drop(n+1)lproduit la liste lavec le nth élément supprimé.


Haskell, si belle.
FMaz

1

perl, 61 octets

@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p

La sortie se retrouve dans le tableau @o. Exemple avec un tableau d'entrée comme arguments de ligne de commande:

perl -le'@o=@p=0..@ARGV-1;splice@o,$_,0,splice@o,$_-pop,1for reverse@p;print@o' 0 1 1 2 1 0
402135

1

Rubis, 49 octets

->l{(w=l.size).times{l.insert(l.shift+w-=1,w)};l}

Effectue «l'insertion inverse» en place dans la liste, en commençant par le plus grand nombre.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.