B u ı s ı z Dan E t


30

Zorluk basittir: sınırlı negatif olmayan bir tamsayı verildiğinde iç içe geçmiş bir dizi çıktısı alan bir program veya işlev yazın.

Kurallar

  • Kodunuz 0 0 n ‌ <2 31 her tamsayı için benzersiz bir geçerli yuvalanmış dizi oluşturmalıdır .
  • 16'ya kadar açık parantezle mümkün olan her iç içe dizi bu aralık içinde çıkarılmalıdır. (Bu, kodunuzun 16'dan fazla açık parantez içeren iç içe bir diziyi asla çıkarmayacağı anlamına gelmez.)
  • Kodunuz, gerçek bir dizi yerine iç içe dizinin dize olarak gösterilmesini sağlayabilir (virgüllü veya virgül olmadan).

Bir olası haritalama:

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

puanlama

Bu , yani bayt cinsinden en kısa kod kazanır.


Herhangi bir zaman / bellek kısıtlaması var mı?
Dennis,

@Dennis 1 saat bir süre kısıtlaması için makul görünüyor mu? Hafıza için neyin makul olduğu hakkında hiçbir fikrim yok.
ETHProductions

Bir zaman sınırı varsa, hafıza önemli bir şey değildir. Bir saat çok cömert görünüyor. Kodumun yeterince hızlı olup olmadığını doğrulamak için tam bir saat beklemek istemem.
Dennis,

4
Zaman kısıtlaması olmamasını tercih ederim. Bu özgünlük için daha fazla kapsam verir
Ton Hospel

2
@TonHospel Virgül kullanmadan çıktı alabilirsiniz. Sanırım girişinizin geçerli olduğunu kanıtladığınız sürece hiçbir zaman kısıtlaması olmaz.
ETHProductions

Yanıtlar:


12

Python 2.7, 172 149 124 118 bayt

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

Açıklama:

Bir bijection tanımlayın [1ve ]0. Herhangi bir parantez düzenlemesi daha sonra ikili bir sayı olarak yazılabilir ve bunun tersi, örneğin [][]1010(10) ve [[][]]110100(52). 15'e kadar açık parantezin (toplamda 30 parantez) tüm geçerli düzenlemeleri, tam olarak 2 31'den küçük sayılar olan 30 bit'e kadar (baştaki sıfırları yok sayarak) sayılarla kaplanır .

İlk for-loop, düzenlemenin geçerli olup olmadığını kontrol ederken bir sayıyı parantez düzenlemesine dönüştürerek bu çekişmenin tersini verir.

