B u i l dan e s t

30

Die Herausforderung ist einfach: Schreiben Sie ein Programm oder eine Funktion, die bei einer endlichen nicht-negativen Ganzzahl ein verschachteltes Array ausgibt.

Die Regeln

  • Ihr Code muss für jede Ganzzahl 0 ‌≤ n ‌ <2 31 ein eindeutiges gültiges verschachteltes Array erzeugen .
  • Innerhalb dieses Bereichs muss jedes mögliche verschachtelte Array mit bis zu 16 offenen Klammern ausgegeben werden. (Dies bedeutet nicht, dass Ihr Code niemals ein verschachteltes Array mit mehr als 16 offenen Klammern ausgeben kann.)
  • Ihr Code gibt möglicherweise eine Zeichenfolgendarstellung des verschachtelten Arrays anstelle eines tatsächlichen Arrays (mit oder ohne Kommas) aus.

Eine mögliche Zuordnung:

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

Wertung

Das ist , also gewinnt der kürzeste Code in Bytes.

ETHproductions
quelle
Gibt es Zeit- / Speicherbeschränkungen?
Dennis
@ Tennis Scheint 1 Stunde für eine zeitliche Beschränkung angemessen? Ich habe keine Ahnung, was für ein Gedächtnis angemessen ist.
ETHproductions
Speicher ist keine große Sache, wenn es ein Zeitlimit gibt. Eine Stunde scheint sehr großzügig. Ich möchte nicht eine volle Stunde warten, um zu überprüfen, ob mein Code schnell genug ist.
Dennis
4
Ich würde keine zeitlichen Einschränkungen bevorzugen. Das gibt mehr Spielraum für Originalität
Ton Hospel
2
@TonHospel Sie können ohne Komma ausgeben. Ich denke, keine zeitlichen Einschränkungen wären in Ordnung, solange Sie nachweisen können, dass Ihre Eingabe gültig ist.
ETHproductions

Antworten:

12

Python 2.7, 172 149 124 118 Bytes

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]+"]"

Erläuterung:

Definieren Sie eine Bijektion mit [1und ]0. Jede Anordnung von Klammern kann dann als Binärzahl geschrieben werden und umgekehrt, zum Beispiel [][]1010(10) und [[][]]110100(52). Alle gültigen Anordnungen von bis zu 15 offenen Klammern (insgesamt 30 Klammern) werden durch Zahlen mit bis zu 30 Bits (ohne führende Nullen) abgedeckt, bei denen es sich genau um Zahlen unter 2 31 handelt .

Die erste for-Schleife gibt die Umkehrung dieses Bijektors an und konvertiert eine Zahl in eine Anordnung von Klammern, während überprüft wird, ob die Anordnung gültig ist.

