Commander une liste


26

Sommaire

Étant donné une liste d'entiers, retournez l'index auquel chaque entier se retrouverait lors du tri.

Par exemple, si la liste était [0,8,-1,5,8], vous devriez revenir [1,3,0,2,4]. Notez que les deux 8s maintiennent leur ordre l'un par rapport à l'autre (le tri est stable).

Autrement dit: pour chaque élément de la liste, renvoyez le nombre d'éléments de la liste qui sont: plus petits que l'élément choisi OU (égal à l'élément ET apparaît avant l'élément choisi)

Les index doivent commencer par 0 (pas 1) EDIT: étant donné le grand recul, je vais autoriser les indices basés sur 1.

Cas de test:

0                -> 0
23               -> 0
2,3              -> 0,1
3,2              -> 1,0
2,2              -> 0,1
8,10,4,-1,-1,8   -> 3,5,2,0,1,4
0,1,2,3,4,5,6,7  -> 0,1,2,3,4,5,6,7
7,6,5,4,3,2,1,0  -> 7,6,5,4,3,2,1,0
4,4,0,1,1,2,0,1  -> 6,7,0,2,3,5,1,4
1,1,1,1,1,1,1,1  -> 0,1,2,3,4,5,6,7
1,1,1,1,1,1,1,0  -> 1,2,3,4,5,6,7,0

Malgré la simplicité de ce défi, je n'ai pas pu trouver de doublon de ce défi.
Nathan Merrill

1
Il s'agit d'une spécialisation de cette question où au lieu de prendre deux tableaux, il faut un tableau et le second est [0 1 ... n-1].
Peter Taylor

@PeterTaylor: Dans ce défi, le tableau n'a pas de répétitions.
Lynn

2
Note aux solveurs: ce 8,10,4,-1,-1cas de test est très trompeur. Essayez d' 4,4,0,1,1,2,0,1abord celui-là.
Lynn

@Lynn J'ai recherché ce que fait le "grade up", et j'ai compris pourquoi ce cas de test est si trompeur. Fixé.
Nathan Merrill

Réponses:


21

APL, 2 octets

⍋⍋

Le «grade up» intégré, appliqué deux fois. Fonctionne si l'indexation commence à 0, ce qui n'est pas la valeur par défaut pour toutes les versions d'APL. Essayez-le ici!

Pourquoi ça marche?

⍋xrenvoie une liste d'indices qui seraient triés de manière stablex . Par exemple:

    x ← 4 4 0 1 1 2 0 1
    ⍋x
2 6 3 4 7 5 0 1

parce que si vous prenez un élément 2, alors 6, alors 3… vous obtenez une liste triée de manière stable:

    x[⍋x]
0 0 1 1 1 2 4 4

Mais la liste d'index qui répond à cette question est subtilement différente: nous voulons d'abord l'index du plus petit élément, puis le deuxième plus petit, etc. - encore une fois, en gardant l'ordre d'origine.

Si nous regardons ⍋x, cependant, nous voyons que cela peut nous donner facilement cette liste: la position d'un 0in ⍋xnous indique où le plus petit élément finirait après le tri, et la position d'un 1in ⍋xnous indique où le deuxième plus petit élément finirait , etc.

Mais nous savons que ⍋xcontient exactement les nombres [0, 1… n − 1] . Si nous le notons à nouveau , nous obtiendrons simplement l'indice de 0in ⍋x, puis l'indice de 1in ⍋x, etc., ce qui est précisément ce qui nous intéresse.

La réponse est donc ⍋⍋x.


wow, cela doit avoir été minutieusement joué au golf: P
Downgoat

ngn-apl ne prend en charge que l'UTF-8, mais cela fonctionne à peu près dans toutes les saveurs à condition que l'origine de l'index soit définie sur 0.
Dennis

Cela me fait me demander: existe-t-il des essais en ligne pour les saveurs APL classiques?
Lynn

Il existe TryAPL pour Dyalog, mais IO par défaut est 1. Cependant, il est facilement modifiable. permalien
Dennis

1 basé est autorisé maintenant.
Nathan Merrill


6

