Znajdź „rozpakowany rozmiar” listy

12

Zdefiniujmy funkcję „nieopakowanego rozmiaru” ulisty zagnieżdżonej l(zawierającej tylko listy) według następujących reguł:

  • Jeśli ljest pusty, to u(l)jest 1.
  • Jeśli ljest niepuste, u(l)jest równe sumie nieopakowanych rozmiarów każdego elementu lplus jeden.

Twoim zadaniem jest napisanie programu (lub funkcji), który pobiera listę jako dane wejściowe i wyprowadza (lub zwraca) nieopakowany rozmiar listy.

Przypadki testowe:

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

To jest , więc wygrywa najkrótszy program (w bajtach).

Esolanging Fruit
źródło
2
Czy dane wejściowe można traktować jako ciąg znaków, tzn. Z dołączonymi znakami cudzysłowu? Czy możemy użyć ()zamiast []?
Luis Mendo,
czy możemy wziąć dane wejściowe w tym formacie [[[]][]]zamiast tego [[[]],[]]w twoim drugim przykładzie?
Mukul Kumar,
Jaki jest rozmiar ["This is some text [with square brackets in] ...[& maybe more than one pair]"]?
Jonathan Allan,
2
@DrMcMoylex Nie zgadzam się. Chociaż liczenie liczby ]wydaje się być najkrótszym rozwiązaniem w wielu językach, istnieje również wiele odpowiedzi, które faktycznie rozwiązują to wyzwanie za pomocą manipulacji listami, a przynajmniej w esolangach liczenie wystąpień ustalonego znaku również różni się od liczenia wystąpienia znaku wejściowego.
Martin Ender

Odpowiedzi:

23

Siatkówka , 1 bajt

]

Wypróbuj online! (Pierwszy wiersz włącza pakiet testowy oddzielony od linii).

Domyślnie Retina zlicza liczbę dopasowań podanego wyrażenia regularnego na wejściu. Rozpakowany rozmiar jest po prostu równy liczbie []par na wejściu, a zatem liczbie ].

Martin Ender
źródło
1
Właściwe narzędzie do pracy!
Cyoce
@MartinEnder czy kiedykolwiek dodajesz nowe funkcje do swojego języka, aby zapisać bajty w pytaniu o kodegolfa?
lois6b,
5
@ lois6b nie działa wstecz, ale od czasu do czasu poprawiam język, aby był bardziej wydajny dla przyszłych zastosowań. To powiedziawszy, ta odpowiedź zadziałałaby w pierwszej wersji Retiny od tyłu, gdy byłby to po prostu sposób na uruchomienie pojedynczego wyrażenia regularnego (/ substytucji) względem danych wejściowych bez narzutu składniowego.
Martin Ender
11

Mathematica, 9 bajtów

LeafCount

Okazuje się, że jest do tego wbudowana ...

Zauważ, że to nie zadziałałoby, gdyby listy faktycznie zawierały elementy spoza listy. Tak LeafCountnaprawdę liczy się liczba podwyrażeń atomowych. W przypadku danych wejściowych {{}, {{}}}wyrażenie faktycznie brzmi:

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

Tutaj podwyrażenia atomowe są w rzeczywistości głowami List .

Martin Ender
źródło
1
Mathematica ma wbudowane wszystko ...
kirbyfan64sos
2
@ Challenger5 Oy, plagiat. : P
Martin Ender
7

Brainfuck, 71 61 59 bajtów

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

Pobiera dane wejściowe ze STDIN w formacie podanym w pytaniu i wysyła znak, którego kod ASCII jest „nieopakowanym rozmiarem”.

Nadal jestem kompletnym amatorem w Brainfuck, więc najprawdopodobniej istnieje wiele optymalizacji, które można jeszcze wprowadzić.

Wypróbuj online!

Nie golfowany:

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)

<.
Klamka
źródło
5

JavaScript (ES6), 29 27 bajtów

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

uwielbiam, gdy rekurencja okazuje się tak czysto. Zasadniczo jest to pierwsze wyszukiwanie głębokości wejścia, dodawanie 1 za każdym razem, gdy osiągnięty zostanie koniec tablicy.

Jeśli pusta tablica była fałszywa w JS, może to być 24 bajty:

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

Ale niestety tak nie jest. Inne próby:

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
ETHprodukcje
źródło
Czy f=a=>a[0]?f(a.pop())+f(a):1zadziała? (Liczba samych bajtów.)
Neil,
@ Nee Tak, to jedno z rozwiązań, które już wypróbowałem. Nie sądzę, żeby można było skrócić ...
ETHprodukcje
(Nawiasem mówiąc, wybrałbym ekstrawagancję f=a=>a.reduce((n,a)=>n+f(a),1). Teraz f=(n,a)=>n+a.reduce(f,1)ma tylko 24 bajty, ale niestety parametry są w niewłaściwej kolejności.)
Neil
@Neil Zrobiłem to najpierw, z wyjątkiem skrócenia go o 1 bajt:f=a=>a.map(a=>n+=f(a),n=1)&&n
ETHprodukcje
Ach, przepraszam, nie myślałem o przeglądaniu historii edycji.
Neil,
4