Geçersiz düzenlemeler, çarpışmayı önlemek için yazdırma deyiminde uzun parantez dizileriyle değiştirilir. Örneğin 11(3) ↔ [[geçerli değil, bunun yerine 3 + 16 parantez birleştiriyoruz. Bu, tüm düzenlemelerin benzersiz olmasını sağlar.

Elde edilen düzenleme, iç içe bir dizi yapmak için bir çift parantez içine yerleştirilir, böylece 1010(10) olur [[][]]ve 110100(52) olur [[[][]]]. Ekstra açık parantez, şimdi tüm dizileri 16 açık parantez ile kapattığımız anlamına gelir.


Aşağıdaki program, 16 adede kadar parantez ile verilen bir dizinin numarasını bulmak için kullanılabilir.

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

"Eşsiz" olarak belirtilen operasyonun amacının hoş bir şekilde kötüye kullanılması
Ton Hospel

Bu sadece bir dahi. Aferin. (Ve
virgülsüz bir

12

Python, 153 128 bayt

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)

Soldan sağa ikili rakamlarına bakarak n sayısını iç içe geçmiş bir listeyle eşleriz. Bu algoritma sadece 2 32'nin altındaki herhangi bir sayı için işe yaramaz .

  1. Geçerli ikili hane 1 ise, çıktı [.
  2. Aksi takdirde, şu ana kadar çıktığımız parantez dizisi tek bir kapama braketi ile dengelenirse, çıktı ][.
  3. Aksi takdirde, bu ikili sayıdaki son 0 ise, çıktı ][.
  4. Aksi takdirde çıktı ].

Sonunda açılmış parantezleri kapattık.


5

Kaşık , 63 bayt (501 bit)

000001001001001011001101001010011011111001010001000000101010
101101100110100101101001000101100010001000000100011000010000
000000000000001110111110010000001110110110010100100100100100
000110011010001000000110110000010000001010110011011011011001
000000011010010010010001000000111011011011101001001001000110
110110010100100101011001000100000011010001000000111011011001
010010010010010001101101101001000110110010110001101101101101
100100010001010010001010011011001000000011001101001001010010
000001100101001000111

Bu, kaşığa dönüştürülen aşağıdaki beyin fırtınası programıdır:

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

Stdin'de ikili bir tamsayı okur ve iç içe geçmiş listeyi stdin'de çıkarır. Boş dize olarak giriş yapılmasını gerektirir (basamaksız) ve 8 bit hücreli bir beyin yorumlayıcısı gerektirir. Python cevabımla aynı algoritma.

Okunabilir sürüm:

-[+[+<]>>+]<+++.           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
Geçenlerde başka bir cevap üzerine bu tartışmayı yaptık ve 63 baytlık bir dosyayı idare edebilecek gerçek bir davetsiz misafir yok gibi görünüyor. Başvuru uygulaması bayt 0x30 ve 0x31 kullandı, bu yüzden bu cevap 501 baytlık bir dosya gerektirecekti .
Dennis,

5

Jöle , 28 bayt

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

Bu, karakterlerin tüm karakter dizileri üzerinde yinelenir [ve ]a ile başlayan ve a [ile biter ], köşeli ayraçların eşleşip eşleşmediğini doğrular ve n. Eşleşmeyi yazdırır .

Çevrimiçi deneyin!


5

Perl, 80 79 bayt

Yine orlp'in algoritmasını kullanır , ama bu sefer ilk önce çalışıp çalışmadığını kontrol ettim ...

İçin +1 içerir -p

STDIN'e giriş numarası verin

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'un çözümü perl'de 64 bayttır:

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

Dennis'in çözümü perl'de 59 bayttır (büyük sayılar için giderek daha yavaş):

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

Bunu sadece 65 bayt olarak almanız gerektiğini düşünüyorum (aslında 64 değil mi)?
Linus

1
@Linus Kurallarınızdan kaçınmak zekice olsa ve tüm avantajlarını hak etse de, biraz aldatma olduğunu düşünüyorum. Puanlama için -p1 ekstra bayt olarak sayılır
Ton Hospel

5

Python 3, 120 114 bayt

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)

İdeone üzerinde test et .

Nasıl çalışır

Tanımlanan f işlevi n girişini alır ve k ile 0 değerini başlatır . Biz artan tutmak edeceğiz k kadar n + 1 değerlerine k geçerli çıkışında sonucu. Böyle bir k değerini her bulduğumuzda , n -1'e ulaştığında azalır , 0~n verir ve k'nın son değerine karşılık gelen r listesi yazdırılır.

Pozitif tamsayılardan iç içe listelere kısmi haritalama (yani, k ↦ r ) bijektif olmalıdır, fakat başka bir kısıtlama yoktur. Bu cevapta kullanılan bir aşağıdaki gibi çalışır.

  1. Dönüştürme k ile bakarak bir ikili dize gösterimine 0b .

    Örneğin, 44 ↦ "0b101100" .

  2. Tüm yerine 0 'ın (kod noktası 48 String'i ile String temsili olarak) ''] ve 1 ' in (kod noktası 49 ile birlikte) [ .

    Örneğin, "0b101100" ↦ "], b [], [[],]," .

  3. İlk üç karakteri ( "0b" ye karşılık gelirler ) ve sondaki karakteri (umarım virgül) kaldırın .

    Örneğin, "], b [], [[],]," ↦ "[], [[],]" .

  4. Oluşturulan kodu değerlendirmeyi deneyin. Bu bir hatayla sonuçlanırsa, k hiçbir listeyle eşleştirilmez.

    Örneğin, "[], [[],]" ↦ ([], [[]]) .

  5. Sonucu (varsa) boş listeyle birleştirin. Bu bir hatayla sonuçlanırsa, k hiçbir listeyle eşleştirilmez.

    Örneğin, ([], [[]]) + [] hataları + , listeleri ve tekilleri birleştiremez.


