Conte as palavras cruzadas

10

Considere a seguinte grade padrão de palavras cruzadas 15 × 15 .

Grade de palavras cruzadas

Podemos representar isso na arte ASCII usando #blocos e (espaço) quadrados brancos.

     #    #    
     #    #    
          #    
   #   #       
###     ##   ##

     ##   #    
   #       #   
    #   ##     

##   ##     ###
       #   #   
    #          
    #    #     
    #    #     

Dada uma grade de palavras cruzadas no formato de arte ASCII acima, determine quantas palavras ela contém. (A grade acima tem 78 palavras. É o quebra - cabeça do New York Times da última segunda-feira .)

Uma palavra é um grupo de dois ou mais espaços consecutivos em execução na vertical ou na horizontal. Uma palavra começa e termina com um bloco ou a borda da grade e sempre corre de cima para baixo ou da esquerda para a direita, nunca na diagonal ou para trás. Observe que as palavras podem abranger toda a largura do quebra-cabeça, como na sexta linha do quebra-cabeça acima. Uma palavra não precisa estar conectada a outra palavra.

Detalhes

  • A entrada sempre será um retângulo contendo os caracteres #ou (espaço), com linhas separadas por uma nova linha ( \n). Você pode assumir que a grade é composta por 2 caracteres ASCII imprimíveis distintos em vez de #e .
  • Você pode assumir que há uma nova linha à direita opcional. Os caracteres de espaço à direita contam, pois afetam o número de palavras.
  • A grade nem sempre será simétrica e pode ser todos os espaços ou todos os blocos.
  • Teoricamente, seu programa deve funcionar em uma grade de qualquer tamanho, mas para esse desafio nunca será maior que 21 × 21.
  • Você pode considerar a grade como entrada ou o nome de um arquivo que contém a grade.
  • Pegue a entrada dos argumentos stdin ou da linha de comando e envie para stdout.
  • Se preferir, você pode usar uma função nomeada em vez de um programa, tomando a grade como argumento de string e produzindo um número inteiro ou string via stdout ou retorno de função.

