B u i l dan e s t

30

Tantangannya sederhana: menulis sebuah program atau fungsi yang, ketika diberi bilangan bulat non-negatif terbatas, menghasilkan array bersarang.

Aturan

  • Kode Anda harus menghasilkan array bertingkat valid unik untuk setiap bilangan bulat 0 ‌≤ n ‌ <2 31 .
  • Setiap kemungkinan array bersarang dengan hingga 16 tanda kurung terbuka harus dikeluarkan dalam kisaran ini. (Ini tidak berarti bahwa kode Anda tidak pernah dapat menghasilkan array bersarang dengan lebih dari 16 tanda kurung terbuka.)
  • Kode Anda dapat menampilkan representasi string dari array bersarang alih-alih array yang sebenarnya (dengan atau tanpa koma).

Satu pemetaan yang mungkin:

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

Mencetak gol

Ini adalah , jadi kode terpendek dalam byte menang.

Produksi ETH
sumber
Apakah ada batasan waktu / memori?
Dennis
@ Dennis Apakah 1 jam tampaknya masuk akal untuk pembatasan waktu? Saya tidak tahu apa yang masuk akal untuk memori.
ETHproduk
Memori bukan masalah besar jika ada batas waktu. Satu jam sepertinya sangat murah hati. Saya tidak ingin menunggu satu jam penuh untuk memverifikasi apakah kode saya cukup cepat.
Dennis
4
Saya lebih suka tidak ada batasan waktu. Itu memberi lebih banyak ruang untuk orisinalitas
Ton Hospel
2
@TonHospel Anda dapat membuat output tanpa koma. Saya kira tidak ada batasan waktu akan baik-baik saja, selama Anda dapat membuktikan bahwa entri Anda valid.
Produksi ETH

Jawaban:

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

Penjelasan:

Tentukan sebuah bijection oleh [1dan ]0 . Pengaturan kurung kemudian dapat ditulis sebagai angka biner dan sebaliknya, misalnya [][]1010(10) dan [[][]]110100(52). Semua pengaturan yang valid hingga 15 tanda kurung terbuka (total tanda kurung 30) dicakup oleh angka hingga 30 bit (mengabaikan angka nol di depan), yang jumlahnya tepatnya kurang dari 2 31 .

For-loop pertama memberikan kebalikan dari bijection ini, mengubah angka menjadi susunan kurung, sambil memeriksa bahwa susunan itu valid.

