Suportes de bloqueio

30

Escreva um programa ou função que utilize uma cadeia de oito bytes contendo um de cada um dos caracteres ()[]{}<>organizados de maneira que os quatro tipos de colchetes respectivos correspondam. Por exemplo, ]<([){}>é uma entrada inválida porque os colchetes não correspondem (embora todos os outros correspondam).

Imprima ou retorne um número inteiro de 0para 6que indica quantos dos seis possíveis pares dos quatro tipos de colchetes estão intertravados. Os pares de tipos de colchetes são considerados intertravados se ocorrer exatamente um colchete de um tipo entre os colchetes do outro tipo. Assim, ([)]e [(])estão interligados, mas ()[], [](), ([]), e [()]não são.

O código mais curto em bytes vence.

Exemplos de entrada / saída

()[]{}<> : 0
([{<>}]) : 0
<>{[]}() : 0
{<>([])} : 0
<(>)[{}] : 1
<[({)}]> : 1
[{<}]>() : 2
{<>([}]) : 2
<{(>})[] : 3
[(]<){>} : 3
<([>{)}] : 4
(<{[>})] : 4
(<[{)>}] : 5
<{[(>})] : 5
[{<(]}>) : 6
(<{[)>}] : 6
Passatempos de Calvin
fonte

Respostas:

17

CJam, 18

l7~f&_f{\/~;&}s,2/

Obrigado isaacg por algumas idéias de golfe :)
Experimente on-line ou tente todos os exemplos

Explicação:

l         read a line of input
7~f&      clear the lowest 3 bits of each character
           the goal is to convert brackets of the same type to the same char
_         duplicate the resulting string, let's call it S
f{…}      for each character in S, and S (the char and S are pushed every time)
  \       swap the character with S
  /       split S around that character, resulting in 3 pieces:
           before, between, after
  ~       dump the pieces on the stack
  ;       pop the last piece
  &       intersect the first 2 pieces
          after the loop, we have an array of strings
          containing the chars interlocking to the left with each char of S
s         join all the string into one string
,         get the string length
2/        divide by 2, because S has duplicated characters
aditsu
fonte
1
Ah, então você é o cara que criou o CJam ?? Você me deve todas as respostas que perdi que foram vencidas pelas respostas do CJam! ;)
kirbyfan64sos
6
@ kirbyfan64sos bem, é melhor você começar a aprender também se quiser ganhar :)
aditsu
9
7~f&? Eu já gosto dessa resposta e nem li o resto.
Dennis
11

Python 2, 163 bytes

def f(b,e='([{<)]}>',q=range(4)):
 b=[b[b.index(e[j])+1:b.index(e[j+4])]for j in q]
 print sum(sum(abs(b[k].count(e[j])-b[k].count(e[j+4]))for j in q)for k in q)/2

Ele examina as coisas entre cada par de colchetes correspondentes e conta o número de colchetes individuais à esquerda ou à direita presentes. A soma destes divididos por dois é a saída.

Tenho certeza de que poderia ser muito mais jogado por jogadores melhores do que eu.

Passatempos de Calvin
fonte
31
Bem, aconteceu. Calvin postou uma resposta. O fim dos tempos está chegando.
Alex A.
4

GNU sed -r, 147

A saída é unária conforme esta meta-resposta .

y/([{</)]}>/
s/.*/\t& & & & /
:b
y/)]}>/]}>)/
s/\S*>(\S*)>\S* /\1\t/
t
s/\S* //
:
s/(\t\S*)(\S)(\S*)\2(\S*\t)/\1\3\4/
t
s/\S *$/&/
tb
s/\s//g
s/../1/g

Nota: Substitua \tportab caracteres para obter a pontuação correta. No entanto, o programa funcionará de qualquer maneira com o GNU sed.

Experimente online .

Trauma Digital
fonte
3

Perl, 77 bytes

76 código + 1 comutador

perl -pe 'y/)]}>/([{</;for$x(/./g){$h{$x="\\$x"}++&&s!$x(.*)$x!$z+=length$1,$1!e}$_=$z'

Recebe informações do STDIN e o programa deve ser iniciado de novo para cada entrada.