Ungültige Anordnungen werden in der Druckanweisung durch lange Reihen von Klammern ersetzt, um Kollisionen zu vermeiden. Zum Beispiel ist 11(3) ↔ [[nicht gültig, also verketten wir stattdessen 3 + 16 Klammern. Dies stellt sicher, dass alle Arrangements einzigartig sind.

Die resultierende Anordnung wird in ein Paar von Klammern gesetzt, um ein verschachteltes Array zu bilden, so dass 1010(10) wird [[][]]und 110100(52) wird [[[][]]]. Die zusätzliche offene Klammer bedeutet, dass wir jetzt alle Arrays mit 16 offenen Klammern abgedeckt haben.


Das folgende Programm kann verwendet werden, um die Nummer für ein bestimmtes Array mit bis zu 16 Klammern zu ermitteln.

s=raw_input();o="";
for c in s[1:-1]:
 if c=="[":o+="1"
 if c=="]":o+="0"
print int(o,2)
Linus
quelle
Ein netter Missbrauch der Absicht des Ops, als er "einzigartig" spezifizierte
Ton Hospel
Das ist einfach genial. Gut gemacht. (Ein Format ohne Komma ist zulässig.)
kommaloses
12

Python, 153 128 Bytes

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)

Wir ordnen einer verschachtelten Liste eine Zahl n zu, indem wir ihre Binärziffern von links nach rechts betrachten. Dieser Algorithmus funktioniert für jede Zahl, nicht nur für unter 2 32 .

  1. Wenn die aktuelle Binärzahl eine 1 ist, wird ausgegeben [.
  2. Andernfalls würde die Abfolge der bisher ausgegebenen Klammern durch eine einzige schließende Klammer ausgeglichen ][.
  3. Andernfalls wird ausgegeben, wenn dies die letzte 0 in der Binärzahl ist ][.
  4. Sonst Ausgabe ].

Zum Schluss schließen wir alle geöffneten Klammern.

orlp
quelle
5

Löffel , 63 Bytes (501 Bits)

000001001001001011001101001010011011111001010001000000101010
101101100110100101101001000101100010001000000100011000010000
000000000000001110111110010000001110110110010100100100100100
000110011010001000000110110000010000001010110011011011011001
000000011010010010010001000000111011011011101001001001000110
110110010100100101011001000100000011010001000000111011011001
010010010010010001101101101001000110110010110001101101101101
100100010001010010001010011011001000000011001101001001010010
000001100101001000111

Dies ist das folgende Brainfuck-Programm, das in Löffel umgewandelt wurde:

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

Liest eine Ganzzahl in binär auf stdin und gibt die verschachtelte Liste auf stdin aus. Erfordert die Eingabe von 0 als leere Zeichenfolge (keine Ziffern) und einen Brainfuck-Interpreter mit 8-Bit-Zellen. Gleicher Algorithmus wie meine Python-Antwort.

Lesbare Version:

-[+[+<]>>+]<+++.           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
orlp
quelle
3
Wir haben diese Diskussion kürzlich über eine andere Antwort geführt, und es scheint keinen tatsächlichen Intrepreter zu geben, der in der Lage ist, eine 63-Byte-Datei zu verarbeiten. Die Referenzimplementierung verwendete die Bytes 0x30 und 0x31, sodass für diese Antwort eine 501- Byte- Datei erforderlich wäre .
Dennis
5

Gelee , 28 Bytes

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

Diese iteriert über alle Saiten der Zeichen [und ]beginnen mit dem [und am Ende mit einem ], überprüft , ob die Klammern entsprechen, und druckt die n - te Spiel.

Probieren Sie es online!

Dennis
quelle
5

Perl, 80 79 Bytes

Verwendet wieder den Algorithmus von orlp , aber dieses Mal habe ich zuerst geprüft, ob es funktioniert ...

Beinhaltet +1 für -p

Geben Sie die Eingangsnummer für STDIN ein

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

Linus 'Lösung ist 64 Bytes in Perl:

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

Dennis 'Lösung ist 59 Bytes in Perl (zunehmend langsamer für große Zahlen):

#!/usr/bin/perl -p
1while$_-=(sprintf"%b",$n++)=~/^(1(?1)*0)+$/;$_=$&;y;10;()
Tonne Hospel
quelle
Ich habe das Gefühl, Sie sollten dies einfach mit 65 Bytes bewerten (ist es nicht tatsächlich 64)?
Linus
1
@Linus Während Ihre Regeln ausweichen ist brillant und verdient all seine Upvotes, halte ich es ein bisschen ein Betrüger. Für die Wertung wird das -pals 1 extra Byte gezählt
Ton Hospel
5

Python 3, 120 114 Bytes

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)

Teste es auf Ideone .

Wie es funktioniert

Die definierte Funktion f nimmt den Eingang n und initialisiert k auf 0 . Wir werden k so lange inkrementieren, bis n + 1 Werte von k eine gültige Ausgabe ergeben. Jedes Mal, wenn wir einen solchen Wert von k finden , wird n dekrementiert, sobald es -1 erreicht , ~nergibt 0 und die Liste r , die dem letzten Wert von k entspricht wird gedruckt.

Die teilweise Zuordnung der positiven Ganzzahlen zu verschachtelten Listen (dh k ↦ r ) muss bijektiv sein, es gibt jedoch keine anderen Einschränkungen. Die in dieser Antwort verwendete Methode funktioniert wie folgt.

  1. Wandle k in eine binäre Zeichenfolgendarstellung um und starre mit 0b .

    Zum Beispiel 44 ≤ "0b101100" .

  2. Ersetzen Sie alle 0 's (Codepunkt 48 ) in der String - Darstellung mit der Zeichenkette "]" , und all 1 ' s (Codepunkt 49 ) mit [ .

    Zum Beispiel "0b101100" ↦ "], b [], [[],]," .

  3. Entfernen Sie die ersten drei Zeichen (sie entsprechen "0b") ) und das Zeichen (hoffentlich ein Komma).

    Zum Beispiel "], b [], [[],]," ↦ "[], [[],]" .

  4. Versuchen Sie, den generierten Code auszuwerten. Wenn dies zu einem Fehler führt, wird k keiner Liste zugeordnet.

    Zum Beispiel "[], [[],]" ↦ ([], [[]]) .

  5. Verketten Sie das Ergebnis (falls vorhanden) mit der leeren Liste. Wenn dies zu einem Fehler führt, wird k keiner Liste zugeordnet.

    Zum Beispiel ([], []]) + [] Fehler, da + Listen und Tupel nicht verketten kann.

