B u i l dan e s t


30

La sfida è semplice: scrivere un programma o una funzione che, quando viene dato un numero intero non negativo finito, genera un array nidificato.

Le regole

  • Il codice deve produrre un array nidificato valido univoco per ogni numero intero 0 ‌≤ n ‌ <2 31 .
  • Ogni possibile array nidificato con un massimo di 16 parentesi aperte deve essere emesso in questo intervallo. (Ciò non significa che il codice non possa mai generare un array nidificato con più di 16 parentesi aperte.)
  • Il codice può generare una rappresentazione in formato stringa dell'array nidificato anziché un array effettivo (con o senza virgole).

Una possibile mappatura:

0 -> []
1 -> [[]]
2 -> [[[]]]
3 -> [[], []]
4 -> [[[[]]]]
5 -> [[[], []]]
6 -> [[[]], []]
7 -> [[], [[]]]
8 -> [[], [], []]
9 -> [[[[[]]]]]
etc.

punteggio

Questo è , quindi vince il codice più breve in byte.


Ci sono restrizioni di tempo / memoria?
Dennis,

@Dennis 1 ora sembra ragionevole per un limite di tempo? Non ho idea di cosa sia ragionevole per la memoria.
ETHproductions,

La memoria non è un grosso problema se c'è un limite di tempo. Un'ora sembra molto generosa. Non vorrei aspettare un'ora intera per verificare se il mio codice è abbastanza veloce.
Dennis,

4
Preferirei senza limiti di tempo. Questo dà più spazio per l'originalità
Ton Hospel,

2
@TonHospel È possibile produrre senza virgole. Immagino che nessuna limitazione di tempo andrebbe bene, purché tu possa provare che la tua iscrizione è valida.
ETHproductions,

Risposte:


12

Python 2.7, 172 149 124 118 byte

x=input();y="";z=0
for b in bin(x)[2+(x<1):]:y+="[]"[b<"1"];z+=b>"0"or-1;z+=99*(z<0)
print"["+(y,"[]"*(x+16))[z>0]+"]"

Spiegazione:

Definire una biiezione di [1e ]0. Qualsiasi disposizione di parentesi può quindi essere scritta come un numero binario e viceversa, ad esempio [][]1010(10) e [[][]]110100(52). Tutte le disposizioni valide per un massimo di 15 parentesi aperte (30 parentesi in totale) sono coperte da numeri con un massimo di 30 bit (ignorando gli zeri iniziali), che sono precisamente i numeri inferiori a 2 31 .

Il primo for-loop fornisce l'inverso di questa biiezione, convertendo un numero in una disposizione di parentesi, mentre verifica che la disposizione sia valida.

