Finden Sie die "Größe" einer Liste

12

Definieren wir die Funktion "Unwrapped Size" ueiner verschachtelten Liste l(die nur Listen enthält) anhand der folgenden Regeln:

  • Wenn lleer ist, dann u(l)ist 1.
  • Wenn lnicht leer u(l)ist, entspricht dies der Summe der unverpackten Größen aller Elemente in lplus eins.

Ihre Aufgabe ist es, ein Programm (oder eine Funktion) zu schreiben, das eine Liste als Eingabe verwendet und die nicht umbrochene Größe der Liste ausgibt (oder zurückgibt).

Testfälle:

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

Das ist , also gewinnt das kürzeste Programm (in Bytes).

Esolanging Fruit
quelle
2
Kann die Eingabe als Zeichenfolge, dh mit Anführungszeichen, verstanden werden? Können wir ()statt verwenden []?
Luis Mendo
Können wir [[[]][]]stattdessen [[[]],[]]in Ihrem zweiten Beispiel Eingaben in diesem Format vornehmen ?
Mukul Kumar
Was ist die Größe von ["This is some text [with square brackets in] ...[& maybe more than one pair]"]?
Jonathan Allan
2
@ DrMcMoylex Ich bin anderer Meinung. Während das Zählen der Anzahl ]in vielen Sprachen die kürzeste Lösung zu sein scheint, gibt es auch viele Antworten, die diese Herausforderung tatsächlich durch Listenmanipulation lösen, und zumindest bei Esolangs unterscheidet sich das Zählen des Auftretens eines festen Zeichens erheblich vom Zählen die Vorkommen eines Eingabezeichens.
Martin Ender

Antworten:

23

Netzhaut , 1 Byte

]

Probieren Sie es online! (Die erste Zeile aktiviert eine durch Zeilenvorschub getrennte Testsuite.)

Standardmäßig zählt Retina die Anzahl der Übereinstimmungen des angegebenen regulären Ausdrucks in der Eingabe. Die unverpackte Größe entspricht einfach der Anzahl der []Paare in der Eingabe und damit der Anzahl der ].

Martin Ender
quelle
1
Das richtige Werkzeug für den Job!
Cyoce
@MartinEnder fügen Sie Ihrer Sprache jemals neue Funktionen hinzu, um Bytes in einer Codegolf-Frage zu speichern?
lois6b
5
@ lois6b nicht rückwirkend, aber ich verbessere gelegentlich die Sprache, um sie für zukünftige Zwecke leistungsfähiger zu machen. Allerdings hätte diese Antwort in der allerersten Version von Retina von Anfang an funktioniert, als es einfach eine Möglichkeit war, eine einzelne Regex (/ substitution) ohne syntaktischen Aufwand für die Eingabe auszuführen.
Martin Ender
11

Mathematica, 9 Bytes

LeafCount

Es hat sich herausgestellt, dass es dafür ein eingebautes gibt ...

Beachten Sie, dass dies nicht funktioniert, wenn die Listen tatsächlich Nicht-Listenelemente enthalten. Was LeafCountwirklich tut, ist die Anzahl der atomaren Unterausdrücke zu zählen. Zur Eingabe {{}, {{}}}lautet der Ausdruck tatsächlich:

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

Hier sind die atomaren Unterausdrücke eigentlich die Köpfe List .

Martin Ender
quelle
1
Mathematica hat ein eingebautes für alles ...
kirbyfan64sos
2
@ Challenger5 Oy, Plagiat. : P
Martin Ender
7

Brainfuck, 71 61 59 Bytes

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

Übernimmt die Eingabe von STDIN in dem in der Frage angegebenen Format und gibt das Zeichen aus, dessen ASCII-Code die "nicht umbrochene Größe" der Liste ist.

Ich bin immer noch ein absoluter Amateur bei Brainfuck, daher gibt es höchstwahrscheinlich noch viele Optimierungen, die vorgenommen werden können.

