Ordinamento di inserzione inversa


19

Obbiettivo

Genera l'elenco criptato originale, dai movimenti che farebbe un ordinamento di inserzione per ordinarlo. L'elenco originale avrà tutti i numeri da 0a N-1(incluso) dove si Ntrova la dimensione dell'input.

Ingresso

Un elenco contenente le mosse necessarie per ordinare l'elenco. Ogni valore rappresenta la quantità di slot spostati dal numero originale (criptato) per essere nella sua posizione giusta, tenere presente che questo processo è da sinistra a destra.
Il valore nella posizione (indicizzata 0) inell'elenco di input sarà compreso 0e icompreso.
Non è necessario gestire input non validi, in questo caso è accettabile qualsiasi comportamento (crash, loop infinito, ecc.).

Produzione

L'elenco criptato

Step-by-step per generare le mosse

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]

Quindi, per l'input il [0,1,1,2,1,0]tuo programma deve produrre [4,0,2,1,3,5].
Tieni presente che i movimenti non sono nella posizione nell'elenco (finale) ordinato, ma nel segmento ordinato (la sezione in grassetto)

Casi 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]

vincente

Questo è , quindi vince la risposta più breve.

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
Il programma può anche prendere la lunghezza dell'elenco come input?
mbomb007,

@ mbomb007 no.
Rod,

Possiamo usare invece i passaggi (n-1)? Il primo non è necessario, poiché è sempre zero.
GB

@GB certo, finché l'output è corretto, puoi usare qualsiasi algoritmo
Rod

Risposte:


14

Gelatina , 12 byte

L!_UÆ¡$œ?J’U

Provalo online!

Spiegazione

Possiamo sostanzialmente vedere le due liste (l'input e l'output) come codificare un numero intero; l'input codifica un numero intero in base fattoriale e l'output codifica un numero intero come permutazione. Fortunatamente, Jelly ha builtin che sono già molto vicini a entrambe queste codifiche, quindi è semplicemente una questione di scrivere piccoli pezzi di codice da convertire in un numero intero, quindi di nuovo nell'altra codifica.

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

Nel caso del fattoriale di base, possiamo osservare che il primo elemento dell'elenco deve essere 0, il secondo può essere 0 o 1, il terzo deve essere 0/1/2 e così via. Pertanto, dobbiamo invertire l'input per ottenere i suoi elementi nel normale ordine di scrittura per la conversione di base.

Inoltre, affinché gli ordini relativi della conversione fattoriale e della conversione di permutazione corrispondano all'operazione utilizzata dall'ordinamento di inserzione, è necessario effettuare due regolazioni: invertire la sequenza delle permutazioni e invertire l'ordine dell'elenco di output. Invertire la lista di output è abbastanza semplice, richiede solo una Ualla fine del programma. Per invertire la sequenza di permutazioni, sottraggiamo dal fattoriale della lunghezza di input (questo funziona perché il fattoriale di base produce un numero compreso tra 0 e (lunghezza! -1), mentre le permutazioni sono numerate da Jelly da 1 a lunghezza! , producendo un off-by-one implicito che annulla l'off-by-one che normalmente si ottiene sottraendo un indice di permutazione da un fattoriale).

Jelly , 9 byte, in collaborazione con @JonathanAllan

UÆ¡Nœ?J’U

Questa versione del programma è molto simile, ma utilizza un metodo diverso per invertire la sequenza di permutazioni; è sufficiente semplicemente negare l'input con Nper œ?trattare l'ordine al contrario. A parte questo, funziona in modo identico al programma precedente.

Provalo online!


4
O_O Che stregoneria è questa?
DLosc,

Oh bello - sapevo che il mio Æ¡e gli œ?atomi avrebbero funzionato per questo (avevo già iniziato a provare a usarli per questa sfida prima - ero così vicino, avevo solo bisogno L!di essere lì dentro).
Jonathan Allan,

Codice eccellente!
Greg Martin,

1
In effetti, puoi farlo in 9 byte con UÆ¡Nœ?L’Uperché ho implementato œ?(e simili) per agire in modo modulare (come se stessero usando le liste Jelly). Il Ngiusto si indicizza con il valore negativo. Nota: sono passato Ja L- questo è solo perché, dato un numero, fa comunque un intervallo sotto il cofano).
Jonathan Allan,

6

Mathematica, 92 byte

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

