Encuentra el "tamaño sin envolver" de una lista


12

Definamos la función ude "tamaño sin envolver" de una lista anidada l(que contiene solo listas) mediante las siguientes reglas:

  • Si lestá vacío, entonces u(l)es 1.
  • Si lno está vacío, u(l)es igual a la suma de los tamaños sin envolver de cada elemento l, más uno.

Su tarea es escribir un programa (o función) que tome una lista como entrada y produzca (o devuelva) el tamaño sin envolver de la lista.

Casos de prueba:

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

Este es el , por lo que gana el programa más corto (en bytes).


2
¿Se puede tomar la entrada como una cadena, es decir, entre comillas? ¿Podemos usar en ()lugar de []?
Luis Mendo

¿podemos tomar entrada en este formato en [[[]][]]lugar de esto [[[]],[]]en su segundo ejemplo?
Mukul Kumar

¿De qué tamaño es ["This is some text [with square brackets in] ...[& maybe more than one pair]"]?
Jonathan Allan


2
@DrMcMoylex No estoy de acuerdo. Si bien contar el número de ]sí parece ser la solución más corta en muchos idiomas, también hay muchas respuestas que realmente resuelven este desafío a través de la manipulación de listas, y al menos en esolangs contar las ocurrencias de un carácter fijo también es bastante diferente de contar Las ocurrencias de un carácter de entrada.
Martin Ender

Respuestas:


23

Retina , 1 byte

]

Pruébalo en línea! (La primera línea habilita un conjunto de pruebas separado por salto de línea).

Por defecto, Retina cuenta el número de coincidencias de la expresión regular dada en la entrada. El tamaño sin envolver es simplemente igual al número de []pares en la entrada y, por lo tanto, al número de ].


1
¡La herramienta adecuada para el trabajo!
Cyoce

@MartinEnder ¿alguna vez agrega nuevas funciones a su idioma para guardar bytes en una pregunta de codegolf?
lois6b

55
@ lois6b no retroactivamente, pero ocasionalmente mejoro el lenguaje para hacerlo más poderoso para usos futuros. Dicho esto, esta respuesta habría funcionado en la primera versión de Retina desde atrás cuando era simplemente una forma de ejecutar una expresión regular (/ sustitución) contra la entrada sin sobrecarga sintáctica.
Martin Ender

11

Mathematica, 9 bytes

LeafCount

Resulta que hay un incorporado para eso ...

Tenga en cuenta que esto no funcionaría si las listas realmente contienen elementos que no son de la lista. Lo que LeafCountrealmente hace es contar el número de subexpresiones atómicas. Para la entrada {{}, {{}}}, la expresión en realidad lee:

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

Aquí las subexpresiones atómicas son en realidad las cabezas List .


1
Mathematica tiene una función incorporada para todo ...
kirbyfan64sos

2
@ Challenger5 Oy, plagio. : P
Martin Ender

7

Brainfuck, 71 61 59 bytes

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

Toma información de STDIN en el formato dado en la pregunta y genera el carácter cuyo código ASCII es el "tamaño sin envolver" de la lista.

Todavía soy un completo aficionado en Brainfuck, por lo que es muy probable que aún se puedan hacer muchas optimizaciones.

Pruébalo en línea!

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

<.

5

JavaScript (ES6), 29 27 bytes

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

Me encanta cuando una recursión resulta tan limpia. Esto es básicamente una búsqueda profunda de la entrada, agregando 1 cada vez que se alcanza el final de una matriz.

Si una matriz vacía fuera falsa en JS, esto podría ser de 24 bytes:

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

Pero, por desgracia, no lo es. Otros intentos

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

Funcionaria f=a=>a[0]?f(a.pop())+f(a):1? (Sin embargo, el mismo número de bytes.)
Neil

@Neil Sí, esa es una de las soluciones que ya he probado. No creo que sea posible acortar más ...
ETHproductions