Perl, 9 8 7 + 1 = 8 bajtów

Wymaga -pflagi

$_=y;[;

Dzięki @Dada za dwa bajty zapisów (uwielbiam to wykorzystanie średnika btw)

Gabriel Benamy
źródło
1
-pby zaoszczędzić 1 bajt;)
Dada
Możesz użyć, y;[;aby zapisać jeszcze jeden bajt
Dada,
4

CJam , 7 5 bajtów

Dzięki Peter Taylor za usunięcie 2 bajtów! ( e=zamiast f=:+)

r'[e=

Wypróbuj online!

r         e# Read input
 '[       e# Push open bracket char
   e=     e# Count occurrences. Implicit display
Luis Mendo
źródło
3

05AB1E , 4 bajty

I'[¢

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

Wypróbuj online!

Myślę, że można grać bardziej w golfa, ale to „I” jest obowiązkowe, w przeciwnym razie dane wejściowe są traktowane jako rzeczywista tablica zamiast łańcucha

Osable
źródło
2
"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"w danych wejściowych usuwa to Iwymaganie, chociaż nie wiem, czy jest to dozwolone.
Magic Octopus Urn
1
@carusocomputing: Obecnie nie jest to dozwolone, ale to może się zmienić (widzę, że Luis zadaje OP to samo pytanie)
Emigna,
Dang, 14 godzin przede mną.
Oliver Ni
3

Labirynt , 8 bajtów

&-
#,(/!

Wypróbuj online!

Wyjaśnienie

Liczy się nawiasy otwierające dzięki odrobinie bitowej magii. Jeśli weźmiemy pod uwagę wyniki kodów charakter bitowego i [, ,i ]z 2, otrzymujemy:

[ , ]
2 0 0

Jeśli więc zsumujemy wynik tej operacji dla każdej postaci, otrzymamy dwukrotność pożądanej wartości.

Jeśli chodzi o sam kod, blok 2x2 na początku jest małą pętlą. Przy pierwszej iteracji &-nie rób nic, poza tym, że umieszczają jawne zero na domniemanym zera u dołu stosu. Będzie to bieżąca suma (a później zapisanie bajtu będzie ujemne). Następnie pętla wygląda następująco:

,   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.

Po opuszczeniu pętli wykonywany jest następujący bit liniowy:

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

Później trafia w martwe i odwraca się. Podczas próby /ponownego uruchomienia program kończy się z powodu próby podziału przez zero.

Martin Ender
źródło
3

Python 3 2, 36 23 bajtów

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

Zauważyłem, że u(l)jest to liczba [reprezentująca ciąg znaków l, więc ten program próbuje to zrobić. Prawdopodobnie można by dalej grać w golfa, znajdując inny sposób na zrobienie tego, chociaż ...

Esolanging Fruit
źródło
6
23 bajty:lambda x:`x`.count("[")
acrolith
2

Python, 26 bajtów

f=lambda a:sum(map(f,a))+1

Prosta formuła rekurencyjna.

ETHprodukcje
źródło
2

C #, 46 41 bajtów

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

l to ciąg zagnieżdżonej listy. Sprawdź to tutaj .

zdrowaśka
źródło
Użyj 4 spacji (przed kodem) do sformatowania go w blok kodu
user41805
@KritixiLithos ups, zapomniałem poprawnie to zrobić. Dziękujemy za zwrócenie uwagi :)
Ave
I to musi być program lub funkcja, to nie jest ani jedno, ani drugie.
user41805,
@KritixiLithos ups, dzięki za wskazanie, właśnie to naprawiłem.
Ave
2
Możesz upuścić nawiasy klamrowe i returnużywając funkcji wyrażania treści. Również charpośrednio rzuca się intwięc można użyć 91zamiast '[': int u(string l)=>l.Count(c=>c==91);Dalej, można upuścić podpisu funkcji i stosować metodę lambda: l=>l.Count(c=>c==91);.
mleko
2

Rubinowy, 13 (+1) bajtów

p $_.count ?[

Wywoływany z -nargumentem:

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

EDYCJA: Zmieniono, aby faktycznie wydrukować odpowiedź

Lee W.
źródło
To nie wydaje się nic drukować. (O ile nie jest to odpowiedź REPL, w takim przypadku język należy podać jako Ruby REPL.)
Martin Ender
@Martin Ender ♦ Specyfikacja zezwala na zwracanie wartości zamiast jej drukowania.
Lee W
Odnosi się to do przesyłania funkcji. Np. ->s{s.count ?[}Byłby to prawidłowy wniosek.
Martin Ender,
Czy to ogólna zasada?
Lee W
2

Brain-Flak , 63 , 61 bajtów

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

Wypróbuj online! 58 bajtów kodu i +3 dla -aflagi umożliwiającej wprowadzanie ASCII.

Czytelna wersja / objaśnienie:

#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
<>
James
źródło
1

///, 13 bajtów

/[/0//]///,//

Wyjście jednostkowe.

Wypróbuj online!

Wyjaśnienie:

/[/0/          Replace every [ with 0
     /]///,//  Remove every ] and ,
acrolith
źródło
Jak się wymawiasz ///?
roblogic
@ropata Slashes
acrolith
1

PHP, 35 bajtów

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

preg_match_all znajduje wszystkie pasujące wystąpienia wyrażenia regularnego i zwraca liczbę, dlatego potrzebne są krótkie znaczniki echa.

Podobnie jak większość odpowiedzi, zlicza liczbę [wejść i wyjść w liczbie

gabe3886
źródło
1
Jeśli użyjesz ]zamiast [, nie będziesz musiał uciekać.
Martin Ender,
2
count_chars()[91];robi to samo, ale jest krótszy.
user59178,
1

Rakieta 82 bajtów

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

Nie golfowany:

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

Testowanie:

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

Wynik:

1
4
19
4
rnso
źródło
1

V , 10 bajtów

ÓÛ
ÒC0@"

Wypróbuj online!

Zawiera niektóre niedrukowalne znaki, oto wersja do odczytu:

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

<C-a>reprezentuje „ctrl-a” (ASCII 0x01) i <esc>reprezentuje klawisz Escape (ASCII 0x1b).

ÓÛ              " 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

Więcej zabawy, mniej golfowa wersja:

o0kòf]m`jòd

Wypróbuj online!

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
James
źródło
1

Scala, 15 bajtów

s=>s.count(92<)

Nie golfowany:

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

countLiczy się, jak wiele elementów spełniają predykat, w tym przypadku 92<, co jest metodą <z 92.

corvus_192
źródło
1

O , 15 bajtów

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

Wypróbuj tutaj!

Na wejściu wszelkie przecinki należy usunąć lub zastąpić spacjami.

Wyjaśnienie

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.

Jeśli wolno nam podjąć pracę nad łańcuchem: 10 bajtów

ie\']-e@-p
kirbyfan64sos
źródło
1

> <> , 21 20 18 bajtów

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

Edycja: ocena 1 dla wyciągów goto!

Edycja 2: Najwyraźniej> <> różni się od Befunge tym, że pozwala na niezerowe przesunięcie IP po zawinięciu (innymi słowy, używając instrukcji trampoliny, mogę owinąć do (1, 0) zamiast (0, 0)). Ciekawy.

TryItOnline!

Brian Gradin
źródło
1

Brainfuck, 28 bajtów

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

Wypróbuj online.

Zlicza liczbę znaków wejściowych podzielnych przez 3, tj. Liczbę ]znaków.

Alternatywne rozwiązanie 34-bajtowe zliczające [znaki bezpośrednio i oparte na 8-bitowych komórkach:

,
[
  <-[>-<---]
  >------
  [>-<[-]]
  >+<,
]
>.
Mitch Schwartz
źródło
1

C, 48 46 bajtów

Zaoszczędzono dwa bajty dzięki kirbyfan64sos

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;}

Kod testowy

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

Przypadki testowe

a.exe
1
4
19
cleblanc
źródło
Zmień, *v++^91?0:i++aby i+=*v==91zapisać 3 bajty.
kirbyfan64sos
@ kirbyfan64sos Thanks! Nadal muszę zwiększyć wartość v, ale mogę użyć i+=*v++==91do zapisania dwóch bajtów.
cleblanc
1

tinylisp repl, 39 bajtów

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

Definiuje funkcję, uktórą można wywołać jak (u (q ((())()) ))(dla drugiego przypadku testowego). Wykonanie tego w replice pozwala zaoszczędzić 4 bajty z powodu automatycznie zamykanych nawiasów.

Wyjaśnienie

(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)Konstrukt jest konieczne, ponieważ tinylisp nie posiada wbudowanej funkcji Ponadto jedynie odejmowanie.

DLosc
źródło
1

Haskell, 20 19 17 bajtów

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

Wypróbuj online!

Pobiera listę jako ciąg znaków i umieszcza na 1liście dla każdego z nich ], a następnie podsumowuje wszystkie 1s.


Wersja Pointfree: (19 bajtów)

length.filter(>'[')

Zakłada , [ ]się, że są jedynymi znakami w ciągu. Filtruje listę, aby uzyskać wszystkie znaki większe niż [, które są wszystkie, ]i zwraca długość.

Stosowanie:

Prelude> length.filter(=='[')$"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"
19
Laikoni
źródło
0

Bash + coreutils, 29 bajtów

f()(echo $1|tr -d -c [|wc -c)
Angs
źródło
Możesz usunąć większość tego i po prostu zrobić tr -d -c [|wc -c, co domyślnie przeczyta listę ze standardowego wejścia.
kirbyfan64sos
0

DASH , 14 bajtów

(ss[len;!> ="]

Po prostu się liczy ]. Stosowanie:

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

Rozwiązanie premiowe, 15 bajtów

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

Ten rekurencyjnie liczy się z prawdziwej listy. Stosowanie:

(f\@+1sum ->#f#0)[[]]
Mama Fun Roll
źródło