Funzione pura che prende come input un elenco di numeri interi non negativi e restituisce un elenco di numeri interi non negativi. Il codice sopra contiene a ©, che non è corretto: è un segnaposto per il simbolo a 3 byte U + F3DE, che Mathematica rappresenta da un cerchio con un punto al suo interno e che rappresenta la composizione di permutazioni.

c=Cycles@{#}&definisce una funzione che converte un elenco di numeri interi in un Cyclesoggetto che rappresenta una permutazione; per esempio, c[{3,4}]è la trasposizione che scambia gli elementi 3 e 4 di un elenco. c[i-0~Range~#[[i]]]~Table~{i,l,1,-1}]prende l'elenco di input e genera le permutazioni necessarie per annullare l'ordinamento di inserzione. Quindi c@{}©##&@@compone tutte queste permutazioni insieme, a partire dalla permutazione dell'identità c@{}. Infine, Permute[Range[l=Length@#]-1,...]applica questa permutazione all'elenco 0 indicizzato di lunghezza appropriata.


1
Cosa non incorporato ?! Sicuramente ...
Jonathan Allan,

3
@{#}&)@{}©##&@@sembra spaventoso.
Yytsi,

6

Python 2, 79 68 byte

Grazie a Krazor per aver salvato 10 byte

Grazie a TuukkaX per aver salvato 1 byte

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

Funziona generando le mosse al contrario


2
Fallo 66 ! Che ne dite di: a=input();b=range(len(a));print[b.pop(j-a[j]) for j in b[::-1]][::-1]. Comprensioni elenco ftw!
FMaz,

1
@Krazor Hai uno spazio che potrebbe essere rimosso prima for, quindi immagina che 65 : D
Yytsi

@Krazor Risulta che la comprensione della lista non ha funzionato del tutto, ma mi è piaciuta l'idea di usare b [:: - 1]!
drogato di matematica il

Non c'è modo? Ho commentato con il cellulare, forse ho sbagliato a scrivere qualcosa. Quale parte non funziona? Per me, ha interpretato correttamente e ha soddisfatto tutti i casi di test.
FMaz,

@Krazor Oh whoops, no hai ragione. Sono quello che l'ha scritto male durante i test.
drogato di matematica il

5

JavaScript (ES6), 69 65 63 byte

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

Sia l'input che l'output sono fastidiosamente nell'ordine sbagliato. Modifica: salvato 4 byte grazie a @Arnauld. Salvato 2 byte grazie a @ETHproductions.


Stavo ancora cercando di trovare un modo migliore ma tu eri molto più veloce. Ben fatto!
Arnauld,

1
Non hai bisogno i, vero?
Arnauld,

@Arnauld Apparentemente no. Ho iniziato cercando di capire la risposta di Python e ho appena notato che in realtà non utilizza i...
Neil

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

3

JavaScript (ES6), 73 71 byte

Risparmiato 2 byte grazie a ETHproductions

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

Casi test


Bel modo di ottenere la lunghezza e la portata allo stesso tempo. Stavo per suggerire a=m.map(_=>j++,j=0), ma è della stessa lunghezza e sono sicuro che l'hai già provato.
ETHproductions

@ETHproductions Hai ragione: l'ho provato anche io. :-) (Può essere opportuno notare che questo non è equivalente: ciò impostare ja a.lengthanziché a.length-1e richiederebbe a.splice(--j,0,a.splice(j-m[j],1)[0]))
Arnauld

Eh, ci ho pensato anche io, ma non pensavo che valesse la pena menzionarlo perché ha la stessa lunghezza
ETHproductions

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

2

Haskell , 85 byte

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

Provalo online! Esempio di utilizzo: f [0,1,1,2,1,0]rese [4,0,2,1,3,5].

f xchiama la funzione #con la lista xinvertita e una lista [length x - 1, length x - 2, ... , 0]. (n:r)#lesegue l'ordinamento di inserzione inversa estraendo ricorsivamente l' nelemento th l, dove l!!nproduce l' nelemento th e take n l++drop(n+1)lrestituisce l'elenco lcon l' nelemento th rimosso.


Haskell, così bello.
FMaz,

1

perl, 61 byte

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

L'output termina nell'array @o. Esempio con array di input come argomenti della riga di comando:

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

Rubino, 49 byte

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

Esegue "l'inserimento inverso" all'interno dell'elenco, iniziando con il numero più grande.

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.