Ordinare un elenco


26

Sommario

Dato un elenco di numeri interi, restituisce l'indice in cui ogni numero intero sarebbe finito quando ordinato.

Ad esempio, se l'elenco fosse [0,8,-1,5,8], dovresti tornare [1,3,0,2,4]. Si noti che i due 8mantengono il loro ordine l'uno rispetto all'altro (l'ordinamento è stabile).

In altre parole: per ogni elemento nell'elenco, restituisci il numero di elementi nell'elenco che sono: Più piccolo dell'elemento scelto OPPURE (uguale all'elemento AND appare prima dell'elemento scelto)

Gli indici devono iniziare con 0 (non 1) EDIT: dato il grande pushback, permetterò indicazioni basate su 1.

Casi 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

Nonostante la semplicità di questa sfida, non sono riuscito a trovare un duplicato di questa sfida.
Nathan Merrill,

1
Questa è una specializzazione di questa domanda in cui invece di prendere due array ci vuole un array e il secondo è [0 1 ... n-1].
Peter Taylor,

@PeterTaylor: in quella sfida, l'array non ha ripetizioni.
Lynn

2
Nota per i solutori: quel 8,10,4,-1,-1caso di test è molto ingannevole. Prova 4,4,0,1,1,2,0,1prima quello.
Lynn,

@Lynn Ho cercato cosa fa "grade up" e ho capito perché quel test è così ingannevole. Fisso.
Nathan Merrill,

Risposte:


21

APL, 2 byte

⍋⍋

Il "grade up" incorporato, applicato due volte. Funziona se l'indicizzazione inizia da 0, che non è l'impostazione predefinita per tutte le versioni di APL. Provalo qui!

Perché funziona?

⍋xrestituisce un elenco di indici che verranno ordinati in modo stabilex . Per esempio:

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

perché se prendi element 2, allora 6, allora 3... ottieni un elenco stabile:

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

Ma l'elenco degli indici che risponde a questa domanda è leggermente diverso: prima vogliamo l'indice dell'elemento più piccolo, poi il secondo più piccolo, ecc., Sempre, mantenendo l'ordine originale.

Se guardiamo ⍋x, però, vediamo che può darci facilmente questo elenco: la posizione di un 0in ⍋xci dice dove finisce l'elemento più piccolo dopo l'ordinamento, e la posizione di un 1in ⍋xci dice dove sarebbe finito il secondo elemento più piccolo , eccetera.

Ma sappiamo che ⍋xcontiene esattamente i numeri [0, 1 ... n − 1] . Se lo classifichiamo di nuovo , otterremo solo l'indice di 0in ⍋x, quindi l'indice di 1in ⍋x, ecc., Che è esattamente ciò che ci interessa.

Quindi la risposta è ⍋⍋x.


wow, questo deve essere stato diligentemente giocato a golf: P
Downgoat,

ngn-apl supporta solo UTF-8, ma funziona praticamente in tutti i gusti a condizione che l'origine dell'indice sia impostata su 0.
Dennis

Questo mi fa meravigliare: ci sono delle linee di prova per i classici sapori APL?
Lynn,

C'è TryAPL per Dyalog, ma l'impostazione predefinita IO è 1. Tuttavia è facilmente modificabile. permalink
Dennis

1 basato ora è consentito.
Nathan Merrill,


6

JavaScript ES6, 87 82 79 74 70 byte

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

Non mi piace usare un oggetto, ma sembra essere il modo più breve per tenere traccia dei duplicati

Spiegazione