4

Haskell, 71 bayt

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

Son satırdaki ana işlev, boyuta göre (açık parantez sayısı) sıralanmış, iç içe geçmiş tüm dizilerin bir listesini oluşturur. Bu nedenle, ilk önce en fazla 16 boyuttaki tüm diziler listelenir.

İlk önce daha güzel ve daha kısa olan koda bakalım, ancak Haskell'in typechecker'ı kabul etmeyi reddediyor.

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

Girdideki işlev p, ntüm iç içe geçmiş dizilerin n(açık parantez) bir listesini verir . Bu özyinelemeli yapılır. Bu tür dizilerin her biri sıfır olmayan bir büyüklükten h(ilk üye) kve bazı kuyruklardan t(diğer üyelerden) oluşur n-k. Veya, boyut için boş dizi n==1.

İfade p=<<[1..]daha sonra p(1), p(2), ...boyuta göre sıralanmış tüm dizilerin tek bir sonsuz listesine düzleştirilir .

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

ve ana fonksiyon içine endeksler.

... Ya da Haskell "sonsuz tipini inşa etme: t ~ [t]" hakkında sızlanmasaydı, olur. Haskell, elemanları keyfi olarak iç içe geçmiş dizilerin üzerindeki sonsuz listeyi temsil edemez. Tüm öğeleri aynı tipte olmalıdır, ancak t türü t listesiyle aynı olamaz. Aslında, fonksiyonun pkendisine, Haskell'in sahip olmadığı, bağımlı yazma olmadan tutarlı bir tip atanamaz.

Bunun yerine, parantez dizileri üzerinde çalışırız, üzerinde hareket ederek cons karakterini [ve ]karakterleri simüle ederiz . Bu fazladan 9 bayt alır. Güvenli bir dilde golfün tehlikeleri.


3

Haskell, 87 82 bayt

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

Dizi elemanlarını çıkarır. Kullanım örneği: (([0..]>>= \y->y#y)!!) 3-> "[][]".

İşlev #, iç içe geçmiş tüm dizileri , her birinin kaç tanesinin kaldığını izleyerek naçık ve mkapalı parantezler için dizeler olarak oluşturur . Her zaman ile başlar n == m. Ana işlev y # yher birini çağırır y <- [0,1,...]ve öğeyi girdi tarafından verilen dizine alır.


2

MATL , 31 bayt

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

Çevrimiçi deneyin! Veya ilk birkaç test durumunu doğrulayın (birkaç saniye sürer).

Üretilen haritalama:

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

açıklama

Basamaklı ile kod, ikili sayıları artan test tutar 0yerini -1; yani, hane olarak 1ve kullanarak -1. Rakam 1temsil edecek '['ve -1temsil edecek ']'.

Program n + 1 geçerli numaralar elde edilinceye kadar sayılır . Aşağıdaki iki koşul geçerliyse bir sayı geçerlidir:

  1. Rakamların toplamı sıfırdır (yani, eşit sayıda 1ve vardır -1)
  2. Rakamların kümülatif toplamı, ( durumlar 1'e göre sıfır 1olan -1) sonu hariç her zaman pozitiftir (yani, biriken rakam sayısı her zaman rakamını aşıyor ).

Bir kez n 1 geçerli numaralar elde edilmiştir, sonuncusu değiştirerek çevirilir edilir 1içine [ve -1içine ]ve sonra görüntülenir.

Kod:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.