Pengaturan yang tidak valid diganti dalam pernyataan cetak dengan urutan kurung yang panjang untuk menghindari tabrakan. Misalnya 11(3) ↔ [[tidak valid sehingga kami menggabungkan 3 + 16 tanda kurung. Ini memastikan semua pengaturan unik.

Pengaturan yang dihasilkan ditempatkan dalam sepasang tanda kurung untuk membuat array bersarang, sehingga 1010(10) menjadi [[][]]dan 110100(52) menjadi [[[][]]]. Braket ekstra terbuka berarti kita sekarang telah menutupi semua array dengan 16 tanda kurung terbuka.


Program berikut dapat digunakan untuk mencari tahu angka untuk array yang diberikan hingga 16 tanda kurung.

s=raw_input();o="";
for c in s[1:-1]:
 if c=="[":o+="1"
 if c=="]":o+="0"
print int(o,2)
Linus
sumber
Pelecehan yang bagus terhadap maksud op ketika dia menyebutkan "unik"
Ton Hospel
Itu hanya jenius. Sudah selesai dilakukan dengan baik. (Dan format tanpa koma diperbolehkan.)
ETHproduksi
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)

Kami memetakan nomor n ke daftar bersarang dengan melihat angka binernya dari kiri ke kanan. Algoritma ini berfungsi untuk angka apa pun, tidak hanya di bawah angka 2 32 .

  1. Jika digit biner saat ini adalah 1, output [.
  2. Kalau tidak, jika urutan kurung yang telah kami hasilkan sejauh ini akan seimbang dengan braket penutup tunggal, keluaran ][.
  3. Jika tidak, jika ini adalah 0 terakhir dalam angka biner, hasilkan ][ .
  4. Jika tidak, output ].

Akhirnya, kami menutup tanda kurung yang terbuka.

orlp
sumber
5

Sendok , 63 byte (501 bit)

000001001001001011001101001010011011111001010001000000101010
101101100110100101101001000101100010001000000100011000010000
000000000000001110111110010000001110110110010100100100100100
000110011010001000000110110000010000001010110011011011011001
000000011010010010010001000000111011011011101001001001000110
110110010100100101011001000100000011010001000000111011011001
010010010010010001101101101001000110110010110001101101101101
100100010001010010001010011011001000000011001101001001010010
000001100101001000111

Ini adalah program brainfuck berikut yang dikonversi menjadi sendok:

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

Membaca bilangan bulat dalam biner pada stdin, dan menampilkan daftar bersarang di stdin. Membutuhkan 0 menjadi input sebagai string kosong (tanpa digit), dan membutuhkan juru bahasa brainfuck dengan sel 8-bit. Algoritma yang sama dengan jawaban Python saya.

Versi yang dapat dibaca:

-[+[+<]>>+]<+++.           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
sumber
3
Kami baru-baru ini mengadakan diskusi ini pada jawaban lain, dan sepertinya tidak ada intrepreter aktual yang mampu menangani file 63-byte. Implementasi referensi menggunakan byte 0x30 dan 0x31, jadi jawaban ini akan membutuhkan file 501 byte .
Dennis
5

Jelly , 28 byte

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

Ini mengulangi semua string karakter [dan ]yang dimulai dengan a [dan diakhiri dengan a ], memverifikasi apakah tanda kurung cocok, dan mencetak kecocokan ke- n .

Cobalah online!

Dennis
sumber
5

Perl, 80 79 byte

Sekali lagi menggunakan algoritma orlp , tapi kali ini saya pertama kali memeriksa apakah itu berfungsi ...

Termasuk +1 untuk -p

Berikan nomor input pada 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;();

Solusi Linus adalah 64 byte dalam perl:

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

Solusi Dennis adalah 59 byte dalam perl (semakin lambat untuk jumlah besar):

#!/usr/bin/perl -p
1while$_-=(sprintf"%b",$n++)=~/^(1(?1)*0)+$/;$_=$&;y;10;()
Ton Hospel
sumber
Saya merasa Anda hanya perlu skor ini sebagai 65 byte, (bukan 64 sebenarnya)?
Linus
1
@Linus Sementara aturan Anda menghindar adalah brilian dan layak mendapatkan semua upvotes-nya, saya menganggapnya sedikit curang. Untuk penilaian -pdihitung sebagai 1 byte tambahan
Ton Hospel
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)

Cobalah Ideone .

Bagaimana itu bekerja

Fungsi yang didefinisikan f mengambil input n dan menginisialisasi k ke 0 . Kami akan terus meningkatkan k hingga n + 1 nilai k menghasilkan output yang valid. Setiap kali kita menemukan nilai k , n akan dikurangi begitu mencapai -1 , ~nmenghasilkan 0 , dan daftar r yang sesuai dengan nilai terakhir k dicetak.

