Encontre o "tamanho desembrulhado" de uma lista


12

Vamos definir a função "tamanho não empacotado" ude uma lista aninhada l(contendo apenas listas) pelas seguintes regras:

  • Se lestiver vazio, então u(l)é 1.
  • Se lnão estiver vazio, u(l)é igual à soma dos tamanhos desembrulhados de cada elemento l, mais um.

Sua tarefa é escrever um programa (ou função) que recebe uma lista como entrada e gera (ou retorna) o tamanho desembrulhado da lista.

Casos de teste:

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

Isso é , então o programa mais curto (em bytes) vence.


2
A entrada pode ser tomada como uma string, ou seja, com aspas? Podemos usar em ()vez de []?
Luis Mendo

podemos receber entradas nesse formato, e [[[]][]]não [[[]],[]]no seu segundo exemplo?
Mukul Kumar

Qual é o tamanho de ["This is some text [with square brackets in] ...[& maybe more than one pair]"]?
Jonathan Allan


2
@DrMcMoylex Eu discordo. Embora contar o número de ]pareça ser a solução mais curta em muitos idiomas, também existem muitas respostas que realmente resolvem esse desafio por meio da manipulação de listas e, pelo menos em esolangs, contar as ocorrências de um caractere fixo também é bem diferente de contar as ocorrências de um caractere de entrada.
Martin Ender

Respostas:


23

Retina , 1 byte

]

Experimente online! (A primeira linha ativa um conjunto de testes separado por avanço de linha.)

Por padrão, a Retina conta o número de correspondências do regex especificado na entrada. O tamanho desembrulhado é simplesmente igual ao número de []pares na entrada e, portanto, ao número de ].


1
A ferramenta certa para o trabalho!
Cyoce 11/11

@MartinEnder Você já adicionou novas funções ao seu idioma para salvar bytes em uma questão de codegolf?
lois6b

5
@ lois6b não é retroativo, mas ocasionalmente aprimoro o idioma para torná-lo mais poderoso para usos futuros. Dito isto, essa resposta teria funcionado na primeira versão do Retina de volta quando era simplesmente uma maneira de executar uma única regex (/ substituição) na entrada sem sobrecarga sintática.
Martin Ender

11

Mathematica, 9 bytes

LeafCount

Acontece que há um built-in para isso ...

Observe que isso não funcionaria se as listas realmente contivessem elementos que não são da lista. O que LeafCountrealmente faz é contar o número de subexpressões atômicas. Para entrada {{}, {{}}}, a expressão realmente lê:

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

Aqui as subexpressões atômicas são na verdade as cabeças List .


1
Mathematica tem um built-in para tudo ...
kirbyfan64sos

2
@ Challenger5 Oi, plágio. : P
Martin Enders

7

Brainfuck, 71 61 59 bytes

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

Pega a entrada de STDIN no formato fornecido na pergunta e gera o caractere cujo código ASCII é o "tamanho desembrulhado da lista".

Eu ainda sou um amador completo em Brainfuck, então provavelmente existem muitas otimizações que ainda podem ser feitas.

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

<.

5

JavaScript (ES6), 29 27 bytes

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

Eu adoro quando uma recursão acaba bem. Essa é basicamente uma pesquisa aprofundada da entrada, adicionando 1 sempre que o final de uma matriz for atingido.

Se uma matriz vazia for falsificada em JS, isso pode ser de 24 bytes:

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

Mas, infelizmente, não é. Outras tentativas:

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? (Embora mesmo contagem de bytes.)
Neil

@ Neil Sim, essa é uma das soluções que eu já tentei. Eu não acho que é possível ficar mais curto ... #
1120 ETHproductions

(By the way, eu teria ido para o extravagante f=a=>a.reduce((n,a)=>n+f(a),1)Agora,. f=(n,a)=>n+a.reduce(f,1)É de apenas 24 bytes, mas infelizmente os parâmetros estão na ordem errada.)
Neil

@ Neil Na verdade, eu fiz isso primeiro, exceto f=a=>a.map(a=>n+=f(a),n=1)&&n
encurtá-

Ah, desculpe, eu não tinha pensado em navegar no histórico de edições.
911 Neil

4

Perl, 9 8 7 + 1 = 8 bytes

Requer a -pbandeira

$_=y;[;

Graças a @Dada por dois bytes salvos (eu estou adorando este ponto-e-vírgula explorar btw)


1
-ppara salvar 1 byte;)
Dada