(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 byte

<<

Aumenta il punteggio ( <) due volte. JohnE ha salvato tre byte sottolineando che in K esistono espressioni tacite! Super cool. Provalo.


Il wrapper lambda non è strettamente necessario, puoi semplicemente scriverlo come espressione tacita <<. Provalo qui .
Giovanni,

5

Haskell, 50 48 byte

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

Esempio di utilizzo: m.m $ [4,4,0,1,1,2,0,1]-> [6,7,0,2,3,5,1,4].

Viene map snd.sort.zip x [0..]applicato due volte sull'input, ovvero accoppia ogni elemento e al suo indice i ( (e,i)), ordina rimuovendo i primi elementi. Ripeti una volta.

@Lynn ha pensato m=map snd.sort.(`zip`[0..])che ha lo stesso numero di byte.


5

Python 2, 67 60 byte

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

Grazie a @xnor per giocare a golf con 7 byte!

Provalo su Ideone .


Il Capovolto enumeratepuò essere fatto più breve con un zip: l=input();x=zip(l,range(len(l))).
xnor

In tal caso, una funzione è ancora più breve. Grazie!
Dennis,

4

PowerShell v2 +, 63 byte

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

Prende input $n, reindirizza attraverso un loop su ogni elemento |%{...}. Ogni iterazione, sort $notteniamo il IndexOfnostro elemento attuale $_. Questo conta quanti elementi sono più piccoli dell'elemento corrente. Aggiungiamo a ciò una porzione di $n, che espande ogni iterazione del ciclo, degli elementi che sono uguali all'elemento corrente $_e prendono .Countquello. Quindi sottraggiamo in -1modo da non contare il nostro elemento corrente e quel numero viene lasciato sulla pipeline. L'output alla fine è implicito.

Esempi

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 byte

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

Provalo online!

Spiegazione

{             }       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 byte

/:^:2

Aumenta il punteggio ( /:) due volte ( ^:2). 0-indicizzati.

Per provarlo, digitare f =: /:^:2e quindi f 4 4 0 1 1 2 0 1in tryj.tk .


O /:@/:con uguale numero di byte.
Leaky Nun,

4

MATL, 10 9 4 byte

4 byte salvati grazie a @Luis

&S&S

Questa soluzione utilizza l'indicizzazione basata su 1

Provalo online


@DrGreenEggsandIronMan Cerco meta e non trovo nulla che indichi in entrambi i modi. Detto questo, ho ripristinato la restrizione.
Nathan Merrill,

4

05AB1E, 12 byte

2FvyN‚}){€¦˜

spiegato

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

Provalo online


4

Python 2, 67 byte

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

xnor ha salvato due byte.


È più breve ricreare l'elenco di elementi visti in precedenza mentre a=input();p=[]\nfor x in a:print sorted(a).index(x)+p.count(x);p+=x,
procedi

Ah, mi piace! Grazie.
Lynn,

4

Haskell, 40 byte

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

Annota ogni elemento con il suo indice, quindi associa ogni elemento al conteggio di elementi più piccoli, legando in modo discontinuo l'indice. Nessun ordinamento.


3

Julia, 17 byte

~=sortperm;!x=~~x

1-indicizzati. Aumenta il punteggio ( sortperm) due volte. Provalo qui.

EDIT: Dennis ha salvato quattro byte assegnando nomi di operatore-y di roba! Julia è strana.


3

JavaScript (ES6), 52 byte

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

Definisce gla funzione grade, che restituisce una matrice di indici da cui provengono tutti gli elementi della matrice ordinata nella matrice originale. Sfortunatamente ciò che vogliamo sono gli indici a cui andranno tutti gli elementi. Fortunatamente questo risulta essere la mappatura dal voto all'elenco originale di indici, che può essere considerato il risultato dell'ordinamento del voto, permettendoci così di prendere il voto per ottenere il risultato desiderato.



2

Racchetta, 117 byte

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

Sono eternamente deluso dalla mancanza di un meccanismo per questo.


Sarebbe più breve mettere ogni elemento in una coppia (numero, indice), quindi ordinarlo?
Nathan Merrill,

Ci ho provato, ma mi dà l'inverso dell'elenco che vorrei, e purtroppo ottenere l'indice di un oggetto all'interno dell'elenco per invertirlo è orribilmente inefficiente.
Steven H.

2

Rubino, 54 53 byte

Provalo online

-1 byte dall'aggiornamento all'approccio di @ Downgoat di utilizzare un hash per memorizzare i valori invece di contare i duplicati ogni volta.

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

L'ordinamento di Ruby è instabile , il che significa che questo potrebbe fare la cosa sbagliata sui legami.
Nathan Merrill,

1
@NathaMerrill Non a causa del metodo esatto che sto usando per generare i numeri. Se avessi ordinato su un elenco di indici, avrebbe prodotto il risultato sbagliato. Prova il link! Funzionerà il 60% delle volte, ogni volta. In seguito posterò anche una spiegazione.
Value Ink

Ah ok. Non ero sicuro di cosa stesse facendo il resto del codice (non conosco Ruby)
Nathan Merrill,

? Non fa la cosa sbagliata sui legami, ma fa qualcos'altro che non va nel 40% delle volte?
WGroleau,

@WGroleau è una citazione di Anchorman. Il mio codice funziona sempre, comunque.
Value Ink

2

Clojure, 83 byte

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

Creo una funzione anonima che classifica l'array di input e lo itera due volte sull'input. La prima chiamata restituirà il voto. La seconda chiamata opera sul voto e restituisce il grado.


2

Brachylog , 27 byte

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

Provalo online! o verifica tutti i casi di test .

Spiegazione

Questa è un'implementazione semplice della seguente relazione: ogni numero intero dell'output corrispondente a un elemento dell'input è l'indice di quell'elemento nell'input ordinato.

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 byte

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

1

Lisp comune, 117 byte

(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))))