Dennis
quelle
4

Haskell, 71 Bytes

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

Die Hauptfunktion in der letzten Zeile indiziert eine Liste aller verschachtelten Arrays, sortiert nach Größe (Anzahl der offenen Klammern). Daher werden alle Arrays mit einer Größe von höchstens 16 zuerst aufgelistet.

Schauen wir uns zuerst Code an, der schöner und kürzer ist, aber Haskells Typechecker lehnt es ab, ihn zu akzeptieren.

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

Die Funktion pbei der Eingabe ngibt eine Liste aller verschachtelten Arrays der Größe n(offene Klammern). Dies erfolgt rekursiv. Jedes solche Array besteht aus einem Kopf h(erstes Glied) von Größe kund einem Schwanzt (andere Elemente) der Größe n-k, wobei beide Größen ungleich Null sind. Oder es ist das leere Array für die Größe n==1.

Der Ausdruck wird p=<<[1..]dann flacherp(1), p(2), ... zu einer einzigen unendlichen Liste aller Arrays, sortiert nach Größe, zusammengefasst

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

und die Hauptfunktion indiziert es.

... Oder es wäre, wenn Haskell nicht darüber jammern würde, "den unendlichen Typ zu konstruieren: t ~ [t]". Haskell kann die unendliche Liste nicht darstellen, deren Elemente willkürlich verschachtelte Arrays sind. Alle seine Elemente müssen denselben Typ haben, ein Typ t kann jedoch nicht mit einer Liste von t identisch sein. In der Tat ist die Funktionp selbst kein konsistenter Typ ohne abhängige Typisierung zugewiesen werden, der Haskell fehlt.

Also arbeiten wir stattdessen an Klammerfolgen und simulieren die Nachteile, indem wir auf [und ]Zeichen einwirken . Dies benötigt zusätzliche 9 Bytes. Die Gefahren des Golfspiels in einer typsicheren Sprache.

xnor
quelle
3

Haskell, 87 82 Bytes

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

Gibt die Array-Elemente aus. Anwendungsbeispiel: (([0..]>>= \y->y#y)!!) 3-> "[][]".

Function erstellt #alle verschachtelten Arrays als Zeichenfolgen für noffene und mgeschlossene Klammern, indem protokolliert wird, wie viele davon noch übrig sind. Beginnt immer mit n == m. Die Hauptfunktion ruft y # yjeden auf y <- [0,1,...]und wählt das Element an dem von der Eingabe angegebenen Index aus.

nimi
quelle
2

MATL , 31 Bytes

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

Probieren Sie es online! Oder überprüfen Sie die ersten Testfälle (dauert einige Sekunden).

Das erstellte Mapping ist:

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

Erläuterung

Der Code testet immer mehr Binärzahlen, wobei die Ziffer 0durch ersetzt wird -1. das heißt, mit 1und -1als Ziffern. Die Ziffer 1repräsentiert '['und -1repräsentiert ']'.

Das Programm zählt, bis n + 1 gültige Nummern erhalten wurden. Eine Zahl ist gültig, wenn die folgenden zwei Bedingungen erfüllt sind:

  1. Die Summe der Ziffern ist Null (dh es gibt eine gleiche Anzahl von 1und -1)
  2. Die kumulative Ziffernsumme ist immer positiv (das heißt, die akkumulierte 1Ziffernanzahl übersteigt immer die von -1), außer am Ende (wo sie gemäß Bedingung 1 Null ist).

Sobald n + 1 gültige Zahlen erhalten wurden, wird die letzte durch Ändern 1in [und -1in transliteriert] und dann angezeigt.

Code:

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
Luis Mendo
quelle