Genera permutazioni ansiose


13

introduzione

Ho definito la classe di permutazioni ansiose in una sfida precedente . Come promemoria, una permutazione p dei numeri da 0 a r-1 è ansiosa, se per ogni voce p [i] eccetto la prima, c'è qualche voce precedente p [ik] tale che p [i] == p [ ik] ± 1 . Come fatto divertente, ho anche affermato che per r ≥ 1 , ci sono esattamente 2 permutazioni antsy r-1 di lunghezza r . Ciò significa che esiste una corrispondenza uno a uno tra le permutazioni antsy della lunghezza r e i vettori binari della lunghezza r-1. In questa sfida, il tuo compito è implementare tale corrispondenza.

L'obiettivo

Il tuo compito è scrivere un programma o una funzione che includa un vettore binario di lunghezza 1 ≤ n ≤ 99 e produca una permutazione ansiosa di lunghezza n + 1 . La permutazione può essere basata su 0 o su 1 (ma questo deve essere coerente) e l'input e l'output possono essere in qualsiasi formato ragionevole. Inoltre, input diversi devono sempre fornire output diversi; a parte questo, sei libero di restituire qualunque permutazione ansiosa desideri.

Vince il conteggio dei byte più basso.

Esempio

Le permutazioni antsy (basate su 0) della lunghezza 4 sono

0 1 2 3
1 0 2 3
1 2 0 3
1 2 3 0
2 1 0 3
2 1 3 0
2 3 1 0
3 2 1 0

e il tuo programma dovrebbe restituirne uno per ciascuno dei vettori a otto bit di lunghezza 3:

0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

Il programma può invece assumere la rappresentazione intera di ciascun vettore binario?
mbomb007,

1
@ mbomb007 No, perché gli zeri iniziali sono significativi. 0 1e 0 0 1dovrebbe fornire output di diverse lunghezze.
Zgarb,

Risposte:


3

Gelatina , 12 11 10 byte

ḟẋLṭ+
0;ç/

Provalo online! o generare tutte le permutazioni di lunghezza 4 .

Come funziona

0;ç/   Main link. Argument: B (bit array)

0;     Prepend a 0 to B.
  ç/   Reduce [0] + B by the helper link.


ḟẋLṭ+  Helper link. Left argument: A (array or 0). Right argument: b (bit)

 ẋ     Repeat A b times, yielding A or [].
ḟ      Filter false; remove the elements of A or [] from A.
  L    Get the length of the resulting array.
       This yield len(A) if b = 0 and 0 if b = 1.
    +  Add b to all elements of A.
   ṭ   Tack; append the result to the left to the result to the right.

3

Python 2, 62 60 byte

x=0,
for n in input():x=[t-n+1for t in x]+[n*len(x)]
print x

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

Provalo su Ideone .


Ti serve la virgola x=0,?
ETHproductions

0,è una tupla. Senza la virgola, la mappatura su x fallirebbe.
Dennis,

Penso che puoi capovolgere nper fare [n*len(x)]e cambiare la mappa in un elenco comp.
xnor

@xnor Infatti. Grazie!
Dennis,

3

Python, 54 byte

lambda l:[i-i*x+sum(l[i:])for i,x in enumerate([1]+l)]

Utilizza la seguente procedura:

  1. Prepara un 1 all'elenco.
  2. Per ogni voce 0, scrivere la sua posizione nell'elenco 0 indicizzato.
  3. Per ogni voce, scrivi il numero di 1 alla sua destra, senza contare se stesso.
  4. Aggiungi i risultati dei passaggi 2 e 3 in senso orario.

Ad esempio, l=[1,0,1,0]f(l) == [2,1,3,0,4]

List with prepended 1         1 1 0 1 0

0-indexed position for 0's        2   4
Number of 1's to right        2 1 1 0 0
Sum of above two              2 1 3 0 4

Preparare uno 0 darebbe anche lo stesso risultato. Il enumerateè goffo, vedrò se può fare meglio in modo ricorsivo.


Tecnica intelligente! È affascinante come le diverse tecniche siano le migliori in ogni lingua. Ho provato a portarlo su JS, ma è finito a 57 a causa della mancanza sume della suddivisione della sintassi.
ETHproductions

3

JavaScript (ES6), 48 47 45 byte

a=>[h=l=0,...a.map(c=>c?--l:++h)].map(e=>e-l)

Questo si è rivelato simile al metodo di @ETHproductions, tranne per il fatto che avevo iniziato calcolando direttamente il primo elemento e quindi usando il vettore binario per determinare se ogni cifra è un nuovo massimo o un nuovo minimo. Modifica: salvato 1 byte grazie a @ETHproductions. Salvato 2 byte iniziando con zero e regolando in seguito. Il mio metodo precedente si è rivelato simile al metodo di @ Dennis, ma ha preso 54 byte:

a=>a.reduce((r,b)=>[...r.map(e=>b+e),r.length*!b],[0])

2

Perl, 33 byte

Include +1 per -p

Assegna il vettore come stringa senza spazi su STDIN:

antsy.pl <<< 110

antsy.pl:

#!/usr/bin/perl -p
s%^|.%y/0//+($&?++$a:$b--).$"%eg

2

JavaScript (ES6), 52 byte

v=>[...v,l=0].map(x=>x?l++:h--,h=v.length).reverse()

Provalo:

f=v=>[...v,l=0].map(x=>x?l++:h--,h=v.length).reverse()
g=v=>console.log(f((v.match(/[01]/g)||[]).map(x=>+x)))
<input oninput="g(this.value)" value="010">

Spiegazione

Ciò sfrutta il fatto che quando una permutazione antsy viene invertita, ogni elemento è 1 in più rispetto al massimo delle precedenti voci basse o 1 in meno del minimo delle precedenti voci alte. Denotando un oggetto superiore come a 0e un oggetto inferiore come a 1, possiamo creare una corrispondenza esatta uno a uno tra le permutazioni antsy della lunghezza n e i vettori binari della lunghezza n - 1 .

Il meglio che ho potuto fare con la tecnica di Dennis è di 57 51 byte:

v=>v.reduce((x,n)=>[...x.map(i=>i+n),!n*++j],[j=0])
v=>v.map(n=>x=[...x.map(i=>i+n),!n*++j],x=[j=0])&&x

La soluzione di xnor è 56 (1 byte salvato grazie a @Neil):

l=>[1,...l].map((x,i)=>i*!x+eval(l.slice(i).join`+`||0))

i-i*xpotrebbe essere i*!x.
Neil,

@Neil Ah sì, grazie.
ETHproductions


0

Lotto, 127 byte

@set s=%*
@set/an=h=l=%s: =+%
@for %%b in (%*)do @call:%%b
:0
@echo %n%
@set/an=h+=1
@exit/b
:1
@echo %n%
@set/an=l-=1

Accetta input come parametri della riga di comando, l'output è separato dalla riga. (È possibile inserire come spazio separato su STDIN senza costi aggiuntivi.)

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.