Você pode usar y;[;para salvar mais um byte
Dada

4

CJam , 7 5 bytes

Obrigado a Peter Taylor por remover 2 bytes! (em e=vez de f=:+)

r'[e=

Experimente online!

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

Experimente online!

Eu acho que pode ser jogado mais, mas que 'I' é obrigatório, caso contrário, a entrada é considerada uma matriz real em vez de uma string


2
"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"na entrada remove esse Irequisito, embora eu não saiba se isso é permitido.
Magic Octopus Urn

1
@carusocomputing: Não é permitido atualmente, mas isso pode mudar (eu vejo Luis pedindo ao OP que a mesma pergunta)
Emigna

Dang, 14 horas antes de mim.
Oliver Ni

3

Labirinto , 8 bytes

&-
#,(/!

Experimente online!

Explicação

Isso conta os colchetes de abertura através de um pouco de mágica bit a bit. Se considerarmos os resultados dos códigos de caracteres do bit a bit E de [, ,e ]com 2, temos:

[ , ]
2 0 0

Portanto, se apenas resumirmos o resultado dessa operação para cada caractere, obteremos o dobro do valor que queremos.

Quanto ao código em si, o bloco 2x2 no início é um pequeno loop. Na primeira iteração &-, não faça nada, exceto que eles colocam um zero explícito no topo dos implícitos na parte inferior da pilha. Este será o total em execução (e será realmente negativo salvar um byte mais tarde). Em seguida, o loop é o seguinte:

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

Uma vez que deixamos o loop, o seguinte bit linear é executado:

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

O IP então atinge um morto e se vira. Quando tenta executar /novamente, o programa termina devido à tentativa de divisão por zero.


3

Python 3 2, 36 23 bytes

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

Notei que u(l)é igual ao número de [na representação de string de l, portanto, este programa tenta fazer isso. Provavelmente, ele poderia ser jogado mais longe, encontrando outra maneira de fazer isso, embora ...


6
23 bytes:lambda x:`x`.count("[")
acrolith 10/11


2

C #, 46 41 bytes

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

l é a string da lista aninhada. Teste aqui .


Use as 4 vagas (antes do código) para formatá-lo em um bloco de código
user41805

@KritixiLithos opa, eu esqueci de fazer isso corretamente. Obrigado por apontar isso :)
Ave

E isso tem que ser um programa ou uma função, isso também não é.
user41805

@KritixiLithos opa, obrigado por apontar, apenas corrigi-lo.
Ave

2
Você pode soltar os chavetas e returnusar uma função de expressão corporal. Também charlança implicitamente intassim que você pode usar 91em vez de '[': int u(string l)=>l.Count(c=>c==91);Além disso, você pode soltar a assinatura da função e usar um método lambda: l=>l.Count(c=>c==91);.
milk


2

Ruby, 13 (+1) bytes

p $_.count ?[

Chamado com -nargumento:

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

EDIT: Alterado para realmente imprimir a resposta


Isso não parece imprimir nada. (A menos que seja uma resposta REPL, nesse caso, o idioma deve ser especificado como Ruby REPL).
Martin Ender

@Martin Ender ♦ A especificação permitiu retornar o valor em vez de imprimi-lo.
Lee W

Isso se refere a envios de funções. Por exemplo, ->s{s.count ?[}seria um envio válido.
101316 Martin Ender

Isso é uma regra geral?
Lee W



2

Flacidez Cerebral , 63 , 61 bytes

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

Experimente online! 58 bytes de código e +3 para o -asinalizador que ativa a entrada ASCII.

Versão / explicação legível:

#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 localiza todas as instâncias correspondentes da expressão regular e retorna um número, e é por isso que as tags de eco curto são necessárias.

Como a maioria das respostas, conta o número de [na entrada e gera esse número


1
Se você usar em ]vez de [, não precisará escapar dela.
101316 Martin Ender

2
count_chars()[91];faz praticamente a mesma coisa, mas é mais curto.
user59178

1

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

Teste:

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

Resultado:

1
4
19
4

1

V , 10 bytes

ÓÛ
ÒC0@"

Experimente online!

Isso contém alguns caracteres não imprimíveis, aqui está a versão legível:

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

<C-a>representa "ctrl-a" (ASCII 0x01) e <esc>representa a chave 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

Versão mais divertida e menos divertida:

o0kòf]m`jòd

Experimente 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

1

Scala, 15 bytes

s=>s.count(92<)

Ungolfed:

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

countconta quantos elementos atendem a um predicado, nesse caso 92<, qual é o método <de 92.


1

O , 15 bytes

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

Experimente aqui!

Na entrada, qualquer vírgula deve ser removida ou substituída por espaços.

Explicação

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.

Se pudermos trabalhar em uma sequência: 10 bytes

ie\']-e@-p

1

> <> , 21 20 18 bytes

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

Edit: score 1 for goto declarações!

Edit 2: Aparentemente> <> difere do Befunge, pois permite deslocamento de IP diferente de zero após o empacotamento (em outras palavras, usando uma instrução de trampolim, eu posso empacotar para (1, 0) em vez de (0, 0)). Interessante.

TryItOnline!


1

Brainfuck, 28 bytes

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

Experimente online.

Isso conta o número de caracteres de entrada divisíveis por 3, ou seja, o número de ]caracteres.

Solução alternativa de 34 bytes, contando [caracteres diretamente e confiando nas células de 8 bits:

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

1

C, 48 46 bytes

Guardado dois bytes graças 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 teste

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

Casos de teste

a.exe
1
4
19

Mude *v++^91?0:i++para i+=*v==91para salvar 3 bytes.
kirbyfan64sos

@ kirbyfan64sos Obrigado! Ainda preciso incrementar v, mas posso usar i+=*v++==91para salvar dois bytes.
Cleblanc 11/11

1

repl do tinylisp , 39 bytes

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

Define uma função uque pode ser chamada como (u (q ((())()) ))(para o segundo caso de teste). Fazê-lo na repl salva 4 bytes devido a parênteses fechados automaticamente.

Explicação

(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

A x-(0-y)construção é necessária porque tinylisp não possui uma função de adição interna, apenas subtração.



1

Haskell, 20 19 17 bytes

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

Experimente online!

Pega a lista como string e coloca uma 1em uma lista para cada uma ], depois resume todas as1 s.


Versão sem ponto: (19 bytes)

length.filter(>'[')

Assume que , [ ]são os únicos caracteres na string. Filtra a lista para obter todos os caracteres maiores que[ , que são todos ]e retorna o comprimento.

Uso:

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

0

Bash + coreutils, 29 bytes

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

Você pode remover a maior parte disso e apenas fazer tr -d -c [|wc -c, que por padrão lerá a lista da entrada padrão.
kirbyfan64sos

0

DASH , 14 bytes

(ss[len;!> ="]

Simplesmente conta ]. Uso:

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

Solução de bônus, 15 bytes

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

Este conta recursivamente a partir de uma lista real. Uso:

(f\@+1sum ->#f#0)[[]]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.