Le disposizioni non valide vengono sostituite all'interno dell'istruzione di stampa da lunghe sequenze di parentesi per evitare collisioni. Ad esempio 11(3) ↔ [[non è valido, quindi concateniamo 3 + 16 parentesi. Questo assicura che tutti gli arrangiamenti siano unici.

La disposizione risultante viene inserita in una coppia di parentesi quadre per creare un array nidificato, in modo che 1010(10) diventi [[][]]e 110100(52) diventi [[[][]]]. La parentesi aperta extra significa che ora abbiamo coperto tutte le matrici con 16 parentesi aperte.


Il seguente programma può essere utilizzato per determinare il numero di un determinato array con un massimo di 16 parentesi.

s=raw_input();o="";
for c in s[1:-1]:
 if c=="[":o+="1"
 if c=="]":o+="0"
print int(o,2)

Un bel abuso dell'intento dell'operazione quando ha specificato "unico"
Ton Hospel il

Questo è solo geniale. Molto bene. (E è consentito un formato senza virgola.)
ETHproductions

12

Python, 153 128 byte

s=l=0;r="";n=input()
for d in bin(n)[2:]*(n>0):c=d<"1";l=[l,s>1][c];r+="]"*c+(1-l*c)*"[";s+=1-c-l*c
print"["+r+"["*l+"]"*(s+l+1)

Mappiamo un numero n su un elenco nidificato osservando le sue cifre binarie da sinistra a destra. Questo algoritmo funziona per qualsiasi numero, non solo per 2 32 .

  1. Se la cifra binaria corrente è un 1, emettere [.
  2. Altrimenti, se la sequenza di parentesi che abbiamo emesso finora sarebbe bilanciata da una singola parentesi di chiusura, output ][.
  3. Altrimenti, se questo è l'ultimo 0 nel numero binario, output ][.
  4. Altrimenti uscita ].

Infine, chiudiamo tutte le parentesi aperte.


5

Spoon , 63 byte (501 bit)

000001001001001011001101001010011011111001010001000000101010
101101100110100101101001000101100010001000000100011000010000
000000000000001110111110010000001110110110010100100100100100
000110011010001000000110110000010000001010110011011011011001
000000011010010010010001000000111011011011101001001001000110
110110010100100101011001000100000011010001000000111011011001
010010010010010001101101101001000110110010110001101101101101
100100010001010010001010011011001000000011001101001001010010
000001100101001000111

Questo è il seguente programma Brainfuck convertito in cucchiaio:

-[+[+<]>>+]<+++.[->+>+<<]>>++>>,[>-[<->-----]+<+++[-<+<<.>>>>-<]>[-<<-[->+<]<<<[-]>>>>[-<+<<<+>>>>]<<.>>+<[>-]>[-<+<<.>>>>]<<>>]<,]<<<<[>.>.<<[-]]>>>+[-<.>]+

Legge un numero intero in binario su stdin e genera l'elenco nidificato su stdin. Richiede 0 come input come stringa vuota (senza cifre) e richiede un interprete brainfuck con celle a 8 bit. Stesso algoritmo della mia risposta Python.

Versione leggibile:

-[+[+<]>>+]<+++.           push open bracket and print it
[->+>+<<]                  dup
>>++                       increment to close bracket

>>,[                       read input loop
    >-[<->-----]+<+++          subtract 48 and set up if/else
    [-                         if c == 1
        <+                         increment s
        <<.>>>                     output open bracket
    >-<]>[-<                   else
        <-[->+<]                   decrement and move s
        <<<[-]                     zero l
        >>>>[-<+<<<+>>>>]          l = s and restore s
        <<.>                       output close bracket
        >+<[>-]>[-                 if s == 0
            <+                         undo s decrement
            <<.                        output open bracket
        >>>>]<<
    >>]<
,]

<<<<[                      if l
    >.>.                   output pair
<<[-]]
>>>+[-<.>]                 output close bracket s+1 times

3
Recentemente abbiamo avuto questa discussione su un'altra risposta, e sembra che non ci sia un vero intrepreter in grado di gestire un file a 63 byte. L'implementazione di riferimento utilizzava i byte 0x30 e 0x31, quindi questa risposta avrebbe richiesto un file di 501 byte .
Dennis,

5

Gelatina , 28 byte

ḃ2-*µSN;+\>-Ạ
1Ç#Ṫḃ2ṭ2;1ị⁾][

Questo itera su tutte le stringhe dei personaggi [e ]che iniziano con una [e alla fine con un ], verifica se le staffe corrispondono, e stampa il n ° partita.

Provalo online!


5

Perl, 80 79 byte

Usa ancora l'algoritmo di orlp , ma questa volta ho prima verificato se funziona ...

Include +1 per -p

Fornire il numero di input su STDIN

nest.pl <<< 8

nest.pl:

#!/usr/bin/perl -p
($_=sprintf"%b",$_).=2x(s^.^$&or++$n-pos&&/.0/g?++$n%1:$`&&21^eg-$n);y;102;();

La soluzione di Linus è di 64 byte in perl:

#!/usr/bin/perl -p
$_=sprintf"%b",/.+/g;$_=10x($&&&$&+16)if!/^(1(?1)*0)+$/;y;10;()

La soluzione di Dennis è di 59 byte in perl (sempre più lenta per grandi numeri):

#!/usr/bin/perl -p
1while$_-=(sprintf"%b",$n++)=~/^(1(?1)*0)+$/;$_=$&;y;10;()

Sento che dovresti segnare questo come 65 byte (in realtà non è 64)?
Linus,

1
@Linus Mentre schivare le tue regole è geniale e merita tutti i suoi voti, lo considero un po 'un imbroglione. Per -p
calcolare

5

Python 3, 120 114 byte

def f(n,k=0):
 while~n:
  k+=1
  try:r=eval(bin(k).translate({48:'],',49:'['})[3:-1])+[];n-=1
  except:0
 print(r)

Provalo su Ideone .

Come funziona

La funzione definita f accetta l'ingresso n e inizializza k su 0 . Continueremo ad incrementare k fino a quando n + 1 valori di k genereranno un output valido. Ogni volta che troviamo tale valore di k , n viene diminuito quando raggiunge -1 , ~nproduce 0 e viene stampato l'elenco r che corrisponde all'ultimo valore di k .

La mappatura parziale dagli interi positivi agli elenchi nidificati (ad esempio, k ↦ r ) deve essere biiettiva, ma non ci sono altri vincoli. Quello usato in questa risposta funziona come segue.

  1. Converti k in una rappresentazione di stringa binaria, fissando con 0b .

    Ad esempio, 44 ↦ "0b101100" .

  2. Sostituisci tutti gli 0 (punto di codice 48 ) nella rappresentazione di stringa con la stringa "]," e tutti gli 1 (punto di codice 49 ) con [ .

    Ad esempio, "0b101100" ↦ "], b [], [[],]," .

  3. Rimuovi i primi tre caratteri (corrispondono a "0b" ) e il carattere finale (si spera una virgola).

    Ad esempio, "], b [], [[],]," ↦ "[], [[],]" .

  4. Prova a valutare il codice generato. Se ciò provoca un errore, k non è associato a nessun elenco.

    Ad esempio, "[], [[],]" ↦ ([], [[]]) .

  5. Concatena il risultato (se presente) con l'elenco vuoto. Se ciò provoca un errore, k non è associato a nessun elenco.

    Ad esempio, ([], [[]]) + [] errori poiché + non può concatenare elenchi e tuple.


4

Haskell, 71 byte

p 1=["[]"]
p n=['[':h++t|k<-[1..n-1],h<-p k,_:t<-p$n-k]
((p=<<[1..])!!)

La funzione principale sull'ultima riga viene indicizzata in un elenco di tutte le matrici nidificate, ordinate per dimensione (numero di parentesi aperte). Quindi, tutti gli array di dimensioni al massimo di 16 sono elencati per primi.

Diamo prima un'occhiata al codice che è più bello e più breve, ma il typeckecker di Haskell rifiuta di accettare.

p 1=[[]]
p n=[h:t|k<-[1..n-1],h<-p k,t<-p$n-k]
((p=<<[1..])!!)

La funzione psull'input nfornisce un elenco di tutte le matrici di dimensioni nidificate n(parentesi aperte). Questo è fatto in modo ricorsivo. Ciascuno di questi array è costituito da una testa h(primo membro) di dimensioni ke una coda t(altri membri) di dimensioni n-k, entrambe dimensioni diverse da zero. O è l'array vuoto per dimensione n==1.

L'espressione p=<<[1..]si appiattisce quindi p(1), p(2), ...in un unico elenco infinito di tutte le matrici ordinate per dimensione

[ [], [[]], [[],[]], [[[]]], [[],[],[]], [[],[[]]], [[[]],[]], [[[],[]]], ...

e la funzione principale si indicizza in essa.

... O, se Haskell non si lamentasse di "costruire [ing] il tipo infinito: t ~ [t]". Haskell non può rappresentare l'elenco infinito sopra i cui elementi sono array nidificati arbitrariamente. Tutti i suoi elementi devono avere lo stesso tipo, ma un tipo t non può essere uguale a un elenco di t. In effetti, alla funzione pstessa non può essere assegnato un tipo coerente senza la digitazione dipendente, che manca a Haskell.

Quindi, invece, lavoriamo su stringhe di parentesi, simulando l'operazione contro agendo [e ]caratteri. Questo richiede 9 byte extra. I pericoli del golf in un linguaggio sicuro.


3

Haskell, 87 82 byte

0#0=[""]
n#m=['[':x|n>0,x<-(n-1)#m]++[']':x|n<m,x<-n#(m-1)]
(([0..]>>= \y->y#y)!!)

Emette gli elementi dell'array. Esempio di utilizzo: (([0..]>>= \y->y#y)!!) 3-> "[][]".

La funzione #crea tutte le matrici nidificate come stringhe per parentesi quadre naperte e mchiuse, tenendo traccia di quante parti sono rimaste. Inizia sempre con n == m. La funzione principale chiama y # yper ogni y <- [0,1,...]e seleziona l'elemento nell'indice fornito dall'input.


2

MATL , 31 byte

O`@BEqXJYs0&)0>w~hA+tG>~]x92J-c

Provalo online! Oppure verifica i primi casi di test (richiede alcuni secondi).

La mappatura prodotta è:

0 -> []
1 -> [[]]
2 -> [[][]]
3 -> [[[]]]
4 -> [[][][]]
5 -> [[][[]]]
6 -> [[[]][]]
7 -> [[[][]]]
...

Spiegazione

Il codice continua a testare numeri binari in aumento, con la cifra 0sostituita da -1; cioè usando 1e -1come cifre. La cifra 1rappresenterà '['e -1rappresenterà ']'.

Il programma conta fino a quando non si ottengono n +1 numeri validi . Un numero è valido se valgono le due seguenti condizioni:

  1. La somma delle cifre è zero (ovvero, esiste un numero uguale di 1e -1)
  2. La somma cumulativa delle cifre è sempre positiva (ovvero, il numero accumulato di 1cifre supera sempre quello di -1) tranne alla fine (dove è zero per condizione 1).

Una volta ottenuti n +1 numeri validi, l'ultimo viene traslitterato cambiando 1in [e -1in ], quindi viene visualizzato.

Codice:

O          % Push 0: initial count of valid numbers
`          % Do...while
  @        %   Push iteretation index k, starting at 1
  B        %   Convert to binary. For example, k=6 gives [1 1 0 0]
  Eq       %   Multiply by 2, subtract 1: transforms [1 1 0 0] into [1 1 -1 -1]
  XJ       %   Copy that to clipboard J, without popping it
  Ys       %   Cumulative sum: gives [1 2 1 0]
  0&)      %   Split array into its final element and the rest. Gives 0, [1 2 1]
  0>       %   Yields 1 for positive entries (condition 2). So in this case it
           %   gives [1 1 1]
  w        %   Swap: moves second-top element in the stack (0 in this case) to top
  ~        %   Negate: yields 1 if input is 0 (condition 1). Gives 1 in this case
  h        %   Concatenate horizontally. Gives [1 1 1 1]
  A        %   All: gives 1 if all elements are 1. Gives 1 in this case, meaning
           %   that this k is valid
  +        %   Add the result (0 or 1) to the count of valid numbers
  t        %   Duplicate
  G        %   Push input n
  >~       %   Loop condition: false (exit loop) if count exceeds input n
]          % End loop. At this point the result is in clipboard J, in 1/-1 format
x          % Delete count
92         % Push 92. Will be used to convert 1, -1 to '[', ']' (ASCII 91, 93)
J          % Push result in 1/-1 format
-          % Subtract: converts 1 to 91, -1 to 93
c          % Convert to char. Implicitly display
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.