Applicare due volte una trasformazione di Schwartz .

;; 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)

Test

(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 (utilizzando una libreria esterna) (105 byte)

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

Link a lib: https://github.com/mvegh1/Enumerable Spiegazione del codice: creare un metodo anonimo che accetta un elenco di numeri interi. _.From crea un'istanza della libreria che avvolge un array con metodi speciali. Seleziona mappa ogni elemento su un nuovo elemento, prendendo la "v", analizzandola su una stringa, quindi concatenando l'ndex "i" di quell'elemento (questo risolve il caso di valore duplicato). Quello è memorizzato nella variabile 'a'. Quindi restituiamo il risultato di quanto segue: Mappare ogni elemento in 'a' all'indice di quell'elemento nella versione ordinata di a (come numeri interi) e tornare a un array JS nativo

inserisci qui la descrizione dell'immagine

Si noti che i numeri duplicati negativi sembrano stampare nell'ordine inverso. Non sono sicuro che ciò invalidi questa soluzione? Tecnicamente 8,10,4, -1, -1,8 dovrebbe essere 3,5,2,0,1,4 secondo OP ma il mio codice sta stampando 3,5,2,1,0,4 che credo sia ancora tecnicamente valido?


1

GNU Core Utils, 39 33 byte

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

Produce un output basato su 1. Aggiungi -v0dopo il secondo nlper ottenere un output basato su 0. (+4 byte)

Comandi che stiamo usando:

  • nl aggiunge numeri di riga a ciascuna riga dell'input.
  • sort -n -k 2 ordina per colonna 2 numericamente.
  • cut -f 1 prende la prima colonna delimitata da tabulazioni, scartando il resto.

Inoltre, è -spossibile passare l' opzione sortper richiedere un ordinamento stabile, ma non ne abbiamo bisogno qui. Se due elementi sono identici, sortdeterminerà il loro ordine ritornando alle altre colonne, che in questo caso è l'output monotonicamente crescente da nl. Quindi l'ordinamento sarà stabile senza la necessità di specificarlo, in virtù dell'input.


1

Java 149 140 byte

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;
}

golfed

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;}

Grazie a @Kevin Cruissjen per la rasatura di 9 byte.


@Nathan Merrill L'ho notato quando ho giocato a golf, ma l'ho dimenticato quando ho incollato la risposta golf.
Roman Gräf

1
Puoi giocare ancora a golf. Non hai bisogno degli spazi tra int[] ae int[] b. Puoi togliere intgli anelli. E poiché lo usi b.lengthdue volte all'inizio, puoi inserirlo in un campo separato. Quindi in totale qualcosa del genere: 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 byte ) Hmm, inoltre, non sembra funzionare .. Arrays.sort(...)non restituisce nulla (è un voidmetodo), quindi come puoi confrontarlo con b[i]? ..
Kevin Cruijssen

1

PHP, 88 byte

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

opera su argomenti della riga di comando; stampa un elenco indicizzato 0, con sottolineatura separato. Corri con -nr.

abbattersi

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 byte

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

La maggior parte dei built-in di ordinamento di MATLAB restituirà un secondo array opzionale contenente gli indici ordinati. Il j=poter togliere se la stampa degli indici è accettabile, invece di ritornare.


0

CJam , 19 byte

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

Provalo online!

Spiegazione:

_ 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.