Bir listenin "paketlenmemiş boyutu" nu bulun


12

uYuvalanmış bir listenin l(yalnızca listeleri içeren) "paketlenmemiş boyut" işlevini aşağıdaki kurallarla tanımlayalım :

  • Eğer lo zaman, boşu(l) 1'dir.
  • lBoş değilse , u(l)her öğenin sarılmamış boyutlarının toplamına lartı bire eşittir .

Göreviniz, listeyi girdi olarak alan ve listenin paketlenmemiş boyutunu çıkaran (veya döndüren) bir program (veya işlev) yazmaktır.

Test Durumları:

[]                                           ->  1
[[[]],[]]                                    ->  4
[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]] -> 19
[[[[]]]]                                     ->  4

Bu , bu yüzden en kısa program (bayt cinsinden) kazanır.


2
Girdi bir dize olarak alınabilir, yani tırnak içine alınmış tırnak işareti ile? ()Bunun yerine kullanabilir miyiz []?
Luis Mendo

ikinci örneğinizde [[[]][]]bunun yerine bu biçimde girdi alabilir miyiz [[[]],[]]?
Mukul Kumar

Boyutu nedir ["This is some text [with square brackets in] ...[& maybe more than one pair]"]?
Jonathan Allan


2
@DrMcMoylex Ben katılmıyorum. Sayma sayısı ]birçok dilde en kısa çözüm gibi görünse de, bu zorluğu liste manipülasyonu ile çözen birçok cevap da vardır ve en azından sabit bir karakterin oluşumlarını saymak esolangs'da saymaktan oldukça farklıdır. bir giriş karakterinin oluşumları.
Martin Ender

Yanıtlar:


23

Retina , 1 bayt

]

Çevrimiçi deneyin! (İlk satır, satır besleme ile ayrılmış bir test paketini etkinleştirir.)

Varsayılan olarak, Retina girişte verilen normal ifadenin eşleşme sayısını sayar. Sarılmamış boyut, []girişteki çift sayısına ve dolayısıyla sayısına eşittir ].


1
İş için doğru araç!
Cyoce

@MartinEnder baytları bir codegolf sorusunda kaydetmek için dilinize yeni işlevler eklediniz mi?
lois6b

5
@ lois6b geriye dönük olarak değil, ancak dili gelecekteki kullanımlar için daha güçlü hale getirmek için zaman zaman geliştiriyorum. Bununla birlikte, bu cevap, sözdizimsel yük olmadan girdiye karşı tek bir regex (/ ikame) çalıştırmanın bir yolu olduğunda, Retina'nın ilk versiyonunda arkadan işe yarayacaktı.
Martin Ender

11

Mathematica, 9 bayt

LeafCount

Bunun için yerleşik bir şey olduğu ortaya çıkıyor ...

Listeler aslında liste dışı öğeler içeriyorsa bunun işe yaramayacağını unutmayın. Ne LeafCountgerçekten yapar atom alt ifadelerin sayısını olduğunu. Girdi için {{}, {{}}}, ifade aslında şunu okur:

List[List[], List[List[]]]

Burada atomik alt ifadeler aslında kafalardır List .


1
Mathematica her şey için yerleşik bir ...
kirbyfan64sos

2
@ Challenger5 Oy, intihal. : P
Martin Ender

7

Brainfuck, 71 61 59 bayt

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

STDIN'den soruda verilen formatta girdi alır ve ASCII kodu listenin "paketlenmemiş boyutu" olan karakteri çıktılar .

Ben hala Brainfuck'ta tam bir amatörüm, bu yüzden hala yapılabilecek birçok optimizasyon var.

Çevrimiçi deneyin!

Ungolfed:

read input to tape
>>+[>,]<
current tape: (0 0 1 a b *c)
where abc represents input and * is IP

now we loop over each character (from the end)
this loops assumes we are starting on the (current) last char
and it zeroes the entire string by the time it finishes
[

  subtract 91 from this character
  technically we only subtract 85 here and correct the answer
  with the 6 minus signs below
  >-[<->---]
  current tape: (0 0 1 a b cminus91 *0)

  invert the result and put that in the next cell
  +<------[->[-]<]>
  current tape: (0 0 1 a b 0 *c==91)

  move that result back to the original cell
  [-<+>]<
  current tape: (0 0 1 a b *c==91)

  if the result is true we found a brace
  increment the very first cell if so
  [-<[<]<+>>[>]]<
  current tape: (count 0 1 a *b)

]
current tape: (count *0)

<.

5

JavaScript (ES6), 29 27 bayt

f=([x,...a])=>x?f(x)+f(a):1

bir özyineleme bu temiz çıktı zaman seviyorum. Bu temel olarak girdinin derinlik-ilk araştırmasıdır ve bir dizinin sonuna ulaşıldığında 1 ekler.