JavaScript ES6, 87 82 79 74 70 octets

(a,b={})=>a.map(l=>[...a].sort((a,b)=>a-b).indexOf(l)+(b[l]=b[l]+1|0))

Je n'aime pas utiliser un objet, mais cela semble être le moyen le plus court de garder une trace des dupes

Explication

(a,b={})=>          `a` is input
                    `b` stores the occurrences of each number
  a.map(l =>        Loop over the array, `l` is item
  [...a]            Copy `a`
    .sort(...)       Sort in ascending numerical order
    .indexOf(l)      Index of input in that array
  +                 Add the following to account for dupes
   (b[l]=            set and return the item `l` in hashmap `b` to...
     b[l]+1           Increase the counter by one if it exists yet
     |0               default is zero
   )


6

K , 5 2 octets

<<

Montez ( <) deux fois. JohnE a économisé trois octets en soulignant que les expressions tacites existent en K! Super cool. Essaye le.


Le wrapper lambda n'est pas strictement nécessaire - vous pouvez simplement l'écrire comme une expression tacite <<. Essayez-le ici .
JohnE

5

Haskell, 50 48 octets

import Data.List
m x=map snd$sort$zip x[0..]
m.m

Exemple d'utilisation: m.m $ [4,4,0,1,1,2,0,1]->[6,7,0,2,3,5,1,4] .

Il est map snd.sort.zip x [0..]appliqué deux fois sur l'entrée, c'est-à-dire que chaque élément e est associé à son indice i ((e,i) ), triez-le et supprimez les premiers éléments. Répétez une fois.

@Lynn est arrivé avec m=map snd.sort.(`zip`[0..])le même nombre d'octets.


5

Python 2, 67 60 octets

def f(x):x=zip(x,range(len(x)));print map(sorted(x).index,x)

Merci à @xnor d'avoir joué au golf 7 octets!

Testez-le sur Ideone .


Le Flipped enumeratepeut être fait plus court avec zip: l=input();x=zip(l,range(len(l))).
xnor

Dans ce cas, une fonction est encore plus courte. Merci!
Dennis

4

PowerShell v2 +, 63 octets

param($n)$n|%{($n|sort).IndexOf($_)+($n[0..$i++]-eq$_).count-1}

Prend l'entrée $n, les tuyaux qui traversent une boucle sur chaque élément |%{...}. À chaque itération, nous sort $nobtenons IndexOfnotre élément actuel $_. Cela compte combien d'éléments sont plus petits que l'élément actuel. Nous ajoutons à cela une tranche de $n, qui développe chaque itération de boucle, des éléments qui sont égaux à l'élément courant $_et prenons le .Countde cela. Nous soustrayons ensuite -1afin de ne pas compter notre élément actuel, et ce nombre est laissé sur le pipeline. La sortie à la fin est implicite.

Exemples

PS C:\Tools\Scripts\golfing> .\ordering-a-list.ps1 @(4,4,0,1,1,2,0,1)
6
7
0
2
3
5
1
4

PS C:\Tools\Scripts\golfing> .\ordering-a-list.ps1 @(8,10,4,-1,-1)
3
4
2
0
1

4

CJam, 15 octets

{{eeWf%$1f=}2*}

Essayez-le en ligne!

Explication

{             }       Delimits an anonymous block.
 {         }2*        Run this block on the argument twice:
  ee                  Enumerate ([A B C] → [[0 A] [1 B] [2 C]])
    Wf%               Reverse each ([[A 0] [B 1] [C 2]])
       $              Sort the pairs lexicographically;
                        i.e. first by value, then by index.
        1f=           Keep the indices.

4

J, 5 octets

/:^:2

Montez ( /:) deux fois ( ^:2). 0 indexé.

Pour l' essayer, tapez f =: /:^:2puis f 4 4 0 1 1 2 0 1dans tryj.tk .


Ou /:@/:avec un nombre d'octets égal.
Leaky Nun

4

MATL, 10 9 4 octets

4 octets économisés grâce à @Luis

&S&S

Cette solution utilise l'indexation basée sur 1

Essayez-le en ligne


@DrGreenEggsandIronMan Je recherche des méta et je n'ai rien trouvé qui indique quoi que ce soit. Cela dit, j'ai annulé la restriction.
Nathan Merrill

4

05AB1E, 12 octets

2FvyN‚}){€¦˜

Expliqué

2F            # 2 times do
  vyN‚})      # create list of [n, index]-pairs
        {€¦   # sort and remove first element leaving the index
           ˜  # deep flatten
              # implicit output

Essayez-le en ligne


4

Python 2, 67 octets

a=input()
p=[]
for x in a:print sorted(a).index(x)+p.count(x);p+=x,

xnor a enregistré deux octets.


Il est plus court de recréer la liste des éléments précédemment vus au fur et à mesure:a=input();p=[]\nfor x in a:print sorted(a).index(x)+p.count(x);p+=x,
xnor

Ah, j'aime ça! Merci.
Lynn

4

Haskell, 40 octets

f l|z<-zip l[0..]=[sum[1|y<-z,y<x]|x<-z]

Annotez chaque élément avec son index, puis mappez chaque élément au nombre d'éléments plus petits, en brisant l'égalité sur l'index. Pas de tri.


3

Julia, 17 octets

~=sortperm;!x=~~x

1 indexé. Montez ( sortperm) deux fois. Essayez-le ici.

EDIT: Dennis a économisé quatre octets en donnant des noms d'opérateur de trucs! Julia est bizarre.


3

JavaScript (ES6), 52 octets

a=>(g=a=>[...a.keys()].sort((n,m)=>a[n]-a[m]))(g(a))

Définit gcomme la fonction de grade, qui renvoie un tableau d'index dont tous les éléments du tableau trié seraient issus du tableau d'origine. Malheureusement, ce que nous voulons, ce sont les indices vers lesquels iront tous les éléments. Heureusement, cela s'avère être la correspondance entre la note et la liste d'origine des indices, qui peut elle-même être considérée comme le résultat du tri de la note, ce qui nous permet de prendre la note de la note pour obtenir le résultat souhaité.



2

Raquette, 117 octets

(λ(x)(build-list(length x)(λ(h)((λ(y)(+(count(λ(z)(< z y))x)(count(λ(z)(eq? z y))(take x h))))(list-ref x h)))))

Je suis éternellement déçu par l'absence d'un builtin pour cela.


Serait-il plus court de mettre chaque élément dans une paire (nombre, index), puis de le trier?
Nathan Merrill

J'ai essayé cela, mais cela me donne l'inverse de la liste que je voudrais, et malheureusement, obtenir l'index d'un objet dans la liste afin de l'inverser est horriblement inefficace en octets.
Steven H.

2

Rubis, 54 53 octets

Essayez-le en ligne

-1 octet de la mise à niveau vers l'approche de @ Downgoat consistant à utiliser un hachage pour stocker les valeurs au lieu de compter les doublons à chaque fois.

->a{b={};a.map{|e|a.sort.index(e)+b[e]=(b[e]||-1)+1}}

Le genre de Ruby est instable , ce qui signifie que cela pourrait faire la mauvaise chose sur les liens.
Nathan Merrill

1
@NathaMerrill Ce n'est pas le cas en raison de la méthode exacte que j'utilise pour générer les chiffres. Si je triais sur une liste d'indices, cela produirait le mauvais résultat. Essayez le lien! Cela fonctionnera 60% du temps, à chaque fois. Je posterai également une explication plus tard.
Value Ink

Ah ok. Je n'étais pas sûr de ce que faisait le reste du code (je ne connais pas Ruby)
Nathan Merrill

? Il ne fait pas la mauvaise chose sur les cravates, mais il fait autre chose de mal 40% du temps?
WGroleau

@WGroleau c'est une citation d'Anchorman. Mon code fonctionne tout le temps, cependant.
Value Ink

2

Clojure, 83 octets

(fn[a](nth(iterate #(->> %(map-indexed(comp vec rseq vector))sort(map second))a)2))

Je crée une fonction anonyme qui classe le tableau d'entrée et l'itère deux fois sur l'entrée. Le premier appel renverra la note. Le deuxième appel opère sur la note et renvoie le rang.


2

Brachylog , 27 octets

lL-M,?og:MjO,L~l.#d:Orz:ma?

Essayez-le en ligne! ou vérifiez tous les cas de test .

Explication

Il s'agit d'une implémentation simple de la relation suivante: chaque entier de la sortie correspondant à un élément de l'entrée est l'indice de cet élément dans l'entrée triée.

Example input: [3:2]

lL               L is the length of the input (e.g L=2)
  -M,            M = L-1 (e.g. M=1)
?o               Sort the input...
  g:MjO,         ... and create a list O with L copies of the input (e.g. O=[[2:3]:[2:3]])
L~l.             Output is a list of length L (e.g. [I:J])
    #d           All elements of the output must be distinct (e.g. I≠J)
      :Orz       Zip O with the output (e.g. [[[2:3]:I]:[[2:3]:J]])
          :ma?   Apply predicate Member with that zip as input and the input as output
                 (e.g. 3 is the Ith element of [2:3] and 2 is the Jth element of [2:3])


2

Mathematica, 135 octets

Function[{list}, SortBy[MapIndexed[Join[{#1}, #2]&, Sort@MapIndexed[Join[{#1}, #2] &, list]], #[[1, 2]] &][[All, 2]] - 1]

1

Lisp commun, 117 octets

(flet((i(Z)(mapcar'cdr(stable-sort(loop for e in Z for x from 0 collect(cons e x))'< :key'car))))(lambda(L)(i(i L))))

Appliquez deux fois une transformation schwartzienne.

;; FIRST TIME

(0 8 -1 5 8)
;; add indexes
((0 . 0) (8 . 1) (-1 . 2) (5 . 3) (8 . 4))
;; sort by first element
((-1 . 2) (0 . 0) (5 . 3) (8 . 1) (8 . 4))
;; extract second elements
(2 0 3 1 4)

;; SECOND TIME

(2 0 3 1 4)
;; indexes
((2 . 0) (0 . 1) (3 . 2) (1 . 3) (4 . 4))
;; sort by first element
((0 . 1) (1 . 3) (2 . 0) (3 . 2) (4 . 4))
;; extract second elements
(1 3 0 2 4)

Tester

(let ((fn (flet((i(Z)(mapcar'cdr(stable-sort(loop for e in Z for x from 0 collect(cons e x))'< :key'car))))(lambda(L)(i(i L))))))
  (every
   (lambda (test expected)
     (equal (funcall fn test) expected))

   '((0) (23) (2 3) (3 2) (2 2) (8 10 4 -1 -1 8) (0 1 2 3 4 5 6 7)
     (7 6 5 4 3 2 1 0) (4 4 0 1 1 2 0 1) (1 1 1 1 1 1 1 1) (1 1 1 1 1 1 1 0))

   '((0) (0) (0 1) (1 0) (0 1) (3 5 2 0 1 4) (0 1 2 3 4 5 6 7) (7 6 5 4 3 2 1 0)
     (6 7 0 2 3 5 1 4) (0 1 2 3 4 5 6 7) (1 2 3 4 5 6 7 0))))
=> T

1

JavaScript (à l'aide d'une bibliothèque externe) (105 octets)

(n)=>{var a=_.From(n).Select((v,i)=>v+""+i);return a.Select(x=>a.OrderBy(y=>(y|0)).IndexOf(x)).ToArray()}

Lien vers la bibliothèque: https://github.com/mvegh1/Enumerable Explication du code: créez une méthode anonyme qui accepte une liste d'entiers. _.From crée une instance de la bibliothèque qui enveloppe un tableau avec des méthodes spéciales. Sélectionnez mappe chaque élément à un nouvel élément, en prenant la valeur "v", en l'analysant en une chaîne, puis en concaténant l'index "i" de cet élément (cela résout le cas de valeur en double). C'est stocké dans la variable «a». Ensuite, nous renvoyons le résultat de ce qui suit: Mappez chaque élément de 'a' à l'index de cet élément dans la version triée de a (sous forme d'entiers), puis convertis en tableau JS natif

entrez la description de l'image ici

Notez que les nombres négatifs en double semblent s'imprimer dans l'ordre inverse. Je ne sais pas si cela invalide cette solution? Techniquement, 8,10,4, -1, -1,8 devraient être 3,5,2,0,1,4 selon OP, mais mon code imprime 3,5,2,1,0,4 qui, je crois, est toujours techniquement valable?


1

GNU Core Utils, 39 33 octets

nl|sort -nk2|nl|sort -nk2|cut -f1

Produit une sortie basée sur 1. Ajouter-v0 après la seconde nlpour obtenir une sortie basée sur 0. (+4 octets)

Commandes que nous utilisons:

  • nl ajoute des numéros de ligne à chaque ligne de l'entrée.
  • sort -n -k 2 trie par colonne 2 numériquement.
  • cut -f 1 prend la première colonne délimitée par des tabulations, jetant le reste.

De plus, l' -soption peut être passée à sortpour demander un tri stable, mais nous n'en avons pas besoin ici. Si deux éléments sont identiques, sortdéterminera leur ordre en retombant dans les autres colonnes, qui dans ce cas est la sortie augmentant de façon monotone nl. Le tri sera donc stable sans avoir besoin de le spécifier, grâce à l'entrée.


1

Java 149 140 octets

public int[] indexArray(int[] index){
  int[] out=new int[index.length];
  for(int i=-1;++i<index.length;){
    for(int j=-1;++i<index.length;){
      if(index[i]==Arrays.sort(index.clone())[j]){
        out[i]=j;
      }
    }
  }
  return out;
}

Golfé

int[]a(int[]b){int l=b.length;int[]o=new int[l];for(int i=-1;++i<l;)for(int j=-1;++i<l;)if(b[i]==Arrays.sort(b.clone())[j])o[i]=j;return o;}

Merci à @Kevin Cruissjen pour le rasage de 9 octets.


@Nathan Merrill J'ai remarqué cela quand je l'ai joué au golf, mais je l'ai oublié quand j'ai collé la réponse au golf.
Roman Gräf

1
Vous pouvez jouer au golf un peu plus. Vous n'avez pas besoin des espaces entre int[] aet int[] b. Vous pouvez retirer intles boucles. Et puisque vous utilisez b.lengthdeux fois au début, vous pouvez le mettre dans un champ séparé. Donc au total quelque chose comme ça: int[]a(int[]b){int l=b.length,o[]=new int[l],i,j;for(i=-1;++i<l;)for(j=-1;++i<b.length;)if(b[i]==Arrays.sort(b.clone())[j])o[i]=j;return o;}( 140 octets ) Hmm, aussi, cela ne semble pas fonctionner .. Arrays.sort(...)ne retourne rien (c'est une voidméthode), alors comment pouvez-vous le comparer avec b[i]? ..
Kevin Cruijssen

1

PHP, 88 octets

unset($argv[0]);$a=$argv;sort($a);foreach($argv as$e)echo$h[$e]+++array_search($e,$a),_;

fonctionne sur des arguments de ligne de commande; imprime une liste indexée 0, séparée par un trait de soulignement. Courez avec -nr.

panne

unset($argv[0]);        // remove file name from arguments
$a=$argv;               // create copy
sort($a);               // sort copy (includes reindexing, starting with 0)
foreach($argv as$e)     // loop $e through original
    echo                    // print:
        $h[$e]++            // number of previous occurences
        +array_search($e,$a)// plus position in copy 
        ,_                  // followed by underscore
    ;

0

MATLAB, 29 octets

function j=f(s);[~,j]=sort(s)

La plupart des fonctions intégrées de tri de MATLAB renverront un deuxième tableau facultatif contenant les indices triés. Le j=pourrait être supprimé si l'impression des index est acceptable, plutôt que de les renvoyer.


0

CJam , 19 octets

_$:A;{A#_AWt:A;1+}%

Essayez-le en ligne!

Explication:

_ duplicate array
 $ sort array
  :A store in variable A
    ; discard top item in stack
     {A#_AWt:A;1+} block that finds index of item and removes it from sorted array to prevent duplicates
      % map block onto every item in array
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.