Probieren Sie es online!

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)

<.
Türknauf
quelle
5

JavaScript (ES6), 29 27 Bytes

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

Ich liebe es, wenn eine Rekursion so sauber ausfällt. Dies ist im Grunde eine Tiefensuche der Eingabe, bei der 1 addiert wird, wenn das Ende eines Arrays erreicht ist.

Wenn ein leeres Array in JS falsch wäre, könnten dies 24 Bytes sein:

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

Aber leider ist es nicht. Andere Versuche:

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
ETHproductions
quelle
Würde f=a=>a[0]?f(a.pop())+f(a):1funktionieren (Gleiche Anzahl von Bytes)
Neil
@Neil Ja, das ist eine der Lösungen, die ich bereits ausprobiert habe. Ich glaube nicht, dass es möglich ist, kürzer zu werden ...
ETHproductions
(Übrigens hätte ich mich für das Extravagante entschieden f=a=>a.reduce((n,a)=>n+f(a),1). Jetzt sind f=(n,a)=>n+a.reduce(f,1)es nur noch 24 Bytes, aber leider sind die Parameter in der falschen Reihenfolge.)
Neil
@Neil Eigentlich habe ich das zuerst gemacht, außer dass ich es um 1 Byte verkürzt habe:f=a=>a.map(a=>n+=f(a),n=1)&&n
ETHproductions
Ah, tut mir leid, ich hatte nicht gedacht, den Bearbeitungsverlauf zu durchsuchen.
Neil
4

Perl, 9 8 7 + 1 = 8 Bytes

Benötigt die -pFlagge