JS'de boş bir dizi hatalıysa, bu 24 bayt olabilir:

f=a=>a?f(a.pop())+f(a):1

Ama ne yazık ki, değil. Diğer girişimler:

f=a=>a.reduce((n,x)=>n+f(x),1) // Works, but 3 bytes longer
f=a=>a.map(x=>n+=f(x),n=1)&&n  // Works, but 2 bytes longer
f=a=>(x=a.pop())?f(x)+f(a):1   // Works, but 1 byte longer
f=a=>a[0]?f(a.pop())+f(a):1    // Works, but same byte count
f=a=>a+a?f(a.pop())+f(a):1     // Doesn't work on any array containing 1 sub-array
f=a=>a-1?f(a.pop())+f(a):1     // Same

Çalışır mıydı f=a=>a[0]?f(a.pop())+f(a):1? (Yine de aynı bayt sayısı.)
Neil

@Neil Evet, bu zaten denediğim çözümlerden biri. Daha kısa almanın mümkün olduğunu düşünmüyorum ...
ETHproductions

(Bu arada, abartılı için gidecektim f=a=>a.reduce((n,a)=>n+f(a),1). Şimdi, f=(n,a)=>n+a.reduce(f,1)sadece 24 bayt, ama ne yazık ki parametreler yanlış sırada.)
Neil

@ Neil Ben aslında bunu ilk 1 bayt kısaltmak dışında yaptım:f=a=>a.map(a=>n+=f(a),n=1)&&n
ETHproductions

Ah, üzgünüm, düzenleme geçmişine göz atmayı düşünmemiştim.
Neil

4

Perl, 9 8 7 + 1 = 8 bayt

-pBayrak gerektirir

$_=y;[;

@Dada'ya iki bayt tasarruf için teşekkürler (bu noktalı virgül istismar btw'yi seviyorum)


1
-p1 bayt kurtarmak için;)
Dada

