Trouver la «taille non emballée» d'une liste

12

Définissons la fonction "taille non enveloppée" ud'une liste imbriquée l(contenant uniquement des listes) selon les règles suivantes:

  • Si lest vide, alors u(l)est 1.
  • Si lest non vide, u(l)est égal à la somme des tailles non enveloppées de chaque élément dans l, plus un.

Votre tâche consiste à écrire un programme (ou une fonction) qui prend une liste en entrée et génère (ou renvoie) la taille non enveloppée de la liste.

Cas de test:

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

Il s'agit de , donc le programme le plus court (en octets) l'emporte.

Esolanging Fruit
la source
2
L'entrée peut-elle être considérée comme une chaîne, c'est-à-dire avec des guillemets? Pouvons-nous utiliser à la ()place de []?
Luis Mendo
pouvons-nous prendre des entrées dans ce format [[[]][]]au lieu de cela [[[]],[]]dans votre deuxième exemple?
Mukul Kumar
Quelle est la taille de ["This is some text [with square brackets in] ...[& maybe more than one pair]"]?
Jonathan Allan
2
@DrMcMoylex Je ne suis pas d'accord. Bien que compter le nombre de ]ne semble être la solution la plus courte dans de nombreuses langues, il existe également de nombreuses réponses qui résolvent réellement ce défi via la manipulation de liste, et au moins dans les esolangs, compter les occurrences d'un caractère fixe est également très différent de compter les occurrences d'un caractère saisi.
Martin Ender

Réponses:

23

Rétine , 1 octet

]

Essayez-le en ligne! (La première ligne active une suite de tests séparés par un saut de ligne.)

Par défaut, Retina compte le nombre de correspondances de l'expression régulière donnée dans l'entrée. La taille non enveloppée est simplement égale au nombre de []paires en entrée et donc au nombre de ].

Martin Ender
la source
1
Le bon outil pour le travail!
Cyoce
@MartinEnder avez-vous déjà ajouté de nouvelles fonctions à votre langue afin d'économiser des octets dans une question de codegolf?
lois6b
5
@ lois6b pas rétroactivement, mais j'améliore occasionnellement le langage pour le rendre plus puissant pour de futures utilisations. Cela dit, cette réponse aurait fonctionné dans la toute première version de Retina de l'arrière alors qu'il s'agissait simplement d'un moyen d'exécuter une seule expression régulière (/ substitution) contre l'entrée sans surcharge syntaxique.
Martin Ender
11

Mathematica, 9 octets

LeafCount

Il s'avère qu'il y a une fonction intégrée pour cela ...

Notez que cela ne fonctionnerait pas si les listes contenaient réellement des éléments non-liste. Ce LeafCountqui fait vraiment, c'est de compter le nombre de sous-expressions atomiques. Pour l'entrée {{}, {{}}}, l'expression se lit en fait:

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

Ici, les sous-expressions atomiques sont en fait les têtes List .

Martin Ender
la source
1
Mathematica a une fonction intégrée pour tout ...
kirbyfan64sos
2
@ Challenger5 Oy, plagiat. : P
Martin Ender
7

Brainfuck, 71 61 59 octets

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

Prend l'entrée de STDIN dans le format donné dans la question et sort le caractère dont le code ASCII est la "taille non enveloppée" de la liste.

Je suis toujours un amateur complet chez Brainfuck, donc il y a très probablement de nombreuses optimisations qui peuvent encore être faites.

Essayez-le en ligne!

Non golfé:

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)

<.
Poignée de porte
la source
5

JavaScript (ES6), 29 27 octets

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

j'adore quand une récursion se révèle clairement. Il s'agit essentiellement d'une recherche en profondeur de l'entrée, en ajoutant 1 chaque fois que la fin d'un tableau est atteinte.

Si un tableau vide était faux dans JS, cela pourrait être 24 octets:

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