Casos de teste

  1. Entrada:

        #
        #
        #
    

    Saída: 7(Existem quatro espaços antes de cada um #. O resultado seria o mesmo se cada sinal numérico fosse removido, mas o Markdown removeria espaços de outras linhas vazias.)

  2. Entrada:

    ##
     #
    ##
    

    Saída: 0(palavras de uma letra não contam.)

  3. Entrada:

    ######
    #    #
      ####
    # ## #
    # ## #
    #### #
    

    Resultado: 4

  4. Entrada: ( quebra - cabeça do Sunday NY Times de 10 de maio )

       #    ##   #       
       #    #    #       
       #         #       
           #     ###   ##
        #       #        
    ##   #   #           
            #       ##   
          #   ##         
       #        ##      #
             #   ###   ##
    #   ##         ##   #
    ##   ###   #         
    #      ##        #   
             ##   #      
       ##       #        
               #   #   ##
            #       #    
    ##   ###     #       
           #         #   
           #    #    #   
           #   ##    #   
    

    Resultado: 140

Pontuação

O menor código em bytes vence. O desempate é o post mais antigo.

NinjaBearMonkey
fonte

Respostas:

7

CJam, 18 17 13 11 bytes

2 bytes salvos por Dennis.

Usa espaços para células preenchidas e 1para células vazias:

qN/_z+:~1-,

Teste aqui.

Explicação

q    e# Read the entire input.
N/   e# Split into lines.
_z   e# Make a copy and transpose it.
+    e# Add the lines of the two grids together.
:~   e# Evaluate each line which will push a rep-digit number for each empty-cell chunk.
1-   e# Remove all the 1s as these correspond to individual empty cells.
,    e# Get the length of the array.
Martin Ender
fonte
9

Deslizamento , 18 + 3 = 21 bytes

>? ( +(X|$^)<<){2}

Execute com os sinalizadores no(daí o +3) e use espaço / em Xvez de espaço / #. Irritantemente isso é mais longo que o CJam / Pyth, mas acho que o Slip não foi projetado para ser um jogo de golfe particular ...

Experimente online . Observe que o primeiro exemplo está faltando espaços em algumas linhas.

Explicação

>?           Optionally turn right, hence matching either horizontally or vertically
[space]      Match a space
(    ){2}    Group, twice:
[space]+       Match 1+ spaces
(X|$^)         Either an X or the boundary of the grid
<<             Reverse the match pointer by turning left twice

O nsinalizador faz com que a saída imprima o número de correspondências, e a osinalização permite correspondências sobrepostas a partir do mesmo quadrado. A razão para isso é que o Slip tenta correspondências a partir de cada quadrado, e queremos garantir que correspondamos apenas a uma linha completa, em vez de parcial. O deslizamento retorna apenas correspondências únicas, mesmo que tenham começado de posições diferentes.

Nota: Originalmente eu tinha >?( +(X|$^)<<){2}, com o primeiro espaço no interior. Faltariam alguns casos com duas palavras longas no espaço, pois o ponteiro seria assim:

XXX       XXX       XXX       XXX
X>        X >       X<        <
XXX       XXX       XXX       XXX

[sp]    [sp]+$^    <<[sp]    [sp]+   (uh oh match fails)
Sp3000
fonte
Por que os dois sinalizadores são três bytes?
lirtosiast
@ThomasKwa Acho que a política atual com sinalizadores de linha de comando é essa meta post , que conta o número de bytes como a diferença da invocação usual do código. Então aqui é a diferença entre py -3 slip.py regex.txt input.txte py -3 slip.py regex.txt input.txt no, o que é três bytes (incluindo o espaço antes n)
SP3000
Isso faz sentido. Eu estava pensando sobre isso de uma perspectiva de entropia; às vezes esqueço que são personagens que contamos.
precisa saber é o seguinte
4

Haskell, 81 bytes

import Data.List
m x=sum[1|(_:_:_)<-words x]
f x=m x+m(unlines$transpose$lines x)

Usa espaços como caracteres de bloco e qualquer outro caractere (sem espaço em branco) como uma célula vazia.

Como funciona: divida a entrada na lista de palavras nos espaços. Pegue um 1para cada palavra com pelo menos 2 caracteres e some esses 1s. Aplique o mesmo procedimento à transposição (dividida em \n) da entrada. Adicione os dois resultados.

nimi
fonte
4

JavaScript ( ES6 ) 87121 147

Crie a transposição da sequência de entrada e anexe-a à entrada e conte as sequências de 2 ou mais espaços.

Execute o trecho no Firefox para testar.

Créditos @IsmaelMiguel, uma solução para ES5 (122 bytes):

function F(z){for(r=z.split(/\n/),i=0;i<r[j=0][L='length'];i++)for(z+='#';j<r[L];)z+=r[j++][i];return~-z.split(/  +/)[L]};

F=z=>
(
  r=z.split(/\n/),
  [r.map(r=>z+=r[i],z+='#')for(i in r[0])],
  ~-z.split(/  +/).length
)

// TEST
out=x=>O.innerHTML += x + '\n';

[
'     #    #    \n     #    #    \n          #    \n   #   #       \n###     ##   ##\n               \n     ##   #    \n   #       #   \n    #   ##     \n               \n##   ##     ###\n       #   #   \n    #          \n    #    #     \n    #    #     ', '##\n #\n##', '    #\n    #\n    #',
 '######\n#    #\n  ####\n# ## #\n# ## #\n#### #',
 '   #    ##   #       \n   #    #    #       \n   #         #       \n       #     ###   ##\n    #       #        \n##   #   #           \n        #       ##   \n      #   ##         \n   #        ##      #\n         #   ###   ##\n#   ##         ##   #\n##   ###   #         \n#      ##        #   \n         ##   #      \n   ##       #        \n           #   #   ##\n        #       #    \n##   ###     #       \n       #         #   \n       #    #    #   \n       #   ##    #   '  
].forEach(x=>out(x.replace(/ /g,'.')+'\n'+F(x)+'\n'))
<pre id=O></pre>

edc65
fonte
11
Que tal F=z=>{for(r=z.split(/\n/),i=0;i<r[j=0][L='length'];i++)for(z+='#';j<r[L];)z+=r[j++][i];return~-z.split(/ +/)[L]}? Tem 113 bytes. Seu regex foi substituído por / +/(2 espaços), O j=0foi adicionado no forloop 'pai' e, em vez de usar a sintaxe obj.length, mudei para uso L='length'; ... obj[L], que é repetido 3 vezes.
Ismael Miguel
Consegui fazê-lo funcionar em es6fiddle.net/iakdcpdh (em vez de F=z=>precisar usar var F=(z,i,L,j,r)=>). Eu testei no IE11 e funciona!
Ismael Miguel
@IsmaelMiguel well done! e melhor ajuste para ES5. Olhando novamente, encontrei algo mais ES6ish e mais curto. Talvez você possa publicar sua solução para o ES5.
Edc65 6/06/2015
Não, está tudo bem. Foi a sua solução, eu apenas a reduzi. Não acho justo responder como se fosse meu.
Ismael Miguel
Agora que penso nisso, você pode substituir /\n/por uma sequência de modelos por uma nova linha real entre elas. Isso economiza 1 byte, pois você não precisa escrever a sequência de escape.
Ismael Miguel
3

Pitão, 15 14 13 bytes

lftTcjd+.zC.z

Estou usando como separador e #como caracteres de preenchimento, em vez de seu significado oposto ao OP. Experimente online: Demonstração

Em vez de #como caractere de preenchimento, isso também aceita letras. Assim, você pode realmente pegar as palavras cruzadas resolvidas e imprimir o número de palavras. E se você remover o lcomando, ele imprimirá todas as palavras. Teste aqui: quebra-cabeça do Sunday NY Times de 10 de maio

Explicação

        .z      all input rows
          C.z   all input columns (C transposes)
       +        add them (all rows and columns)
     jd         join by spaces
    c           split by spaces
 f              filter for pieces T, which satisfy:
  tT              len(T) > 1
l               length, implicitly printed
Jakube
fonte