Bir y;[;bayt daha kaydetmek için kullanabilirsiniz
Dada

4

CJam , 7 5 bayt

Peter Taylor'a 2 bayt ayırdığı için teşekkürler! ( e=yerine f=:+)

r'[e=

Çevrimiçi deneyin!

r         e# Read input
 '[       e# Push open bracket char
   e=     e# Count occurrences. Implicit display

3

05AB1E , 4 bayt

I'[¢

I    Get input as a string
 '[¢ Count the opening square brackets and implicitly print them

Çevrimiçi deneyin!

Ben daha golf olabilir düşünüyorum ama 'ben' zorunludur, aksi takdirde girdi bir dize yerine gerçek bir dizi olarak kabul edilir


2
"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"girişte bu Igereksinimi kaldırır , ancak buna izin verilip verilmediğini bilmiyorum.
Sihirli Ahtapot Urn

1
@carusocomputing: Şu anda izin verilmiyor, ancak bu değişebilir (Luis'in
OP'ye

Dang, benden 14 saat önce.
Oliver Ni

3

Labirent , 8 bayt

&-
#,(/!

Çevrimiçi deneyin!

açıklama

Bu, açılış köşeli parantezlerini biraz bitsel büyü ile sayar. Biz Bitwise VE karakter kodlarının sonuçlarını ele alırsak [, ,ve ]ile 2elde ederiz:

[ , ]
2 0 0

Dolayısıyla, her işlem için bu işlemin sonucunu özetlersek, istediğimiz değerin iki katını elde ederiz.

Kodun kendisi için, başlangıçtaki 2x2 bloğu küçük bir döngüdür. İlk yinelemede &-, yığının altındaki örtük olanların üstüne açık bir sıfır koymaları dışında hiçbir şey yapmayın. Bu, çalışan toplam olacaktır (ve daha sonra bir baytı kaydetmek negatif olacaktır). Sonra döngü aşağıdaki gibi gider:

,   Read character. At EOF this gives -1 which causes the instruction pointer to
    leave the loop. Otherwise, the loop continues.
#   Push the stack depth, 2.
&   Bitwise AND.
-   Subtract from running total.

Döngüden ayrıldıktan sonra, aşağıdaki doğrusal bit yürütülür:

(   Decrement to turn the -1 into a -2.
/   Divide negative running total by -2 to get desired result.
!   Print.

IP sonra bir ölü vurur ve arkasına döner. /Tekrar yürütmeye çalıştığında, deneme girişimi sıfırdan dolayı program sona erer.


3

Python 3 2, 36 23 bayt

lambda x:`x`.count("[")

Bu dize temsili u(l)sayısına eşit olduğunu fark ettim , bu yüzden bu program bunu yapmaya çalışır. Muhtemelen bunu yapmak için başka bir yol bularak daha da golf olabilir ...[l


6
23 bayt:lambda x:`x`.count("[")
acrolith


2

C #, 46 41 bayt

int u(string l){return l.Count(c=>c=='[');}

l, iç içe liste dizesidir. Burada test edin .


Kod bloğuna biçimlendirmek için 4 boşluğu (koddan önce) kullanın
user41805

@KritixiLithos ayy, bunu doğru yapmayı unuttum. İşaret ettiğiniz için teşekkürler :)
Ave

Ve bu bir program ya da işlev olmalı, ikisi de değil.
user41805

@KritixiLithos ayy, işaret ettiğin için teşekkürler, düzeltti.
Ave

2
Kıvırcık parantezleri ve returnifade gövdeli işlevini kullanarak bırakabilirsiniz . Ayrıca charörtülü atmalarını intkullanabilirsiniz böylece 91yerine '[': int u(string l)=>l.Count(c=>c==91);Ayrıca, sen fonksiyon imza bırakın ve bir lambda yöntemi kullanabilirsiniz: l=>l.Count(c=>c==91);.
süt


2

Ruby, 13 (+1) bayt

p $_.count ?[

Bağımsız -ndeğişken ile çağrıldı :

ruby -ne 'p $_.count ?['

EDIT: Cevabı gerçekten yazdırmak için değiştirildi


Bu hiçbir şey yazdırmıyor gibi görünüyor. (Bu bir REPL cevabı olmadığı sürece, bu durumda dil Ruby REPL olarak belirtilmelidir.)
Martin Ender

@Martin Ender ♦ Değeri yazdırmak yerine döndürmek için izin verilen özellik.
Lee W

Bu, işlev gönderimlerini ifade eder. Örneğin ->s{s.count ?[}geçerli bir sunum olurdu.
Martin Ender

Bu genel bir kural mı?
Lee W



2

Brain-Flak , 63 , 61 bayt

{({}[(((()()()){}){}()){({}[()])}{}]){{}(<>{}())(<>)}{}}<>

Çevrimiçi deneyin! 58 bayt kod ve -aASCII girişini etkinleştiren bayrak için +3 .

Okunabilir versiyon / açıklama:

#While non-empty:
{

    #subtract
    ({}[

    #91
    (((()()()){}){}()){({}[()])}{}

    ])

    #if non-zero
    {

        # Remove the difference
        {}

        #Increment the counter on the other stack
        (<>{}())

        #Push a zero onto the main stack
        (<>)
    }

    #pop the left-over zero
    {}

#endwhile
}

#Move back to the stack with the counter, implicitly display
<>



1

PHP, 35 bayt

<?=preg_match_all('/\[/',$argv[1]);

preg_match_all normal ifadenin eşleşen tüm örneklerini bulur ve bir sayı döndürür, bu nedenle kısa eko etiketlerine ihtiyaç vardır.

Çoğu cevap gibi, [girişteki sayıyı sayar ve bu sayıyı çıkarır


1
]Bunun yerine kullanırsanız [, kaçmak zorunda kalmazsınız.
Martin Ender

2
count_chars()[91];aynı şeyi yapar ama daha kısadır.
user59178

1

Raket 82 bayt

(define n 0)(let p((l l))(if(null? l)(set! n(+ 1 n))(begin(p(car l))(p(cdr l)))))n

Ungolfed:

(define (f l)
  (define n 0)
  (let loop ((l l))
    (if (null? l)
        (set! n (add1 n))
        (begin (loop (first l))
               (loop (rest l)))))
  n)

Test yapmak:

(f '[]) 
(f '[[[]] []]) 
(f '[[[]] [[[[]] []]] [[[]] [[[[]] [[] [[]]]]]]]) 
(f '[[[[]]]])  

Çıktı:

1
4
19
4

1

V , 10 bayt

ÓÛ
ÒC0@"

Çevrimiçi deneyin!

Bu bazı yazdırılamayan karakterler içeriyor, işte okunabilir sürüm:

ÓÛ
Ò<C-a>C0<esc>@"

<C-a>"ctrl-a" (ASCII 0x01) ve <esc>çıkış anahtarını (ASCII 0x1b) temsil eder .

ÓÛ              " Remove all '['s
                "
Ò<C-a>          " Replace what's left with '<C-a>' (the increment command)
      C         " Delete this line
       0<esc>   " And replace it with a '0'
             @" " Run what we just deleted as V code (A bunch of increment commands

Daha eğlenceli, daha az golf versiyon:

o0kòf]m`jòd

Çevrimiçi deneyin!

o0<esc>                     " Put a '0' on the line below us
       k                    " Move back up a line
        ò               ò   " Recursively:
         f]                 "   Move to a right-bracket
           m`               "   Add this location to our jumplist
             j              "   Move down a line
              <C-a>         "   Increment this number
                   <C-o>    "   Move to the previous location
                         d  " Delete the bracket line
                            " Implicitly display

1

Scala, 15 bayt

s=>s.count(92<)

Ungolfed:

s=>s.count(c=>92<c)

countBirçok unsurları bu durumda, bir yüklemi tatmin nasıl sayar 92<yöntemdir, <bir 92.


1

O , 15 bayt

i~{1\{nJ+}d}J;J

Burada deneyin!

Girişte, virgüller kaldırılmalı veya boşluklarla değiştirilmelidir.

açıklama

i~{1\{nJ+}d}J;J
i                Read a line of input.
 ~               Evaluate it.
  {        }J;   Define a function and save it into the `J` variable.
                 Currently, the input array is at the top of the stack.
   1\            Push 1 and swap it with the input array.
     {   }d      For each element in the array...
                 Because the array was popped by `d`, 1 is at the TOS.
      nJ+        Recurse and add the result to 1.
              J  Initiate the function call.
                 The result is printed implicitly.

Bir dize üzerinde çalışmamıza izin verilirse: 10 bayt

ie\']-e@-p

1

> <> , 21 20 18 bayt

0i:0(90.;n?|3%0=+!

Düzenleme: goto ifadeleri için 1 puan!

Düzenleme 2: Görünüşe göre> <> sarmadan sonra sıfır olmayan IP ofsetine izin verdiği için Befunge'den farklıdır (başka bir deyişle, bir trambolin talimatı kullanarak, (0, 0) yerine (1, 0) 'a sarabilirim). İlginç.

TryItOnline!


1

Brainfuck, 28 bayt

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

Çevrimiçi deneyin.

Bu, 3 ile bölünebilen giriş karakteri sayısını, yani ] .

[Karakterleri doğrudan sayan ve 8 bit hücrelere dayanan alternatif 34 baytlık çözüm :

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

1

C, 48 46 Bayt

Kirbyfan64sos sayesinde iki bayt kaydedildi

i;f(char*v){for(i=0;*v;i+=*v++==91);return i;}

i;f(char*v){for(i=0;*v;*v++^91?0:i++);return i;}

Test kodu

main()
{
    printf("%d\n", f("[]"));
    printf("%d\n", f("[[[]] []]"));
    printf("%d\n", f("[[[]] [[[[]] []]] [[[]] [[[[]] [[] [[]]]]]]]"));
}

Test senaryoları

a.exe
1
4
19

3 bayt kaydetmek *v++^91?0:i++için i+=*v==91olarak değiştirin .
kirbyfan64sos

@ kirbyfan64sos Teşekkürler! Hala v'yi artırmam gerekiyor ama i+=*v++==91iki bayt kaydetmek için kullanabilirim .
cleblanc

1

tinylisp repl, 39 bayt

(d u(q((L)(i L(s(u(h L))(s 0(u(t L))))1

Bir işlevi tanımlar ugibi adlandırılabilir (u (q ((())()) ))(ikinci test durumu için). Otomatik kapanma parantezleri nedeniyle bu işlemi yapmak 4 bayt tasarruf sağlar.

açıklama

(d u                                      )  Define u as
    (q                                   )    the following, unevaluated
      (                                 )     list (which acts as a function in tinylisp):
       (L)                                   Given arglist of one element, L, return:
          (i L                         )     If L (is nonempty):
              (s(u(h L))             )        Call u on head of L and subtract
                        (s 0        )          0 minus
                            (u(t L))           call u on tail of L
                                      1      Else, 1

x-(0-y)Tinylisp yerleşik bir ekleme fonksiyonu, sadece çıkarma olmadığı için yapı gereklidir.



1

Haskell, 20 19 17 bayt

f s=sum[1|']'<-s]

Çevrimiçi deneyin!

Listeyi dize olarak alır ve 1her biri için bir liste koyar ], sonra tüm s'leri toplar 1.


Pointfree sürümü: (19 bayt)

length.filter(>'[')

Varsayım , [ ], dizedeki tek karakterdir. Daha büyük olan tüm karakterleri almak için listeyi filtreler [, bunların tümü ]ve uzunluğu döndürür.

Kullanımı:

Prelude> length.filter(=='[')$"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"
19

0

Bash + coreutils, 29 bayt

f()(echo $1|tr -d -c [|wc -c)

Bunların çoğunu kaldırabilir ve tr -d -c [|wc -cvarsayılan olarak listeyi standart girdiden okuyacak şekilde yapabilirsiniz.
kirbyfan64sos

0

DASH , 14 bayt

(ss[len;!> ="]

Basitçe sayar ]. Kullanımı:

(ss[len;!> ="]"])"[[]]"

Bonus çözüm, 15 bayt

a\@+1sum ->#a#0

Bu, tekrarlayan bir şekilde gerçek bir listeden sayılır. Kullanımı:

(f\@+1sum ->#f#0)[[]]
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.