Pemetaan parsial dari bilangan bulat positif ke daftar bersarang (yaitu, k ↦ r ) harus bijective, tetapi tidak ada kendala lain. Yang digunakan dalam jawaban ini beroperasi sebagai berikut.

  1. Konversikan k ke representasi string biner, menatap dengan 0b .

    Misalnya, 44 ↦ "0b101100" .

  2. Ganti semua 0 (titik kode 48 ) dalam representasi string dengan string "]," dan semua 1 (titik kode 49 ) dengan [ .

    Misalnya, "0b101100" ↦ "], b [], [[],]," .

  3. Hapus tiga karakter pertama (sesuai dengan "0b" ) dan karakter trailing (semoga koma).

    Misalnya, "], b [], [[],]," ↦ "[], [[],]" .

  4. Coba evaluasi kode yang dihasilkan. Jika ini menghasilkan kesalahan, k tidak dipetakan ke daftar mana pun.

    Misalnya, "[], [[],]" ↦ ([], [[]]) .

  5. Gabungkan hasilnya (jika ada) dengan daftar kosong. Jika ini menghasilkan kesalahan, k tidak dipetakan ke daftar mana pun.

    Misalnya, ([], [[]]) + [] kesalahan karena + tidak dapat menggabungkan daftar dan tupel.

Dennis
sumber
4

Haskell, 71 byte

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

Fungsi utama pada baris terakhir mengindeks ke dalam daftar semua array bersarang, diurutkan berdasarkan ukuran (jumlah tanda kurung terbuka). Jadi, semua array ukuran paling banyak 16 terdaftar terlebih dahulu.

Pertama mari kita lihat kode yang lebih bagus dan lebih pendek, tetapi typechecker Haskell menolak untuk menerima.

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

Fungsi ppada input nmemberikan daftar semua ukuran array bersarang n(kurung terbuka). Ini dilakukan secara rekursif. Setiap array tersebut terdiri dari beberapa kepala h(anggota pertama) ukuran kdan beberapa ekor t(anggota lainnya) ukuran n-k, keduanya ukuran nol. Atau, ini adalah array kosong untuk ukuran n==1.

Ekspresi p=<<[1..]kemudian diratakan p(1), p(2), ...menjadi daftar tak terbatas tunggal dari semua array yang diurutkan berdasarkan ukuran

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

dan indeks fungsi utama ke dalamnya.

... Atau, itu akan, jika Haskell tidak mengeluh tentang "membangun tipe tak terbatas: t ~ [t]". Haskell tidak dapat mewakili daftar tanpa batas di atas yang elemen-elemennya adalah array bersarang secara sewenang-wenang. Semua elemennya harus memiliki tipe yang sama, tetapi tipe t tidak boleh sama dengan daftar t. Padahal, fungsinyap itu sendiri tidak dapat ditetapkan sebagai tipe yang konsisten tanpa pengetikan dependen, yang tidak dimiliki Haskell.

Jadi, alih-alih kami bekerja pada deretan tanda kurung, mensimulasikan operasi kontra dengan akting [dan ]karakter. Ini membutuhkan tambahan 9 byte. Bahaya bermain golf dalam bahasa yang aman.

Tidak
sumber
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)!!)

Output elemen array. Contoh penggunaan: (([0..]>>= \y->y#y)!!) 3-> "[][]".

Function #membangun semua array bersarang sebagai string untuk tanda kurung nbuka dan mtutup, dengan melacak jumlah masing-masing array yang tersisa. Selalu dimulai dengan n == m. Fungsi utama memanggil y # ysetiap y <- [0,1,...]dan mengambil elemen pada indeks yang diberikan oleh input.

nimi
sumber
2

MATL , 31 byte

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

Cobalah online! Atau verifikasi beberapa kasus uji pertama (butuh beberapa detik).

Pemetaan yang dihasilkan adalah:

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

Penjelasan

Kode terus menguji peningkatan angka biner, dengan digit 0digantikan oleh -1; yaitu, menggunakan 1dan -1sebagai digit. Digit 1akan mewakili '['dan -1akan mewakili ']'.

Program menghitung sampai n +1 angka yang valid telah diperoleh. Angka valid jika dua kondisi berikut berlaku:

  1. Jumlah digit adalah nol (yaitu, ada jumlah yang sama dengan 1dan -1)
  2. Jumlah kumulatif digit selalu positif (yaitu, akumulasi jumlah 1digit selalu melebihi dari -1) kecuali pada akhirnya (di mana nol dengan kondisi 1).

Setelah n +1 angka yang valid telah diperoleh, yang terakhir ditransliterasikan dengan mengubah 1ke [dan -1ke] , dan kemudian ditampilkan.

Kode:

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
sumber