(Por cierto, habría elegido lo extravagante f=a=>a.reduce((n,a)=>n+f(a),1). Ahora, f=(n,a)=>n+a.reduce(f,1)solo tiene 24 bytes, pero lamentablemente los parámetros están en el orden incorrecto)
Neil

@Neil Realmente hice eso primero, excepto acortarlo en 1 byte:f=a=>a.map(a=>n+=f(a),n=1)&&n
ETHproductions

Ah, lo siento, no había pensado en examinar el historial de edición.
Neil

4

Perl, 9 8 7 + 1 = 8 bytes

Requiere la -pbandera

$_=y;[;

Gracias a @Dada por dos bytes guardados (me encanta este punto y coma explotar por cierto)


1
-pguardar 1 byte;)
Dada

Puede usar y;[;para guardar un byte más
Dada

4

CJam , 7 5 bytes

¡Gracias a Peter Taylor por eliminar 2 bytes! (en e=lugar de f=:+)

r'[e=

Pruébalo en línea!

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

3

05AB1E , 4 bytes

I'[¢

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

Pruébalo en línea!

Creo que se puede jugar más al golf, pero ese 'I' es obligatorio, de lo contrario, la entrada se considera una matriz real en lugar de una cadena


2
"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"en la entrada elimina ese Irequisito, aunque no sé si eso está permitido.
Urna mágica del pulpo

1
@carusocomputing: actualmente no está permitido, pero eso podría cambiar (veo a Luis haciendo la misma pregunta al OP)
Emigna

Dang, 14 horas antes que yo.
Oliver Ni

3

Laberinto , 8 bytes

&-
#,(/!

Pruébalo en línea!

Explicación

Esto cuenta los corchetes de apertura a través de un poco de magia bit a bit. Si tenemos en cuenta los resultados de los códigos de caracteres de la AND bit a bit de [, ,y ]con 2, obtenemos:

[ , ]
2 0 0

Entonces, si solo resumimos el resultado de esta operación para cada personaje, obtenemos el doble del valor que queremos.

En cuanto al código en sí, el bloque 2x2 al principio es un pequeño bucle. En la primera iteración &-, en realidad, no haga nada, excepto que ponen un cero explícito encima de los implícitos en la parte inferior de la pila. Este será el total acumulado (y en realidad será negativo guardar un byte más adelante). Entonces el ciclo va de la siguiente manera:

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

Una vez que dejamos el ciclo, se ejecuta el siguiente bit lineal:

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

La IP luego golpea a un muerto y se da vuelta. Cuando intenta ejecutarse /nuevamente, el programa termina debido al intento de división por cero.


3

Python 3 2, 36 23 bytes

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

Noté que u(l)es igual al número de [en la representación de cadena de l, por lo que este programa intenta hacer eso. Sin embargo, probablemente podría jugar más golf al encontrar otra forma de hacer esto ...


66
23 bytes:lambda x:`x`.count("[")
acrolith el


2

C #, 46 41 bytes

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

l es la cadena de la lista anidada. Pruébalo aquí .


Use los 4 espacios (antes del código) para formatearlo en un bloque de código
user41805

@ KritixiLithos ¡Vaya! Olvidé hacer eso correctamente. Gracias por señalarlo :)
Ave

Y esto tiene que ser un programa o una función, esto no es ninguno.
user41805

@KritixiLithos oops, gracias por señalarlo, solo lo arreglé.
Ave

2
Puede soltar las llaves y returnutilizando una función de expresión corporal. También chararroja implícitamente intesta manera puede utilizar 91en lugar de '[': int u(string l)=>l.Count(c=>c==91);Además, se podría caer la firma de la función y el uso de un método lambda: l=>l.Count(c=>c==91);.
leche


2

Rubí, 13 (+1) bytes

p $_.count ?[

Llamado con -nargumento:

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

EDITAR: cambiado para imprimir realmente la respuesta


Esto no parece imprimir nada. (A menos que sea una respuesta REPL, en cuyo caso el idioma debe especificarse como Ruby REPL.)
Martin Ender

@ Martin Ender ♦ La especificación permitió devolver el valor en lugar de imprimirlo.
Lee W

Eso se refiere a presentaciones de funciones. Por ejemplo ->s{s.count ?[}, sería una presentación válida.
Martin Ender

¿Es esa una regla general?
Lee W



2

Brain-Flak , 63 , 61 bytes

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

Pruébalo en línea! 58 bytes de código y +3 para el -aindicador que permite la entrada ASCII.

Versión legible / explicación:

#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 bytes

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

preg_match_all encuentra todas las instancias coincidentes de la expresión regular y devuelve un número, razón por la cual se necesitan las etiquetas de eco cortas.

Como la mayoría de las respuestas, cuenta el número de [entradas y salidas de ese número.


1
Si usa en ]lugar de [, no tendrá que escapar.
Martin Ender

2
count_chars()[91];hace casi lo mismo pero es más corto.
user59178

1

Raqueta 82 bytes

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

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

Pruebas:

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

Salida:

1
4
19
4

1

V , 10 bytes

ÓÛ
ÒC0@"

Pruébalo en línea!

Contiene algunos caracteres no imprimibles, aquí está la versión legible:

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

<C-a>representa "ctrl-a" (ASCII 0x01) y <esc>representa la tecla de 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

Versión más divertida y menos golfista:

o0kòf]m`jòd

Pruébalo en línea!

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 bytes

s=>s.count(92<)

Sin golf:

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

countcuenta cuántos elementos satisfacen un predicado, en este caso 92<, cuál es el método <de 92.


1

O , 15 bytes

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

Pruébalo aquí!

En la entrada, las comas deben eliminarse o reemplazarse por espacios.

Explicación

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 se nos permite trabajar en una cadena: 10 bytes

ie\']-e@-p

1

> <> , 21 20 18 bytes

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

Editar: puntuación 1 para ir a las declaraciones!

Edición 2: aparentemente> <> difiere de Befunge en que permite un desplazamiento de IP distinto de cero después del ajuste (en otras palabras, al usar una instrucción de trampolín, puedo ajustar a (1, 0) en lugar de (0, 0)). Interesante.

TryItOnline!


1

Brainfuck, 28 bytes

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

Pruébalo en línea.

Esto cuenta el número de caracteres de entrada divisibles por 3, es decir, el número de ]caracteres.

Solución alternativa de 34 bytes que cuenta [caracteres directamente y depende de celdas de 8 bits:

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

1

C, 48 46 bytes

Guardado dos bytes gracias a 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;}

Código de prueba

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

Casos de prueba

a.exe
1
4
19

Cambie *v++^91?0:i++a i+=*v==91para guardar 3 bytes.
kirbyfan64sos

@ kirbyfan64sos Gracias! Todavía necesito incrementar v pero puedo usar i+=*v++==91para guardar dos bytes.
cleblanc

1

tinylisp repl, 39 bytes

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

Define una función uque se puede llamar como (u (q ((())()) ))(para el segundo caso de prueba). Hacerlo en la respuesta ahorra 4 bytes debido a paréntesis de cierre automático.

Explicación

(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)construcción es necesaria porque tinylisp no tiene una función de suma incorporada, solo resta.



1

Haskell, 20 19 17 bytes

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

Pruébalo en línea!

Toma la lista como una cadena y pone una 1en una lista para cada uno ], luego resume todos los 1s.


Versión sin puntos: (19 bytes)

length.filter(>'[')

Los supuestos , [ ]son los únicos caracteres en la cadena. Filtra la lista para obtener todos los caracteres mayores que [, que son todos, ]y devuelve la longitud.

Uso:

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

0

Bash + coreutils, 29 bytes

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

Puede eliminar la mayor parte de esto y simplemente hacer tr -d -c [|wc -c, lo que por defecto leerá la lista de la entrada estándar.
kirbyfan64sos

0

DASH , 14 bytes

(ss[len;!> ="]

Simplemente cuenta ]. Uso:

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

Solución extra, 15 bytes

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

Este cuenta recursivamente de una lista real. Uso:

(f\@+1sum ->#f#0)[[]]
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.