Mais hélas, ce n'est pas le cas. Autres tentatives:

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
la source
Ça f=a=>a[0]?f(a.pop())+f(a):1marcherait? (Même nombre d'octets cependant.)
Neil
@Neil Oui, c'est l'une des solutions que j'ai déjà essayées. Je ne pense pas qu'il soit possible de raccourcir ...
ETHproductions
(Soit dit en passant, j'aurais opté pour l'extravagant f=a=>a.reduce((n,a)=>n+f(a),1). Maintenant, ce f=(n,a)=>n+a.reduce(f,1)n'est que 24 octets, mais malheureusement, les paramètres sont dans le mauvais ordre.)
Neil
@Neil J'ai fait ça en premier, sauf le raccourcir d'un octet:f=a=>a.map(a=>n+=f(a),n=1)&&n
ETHproductions
Ah, désolé, je n'avais pas pensé à parcourir l'historique des modifications.
Neil
4

Perl, 9 8 7 + 1 = 8 octets

Nécessite le -pdrapeau

$_=y;[;

Merci à @Dada pour deux sauvegardes d'octets (j'adore cet exploit virgule btw)

Gabriel Benamy
la source
1
-ppour économiser 1 octet;)
Dada
Vous pouvez utiliser y;[;pour enregistrer un octet de plus
Dada
4

CJam , 7 5 octets

Merci à Peter Taylor d'avoir supprimé 2 octets! ( e=au lieu de f=:+)

r'[e=

Essayez-le en ligne!

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

05AB1E , 4 octets

I'[¢

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

Essayez-le en ligne!

Je pense qu'il peut être joué plus mais ce «je» est obligatoire, sinon l'entrée est considérée comme un tableau réel au lieu d'une chaîne

Osable
la source
2
"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"dans l'entrée supprime cette Iexigence, même si je ne sais pas si cela est autorisé.
Urne de poulpe magique
1
@carusocomputing: Ce n'est pas autorisé actuellement, mais cela pourrait changer (je vois Luis poser la même question au PO)
Emigna
Dang, 14 heures avant moi.
Oliver Ni
3

Labyrinthe , 8 octets

&-
#,(/!

Essayez-le en ligne!

Explication

Cela compte les parenthèses d'ouverture via un peu de magie au niveau du bit. Si l' on considère les résultats des codes de caractères du ET de bitwise [, ,et ]avec 2, nous obtenons:

[ , ]
2 0 0

Donc, si nous résumons simplement le résultat de cette opération pour chaque caractère, nous obtenons le double de la valeur souhaitée.

Quant au code lui-même, le bloc 2x2 au début est une petite boucle. Lors de la première itération &-, ne faites rien, sauf qu'ils mettent un zéro explicite au-dessus des implicites au bas de la pile. Ce sera le total cumulé (et il sera en fait négatif d'enregistrer un octet plus tard). Ensuite, la boucle se déroule comme suit:

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

Une fois que nous quittons la boucle, le bit linéaire suivant est exécuté:

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

L'IP frappe alors un mort et se retourne. Lorsqu'il essaie de s'exécuter à /nouveau, le programme se termine en raison de la tentative de division par zéro.

Martin Ender
la source
3

Python 3 2, 36 23 octets

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

J'ai remarqué que u(l)c'est égal au nombre de [dans la représentation sous forme de chaîne de l, donc ce programme essaie de le faire. Il pourrait probablement être approfondi en trouvant un autre moyen de le faire, cependant ...

Esolanging Fruit
la source
6
23 octets:lambda x:`x`.count("[")
acrolith
2

Python, 26 octets

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

Formule récursive simple.

ETHproductions
la source
2

C #, 46 41 octets

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

l est la chaîne de la liste imbriquée. Testez-le ici .

Ave
la source
Utilisez les 4 espaces (avant le code) pour le formater en un bloc de code
user41805
@KritixiLithos oups, j'ai oublié de le faire correctement. Merci de l'avoir signalé :)
Ave
Et cela doit être un programme ou une fonction, ce n'est ni l'un ni l'autre.
user41805
@KritixiLithos oups, merci de l'avoir signalé, venez de le corriger.
Ave
2
Vous pouvez supprimer les accolades et returnen utilisant une fonction d'expression corporelle. Aussi charjette implicitement intque vous pouvez utiliser au 91lieu de '[': De int u(string l)=>l.Count(c=>c==91);plus, vous pouvez laisser tomber la signature de la fonction et utiliser une méthode lambda: l=>l.Count(c=>c==91);.
lait
2

Rubis, 13 (+1) octets

p $_.count ?[

Appelé avec -nargument:

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

EDIT: modifié pour imprimer réellement la réponse

Lee W
la source
Cela ne semble rien imprimer. (Sauf s'il s'agit d'une réponse REPL, auquel cas la langue doit être spécifiée comme Ruby REPL.)
Martin Ender
@Martin Ender ♦ La spécification permettait de renvoyer la valeur au lieu de l'imprimer.
Lee W
Cela fait référence aux soumissions de fonctions. Par exemple, ce ->s{s.count ?[}serait une soumission valable.
Martin Ender
Est-ce une règle générale?
Lee W
2

Brain-Flak , 63 , 61 octets

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

Essayez-le en ligne! 58 octets de code et +3 pour le -adrapeau permettant l'entrée ASCII.

Version / explication lisible:

#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
la source
1

///, 13 octets

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

Sortie en unaire.

Essayez-le en ligne!

Explication:

/[/0/          Replace every [ with 0
     /]///,//  Remove every ] and ,
acrolithe
la source
Comment prononcez-vous ///?
roblogic
@ropata Slashes
acrolith
1

PHP, 35 octets

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

preg_match_all trouve toutes les instances correspondantes de l'expression régulière et renvoie un nombre, c'est pourquoi les balises d'écho courtes sont nécessaires.

Comme la plupart des réponses, il compte le nombre d' [entrées et de sorties de ce nombre

gabe3886
la source
1
Si vous utilisez ]au lieu de [, vous n'aurez pas à y échapper.
Martin Ender
2
count_chars()[91];fait à peu près la même chose mais est plus courte.
user59178
1

Raquette 82 octets

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

Non golfé:

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

Essai:

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

Production:

1
4
19
4
rnso
la source
1

V , 10 octets

ÓÛ
ÒC0@"

Essayez-le en ligne!

Celui-ci contient des caractères non imprimables, voici la version lisible:

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

<C-a>représente "ctrl-a" (ASCII 0x01) et <esc>représente la touche d'échappement (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

Version plus amusante, moins golfique:

o0kòf]m`jòd

Essayez-le en ligne!

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
la source
1

Scala, 15 octets

s=>s.count(92<)

Non golfé:

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

countcompte le nombre d'éléments satisfaisant un prédicat, dans ce cas 92<, qui est la méthode <de 92.

corvus_192
la source
1

O , 15 octets

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

Essayez-le ici!

Dans l'entrée, toutes les virgules doivent être supprimées ou remplacées par des espaces.

Explication

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.

Si nous sommes autorisés à travailler sur une chaîne: 10 octets

ie\']-e@-p
kirbyfan64sos
la source
1

> <> , 21 20 18 octets

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

Edit: marquez 1 pour les déclarations goto!

Edit 2: Apparemment> <> diffère de Befunge en ce qu'il permet un décalage IP non nul après le wrapping (en d'autres termes, en utilisant une instruction de trampoline, je peux boucler sur (1, 0) au lieu de (0, 0)). Intéressant.

TryItOnline!

Brian Gradin
la source
1

Brainfuck, 28 octets

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

Essayez-le en ligne.

Cela compte le nombre de caractères saisis divisible par 3, c'est-à-dire le nombre de ]caractères.

Solution alternative de 34 octets comptant [directement les caractères et s'appuyant sur des cellules 8 bits:

,
[
  <-[>-<---]
  >------
  [>-<[-]]
  >+<,
]
>.
Mitch Schwartz
la source
1

C, 48 46 octets

Enregistré deux octets grâce à 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;}

Code de test

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

Cas de test

a.exe
1
4
19
cleblanc
la source
Passez *v++^91?0:i++à i+=*v==91pour enregistrer 3 octets.
kirbyfan64sos
@ kirbyfan64sos Merci! J'ai encore besoin d'incrémenter v mais je peux utiliser i+=*v++==91pour économiser deux octets.
cleblanc
1

tinylisp repl , 39 octets

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

Définit une fonction uqui peut être appelée comme (u (q ((())()) ))(pour le deuxième cas de test). Le faire dans la repl économise 4 octets en raison de parenthèses fermées automatiquement.

Explication

(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

La x-(0-y)construction est nécessaire car tinylisp n'a pas de fonction d'addition intégrée, seulement une soustraction.

DLosc
la source
1

Haskell, 20 19 17 octets

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

Essayez-le en ligne!

Prend la liste sous forme de chaîne et met un 1dans une liste pour chacun ], puis résume tous les 1s.


Version sans point: (19 octets)

length.filter(>'[')

Suppose que ce , [ ]sont les seuls caractères de la chaîne. Filtre la liste pour obtenir tous les caractères supérieurs à [, qui sont tous ]et renvoie la longueur.

Usage:

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

Bash + coreutils, 29 octets

f()(echo $1|tr -d -c [|wc -c)
Angs
la source
Vous pouvez supprimer la plupart de cela et le faire tr -d -c [|wc -c, ce qui lira par défaut la liste à partir de l'entrée standard.
kirbyfan64sos
0

DASH , 14 octets

(ss[len;!> ="]

Compte tout simplement ]. Usage:

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

Solution bonus, 15 octets

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

Celui-ci compte récursivement à partir d'une vraie liste. Usage:

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