Explicação

  1. Substitua todos os suportes de fechamento por seus correspondentes abertos (y/.../.../ ).
  2. Em seguida, para cada caractere na sequência de entrada ( for$x...), aumente um contador para o caractere ($h{$x}++ ).
  3. Se for a segunda vez que vemos o personagem, obtenha a distância entre as duas ocorrências ( length $1) e remova ambas as ocorrências desse caractere da string. Por exemplo, se a sequência fosse ([{([{<<, existem dois caracteres [e {entre os dois (s. Depois que os (s são processados, a sequência se torna[{[{<< e adicionamos 2 ao número total ( $z) de colchetes.
  4. O resultado é obtido de $z( $_=$z)
svsd
fonte
3

Pitão, 20 bytes

JmC/CdTzlsm@FPcsJd{J

Suíte de teste

JmC/CdTz: Primeiro, isso converte cada par de símbolos em um único caractere, mapeando cada caractere de entrada para seu código de caractere ( Cd) dividido por 10 ( / T), que é o mesmo para cada par, mas diferente entre todos os pares. O número resultante é convertido novamente em um caractere para fins a serem revelados posteriormente ( C). A lista de caracteres resultante é salva em J.

lsm@FPcsJd{J: Agora, mapeamos os caracteres únicos em J( {J). Começamos cortando a string formada concatenando Jusando o caractere atual como delimeter ( csJd). Um par de colchetes se sobrepõe ao par atual se ele aparecer no segundo grupo e no primeiro ou terceiro grupo. Para evitar a contagem dupla, apenas contaremos o primeiro e o segundo caso de grupo. Portanto, removemos o terceiro grupo ( P) e fazemos a interseção dos demais grupos ( @F). Por fim, concatenamos os caracteres de sobreposição ( s) e imprimimos o comprimento do resultado ( l).

isaacg
fonte
3

Python 3, 107

t=0
s=""
for x in input():s+=chr(ord(x)&~7)
for x in s:a=s.split(x);t+=len(set(a[0])&set(a[1]))
print(t//2)

Vagamente baseado na minha solução CJam.

aditsu
fonte
3

Retina , 128 108 64 62 55 bytes

(T`)]>}`([<{
(\D)(.*)\1(.*)
\n$2\n$3
(?=(\D).*\n.*\1)
1
\n
<empty>

Onde <empty>representa uma linha de fuga vazia. Para fins de contagem, coloque cada linha em um arquivo separado e substitua \npor caracteres reais de avanço de linha. Por conveniência, você pode usar esse código equivalente com o -ssinalizador de um único arquivo:

(T`)]>}`([<{
(\D)(.*)\1(.*)
#$2#$3
(?=(\D)[^#]*#[^#]*\1)
1
#
<empty>

Saída unária .

Explicação

O primeiro (diz ao Retina para executar o código inteiro em um loop até que uma iteração pare de alterar a string. Nesse caso, ele sempre repetirá quatro vezes, uma vez para cada tipo de colchete.

T`)]>}`([<{

Isso simplesmente transforma cada colchete de fechamento no colchete de abertura correspondente, para que possamos combinar os colchetes correspondentes com uma referência simples mais tarde. (Esse estágio se torna um não operacional após a primeira iteração. Ele está incluído apenas no loop, porque o Tjá exigia um backtick, portanto, a adição (custa apenas um em vez de dois bytes.)

(\D)(.*)\1(.*)
\n$2\n$3

Isso substitui o par de colchetes mais à esquerda por novas linhas. Usamos \Dpara distinguir colchetes dos 1s que adicionamos posteriormente no loop para contagem. O (.*)final garante que apenas um par seja substituído (porque as correspondências não podem se sobrepor).

(?=(\D).*\n.*\1)
1

A regex inteira está em um lookahead, portanto, isso corresponde a uma posição . Mais especificamente, ele corresponde a uma posição para cada par de colchetes que foi separada pelos outros colchetes que acabamos de transformar em novas linhas. A 1é inserido em cada uma dessas posições. Podemos simplesmente deixar os 1s lá, porque eles não afetam nenhuma das outras expressões regulares (porque eles \Dgarantem que não os correspondemos acidentalmente).

\n
<empty>

Por fim, removemos as novas linhas (ou seja, os espaços reservados para o tipo atual de colchetes) - isso significa que reduzimos o problema restante para uma sequência de comprimento 6 que contém apenas 3 tipos de colchetes, mas, caso contrário, funciona exatamente da mesma maneira.

No final, apenas os 1s inseridos serão deixados, e sua quantidade corresponde exatamente ao número de colchetes.

Martin Ender
fonte
2

JavaScript (ES7), 121 117 bytes

x=>(a=b=0,[for(c of x)for(d of'1234')(e=c.charCodeAt()/26|0)==d?a^=1<<d:b^=(a>>d&1)<<d*4+e],f=y=>y&&y%2+f(y>>1))(b)/2

Uau. Foi divertido. Esbocei uma ideia de resposta quando esse desafio foi lançado, mas ele tinha mais de 150 bytes e não queria me esforçar para jogá-lo. Encontrei essa idéia no meu notebook ontem e decidi que não iria parar de pensar nela até que eu tivesse jogado o golfe completamente. Acabei escrevendo dois algoritmos inteiramente novos, o primeiro dos quais acabou vários bytes mais curto depois de jogar cerca de 25 bytes com toneladas de hackers de bits.

Como funciona

Primeiro, definimos variáveis ae bcomo 0. aé uma matriz binária de 4 bits cujos pares de colchetes estamos atualmente no interior e bé uma matriz binária de 16 bits cujos pares de colchetes estão vinculados.

Em seguida, vamos percorrer cada personagem cem x, e cada caractere dem '0123'. Primeiro, determinar que tipo de suporte cé com e=c.charCodeAt()/26-1|0. Os códigos de caracteres decimais de cada tipo de colchete são os seguintes:

() => 40,41
<> => 60,62
[] => 91,93
{} => 123,125

Dividindo por 26, subtraindo 1 e revestimento, nós os mapeamos para 0, 1, 2 e 3, respectivamente.

Em seguida, verificamos se esse número é igual ao valor atual de d. Se for, estamos entrando ou saindo do dtipo de parêntese, então trocamos o dth acom a^=1<<d. Se não é, mas nós estão dentro do dsuporte tipo th, precisamos virar o eth pouco na dseção de 4 bits th b. Isso é feito da seguinte maneira:

b^=(a>>d&1)<<d*4+e

(a>>d&1)Retorna o dth bit a. Se estivermos dentro do dtipo de colchete, isso retornará 1; caso contrário, ele retornará 0. Em seguida, mudamos isso para a esquerda por d*4+ebits e XOR bpelo resultado. Se estivermos dentro do dtipo de colchete, este XOR será o d*4+eth bit b; caso contrário, não faz nada.

No final de todo o loop, bconterá um número de 1 bits igual ao dobro do valor de retorno desejado. Mas ainda precisamos descobrir quantos bits são esses. É aí que fentra a sub-função :

f=y=>y&&y%2+f(y>>1)

Se yfor 0, isso simplesmente retorna 0. Caso contrário, ele leva o último bit de ycom y%2e adiciona o resultado da execução de todos, exceto o último bit, yatravés da função novamente. Por exemplo:

f(y)         => y && y%2 + f(y>>1)
f(0b1001101) =>       1  + f(0b100110) = 4
f(0b100110)  =>       0  + f(0b10011)  = 3
f(0b10011)   =>       1  + f(0b1001)   = 3
f(0b1001)    =>       1  + f(0b100)    = 2
f(0b100)     =>       0  + f(0b10)     = 1
f(0b10)      =>       0  + f(0b1)      = 1
f(0b1)       =>       1  + f(0b0)      = 1
f(0b0)       => 0                      = 0

Executamos bessa função e dividimos o resultado por 2, e aqui está a nossa resposta.

ETHproductions
fonte
1

Oracle SQL 11.2, 206 bytes

WITH v AS(SELECT b,MIN(p)i,MAX(p)a FROM(SELECT SUBSTR(TRANSLATE(:1,'])>}','[(<{'),LEVEL,1)b,LEVEL p FROM DUAL CONNECT BY LEVEL<9)GROUP BY b)SELECT COUNT(*)FROM v x,v y WHERE x.i<y.i AND x.a<y.a AND y.i<x.a;

Sem golfe:

WITH v AS( -- Compute min and max pos for each bracket type
           SELECT b,MIN(p)i,MAX(p)a 
           FROM   ( -- replace ending brackets by opening brakets and split the string  
                    SELECT SUBSTR(TRANSLATE(:1,'])>}','[(<{'),LEVEL,1)b,LEVEL p 
                    FROM DUAL 
                    CONNECT BY LEVEL<9
                  )
           GROUP BY b
         )
SELECT COUNT(*)
FROM   v x,v y
WHERE  x.i<y.i AND x.a<y.a AND y.i<x.a -- Apply restrictions for interlocking brackets  
Jeto
fonte