$_=y;[;

Vielen Dank an @Dada für die Speicherung von zwei Bytes (ich liebe diesen Semikolon-Exploit übrigens)

Gabriel Benamy
quelle
1
-pum 1 Byte zu sparen;)
Dada
Sie können verwenden y;[;, um ein weiteres Byte zu speichern
Dada
4

CJam , 7 5 Bytes

Vielen Dank an Peter Taylor für das Entfernen von 2 Bytes! ( e=anstelle von f=:+)

r'[e=

Probieren Sie es online!

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

05AB1E , 4 Bytes

I'[¢

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

Probieren Sie es online!

Ich denke, es kann mehr Golf gespielt werden, aber das 'I' ist obligatorisch, andernfalls wird die Eingabe als tatsächliches Array anstelle einer Zeichenfolge betrachtet

Osable
quelle
2
"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"In der Eingabe wird diese IAnforderung entfernt, obwohl ich nicht weiß, ob dies zulässig ist.
Magic Octopus Urn
1
@ Carusocomputing: Es ist derzeit nicht erlaubt, aber das könnte sich ändern (ich sehe, dass Luis dem OP die gleiche Frage stellt)
Emigna
Scheiße, 14 Stunden vor mir.
Oliver Ni
3

Labyrinth , 8 Bytes

&-
#,(/!

Probieren Sie es online!

Erläuterung

Dies zählt die öffnenden Klammern mit ein bisschen bitweiser Magie. Wenn wir die Ergebnisse der Zeichencodes des bitweise berücksichtigen und von [, ,und ]mit 2, erhalten wir:

[ , ]
2 0 0

Wenn wir also das Ergebnis dieser Operation für jedes Zeichen zusammenfassen, erhalten wir den doppelten Wert, den wir wollen.

Was den Code selbst betrifft, ist der 2x2-Block am Anfang eine kleine Schleife. Bei der ersten Iteration &-tun Sie nichts, außer dass sie eine explizite Null auf die impliziten Nullen am unteren Rand des Stapels setzen. Dies wird die laufende Summe sein (und es wird tatsächlich negativ sein, um ein Byte später zu speichern). Dann läuft die Schleife wie folgt ab:

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

Sobald wir die Schleife verlassen, wird das folgende lineare Bit ausgeführt:

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

Die IP trifft dann einen Toten und dreht sich um. Bei einem /erneuten Ausführungsversuch wird das Programm aufgrund der versuchten Division durch Null abgebrochen.

Martin Ender
quelle
3

Python 3 2, 36 23 Bytes

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

Mir ist aufgefallen, dass u(l)das gleich der Zahl [in der String-Darstellung ist l, also versucht dieses Programm das zu tun. Wahrscheinlich könnte man noch mehr Golf spielen, wenn man einen anderen Weg findet, dies zu tun ...

Esolanging Fruit
quelle
6
23 Bytes:lambda x:`x`.count("[")
Acrolith
2

Python, 26 Bytes

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

Einfache rekursive Formel.

ETHproductions
quelle
2

C #, 46 41 Bytes

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

l ist die Zeichenfolge der verschachtelten Liste. Teste es hier .

Ave.
quelle
Verwenden Sie die 4 Leerzeichen (vor dem Code), um ihn in einen Codeblock zu
formatieren
@KritixiLithos Hoppla, ich habe vergessen, das richtig zu machen. Vielen Dank für den Hinweis :)
Ave
Und das muss ein Programm oder eine Funktion sein, das ist beides nicht.
Kritixi Lithos
@KritixiLithos Hoppla, danke für den Hinweis, nur behoben.
Ave
2
Sie können die geschweiften Klammern entfernen und returneine Ausdrucksfunktion verwenden. Auch charimplizit wirft auf , intso dass Sie verwenden können , 91statt '[': int u(string l)=>l.Count(c=>c==91);Weiterhin können Sie die Funktion Signatur löschen und eine Lambda - Methode verwenden: l=>l.Count(c=>c==91);.
Milch
2

Ruby, 13 (+1) Bytes

p $_.count ?[

Mit -nArgument aufgerufen :

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

BEARBEITEN: Wurde geändert, um die Antwort tatsächlich auszudrucken

Lee W
quelle
Dies scheint nichts zu drucken. (Sofern dies keine REPL-Antwort ist, sollte die Sprache in diesem Fall als Ruby REPL angegeben werden.)
Martin Ender
@Martin Ender ♦ Die Spezifikation, mit der der Wert zurückgegeben werden kann, anstatt ihn zu drucken.
Lee W
Das bezieht sich auf Funktionsübergaben. ZB ->s{s.count ?[}wäre eine gültige Vorlage.
Martin Ender
Ist das eine allgemeine Regel?
Lee W
2

Brain-Flak , 63 , 61 Bytes

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

Probieren Sie es online! 58 Byte Code und +3 für das-a Flag, das die ASCII-Eingabe ermöglicht.

Lesbare Version / Erklärung:

#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
quelle
1

/// 13 Bytes

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

Ausgabe in unary.

Probieren Sie es online!

Erläuterung:

/[/0/          Replace every [ with 0
     /]///,//  Remove every ] and ,
Akrolith
quelle
Wie spricht man aus ///?
Roblogic
@ropata Slashes
Acrolith
1

PHP, 35 Bytes

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

preg_match_all Findet alle übereinstimmenden Instanzen des regulären Ausdrucks und gibt eine Zahl zurück. Aus diesem Grund werden die kurzen Echo-Tags benötigt.

Wie die meisten Antworten zählt es die Anzahl [der Eingaben und gibt diese Anzahl aus

gabe3886
quelle
1
Wenn Sie ]anstelle von verwenden [, müssen Sie nicht entkommen.
Martin Ender
2
count_chars()[91];tut fast dasselbe, ist aber kürzer.
user59178
1

Schläger 82 Bytes

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

Testen:

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

Ausgabe:

1
4
19
4
rnso
quelle
1

V , 10 Bytes

ÓÛ
ÒC0@"

Probieren Sie es online!

Dies enthält einige nicht druckbare Zeichen, hier ist die lesbare Version:

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

<C-a>repräsentiert "Strg-a" (ASCII 0x01) und <esc>repräsentiert die Escape-Taste (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

Mehr Spaß, weniger Golf Version:

o0kòf]m`jòd

Probieren Sie es 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
quelle
1

Scala, 15 Bytes

s=>s.count(92<)

Ungolfed:

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

countzählt, wie viele Elemente ein Prädikat erfüllen, in diesem Fall 92<die Methode <von 92.

corvus_192
quelle
1

O , 15 Bytes

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

Probieren Sie es hier aus!

In der Eingabe müssen alle Kommas entweder entfernt oder durch Leerzeichen ersetzt werden.

Erläuterung

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.

Wenn wir an einem String arbeiten dürfen: 10 Bytes

ie\']-e@-p
kirbyfan64sos
quelle
1

> <> , 21 20 18 Bytes

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

Edit: Punktzahl 1 für goto Aussagen!

Bearbeiten 2: Anscheinend unterscheidet sich> <> von Befunge darin, dass es einen IP-Versatz ungleich Null nach dem Einwickeln zulässt (mit anderen Worten, mithilfe einer Trampolinanweisung kann ich nach (1, 0) anstelle von (0, 0) einwickeln). Interessant.

TryItOnline!

Brian Gradin
quelle
1

Brainfuck, 28 Bytes

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

Probieren Sie es online aus.

Dies zählt die Anzahl der eingegebenen Zeichen, die durch 3 teilbar sind, dh die Anzahl der ] Zeichen.

Alternative 34-Byte-Lösung, bei der [Zeichen direkt gezählt und auf 8-Bit-Zellen zurückgegriffen werden:

,
[
  <-[>-<---]
  >------
  [>-<[-]]
  >+<,
]
>.
Mitch Schwartz
quelle
1

C 48 46 Bytes

Zwei Bytes dank kirbyfan64sos gespeichert

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

Code testen

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

Testfälle

a.exe
1
4
19
Cleblanc
quelle
Wechseln Sie *v++^91?0:i++zu i+=*v==91, um 3 Byte zu speichern.
kirbyfan64sos
@ kirbyfan64sos Danke! Ich muss noch v erhöhen, kann aber i+=*v++==91zwei Bytes speichern.
Cleblanc
1

tinylisp repl, 39 bytes

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

Definiert eine Funktion u, die wie folgt aufgerufen werden kann(u (q ((())()) )) (für den zweiten Testfall). Wenn Sie dies in der Replikation tun, sparen Sie 4 Bytes durch automatisch geschlossene Klammern.

Erläuterung

(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

Das x-(0-y)Konstrukt ist notwendig, da tinylisp keine eingebaute Additionsfunktion hat, sondern nur eine Subtraktion.

DLosc
quelle
1

Haskell, 20 - 19 - 17 Bytes

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

Probieren Sie es online!

Nimmt die Liste als String und setzt ein 1 für jede in eine Liste ein. ]Fasst dann alle 1s zusammen.


Pointfree-Version: (19 Bytes)

length.filter(>'[')

Geht davon aus , [ ] sind die einzigen Zeichen in der Zeichenfolge. Filtert die Liste, um alle Zeichen größer als zu erhalten [, die alle sind, ]und gibt die Länge zurück.

Verwendung:

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

Bash + Coreutils, 29 Bytes

f()(echo $1|tr -d -c [|wc -c)
Angs
quelle
Sie können das meiste davon entfernen und einfach tun tr -d -c [|wc -c, wodurch die Liste standardmäßig von der Standardeingabe gelesen wird.
kirbyfan64sos
0

DASH , 14 Bytes

(ss[len;!> ="]

Zählt einfach ]'s. Verwendung:

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

Bonuslösung, 15 Bytes

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

Dieser zählt rekursiv aus einer reellen Liste. Verwendung:

(f\@+1sum ->#f#0)[[]]
Mama Fun Roll
quelle