Cuenta las palabras cruzadas

10

Considere la siguiente cuadrícula estándar de crucigramas de 15 × 15 .

Cuadrícula de crucigramas

Podemos representar esto en el arte ASCII utilizando #bloques y (espacio) para cuadrados blancos.

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

     ##   #    
   #       #   
    #   ##     

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

Dada una cuadrícula de crucigramas en el formato de arte ASCII anterior, determine cuántas palabras contiene. (La cuadrícula anterior tiene 78 palabras. Resulta ser el rompecabezas del New York Times del lunes pasado ).

Una palabra es un grupo de dos o más espacios consecutivos que se ejecutan vertical u horizontalmente. Una palabra comienza y termina con un bloque o el borde de la cuadrícula y siempre corre de arriba a abajo o de izquierda a derecha, nunca en diagonal o hacia atrás. Tenga en cuenta que las palabras pueden abarcar todo el ancho del rompecabezas, como en la sexta fila del rompecabezas de arriba. Una palabra no tiene que estar conectada a otra palabra.

Detalles

  • La entrada siempre será un rectángulo que contenga los caracteres #o (espacio), con filas separadas por una nueva línea ( \n). Puede suponer que la cuadrícula está compuesta de 2 caracteres ASCII imprimibles distintos en lugar de #y .
  • Puede suponer que hay una nueva línea final opcional. Los caracteres de espacio final SÍ cuentan, ya que afectan el número de palabras.
  • La cuadrícula no siempre será simétrica, y puede ser todos los espacios o todos los bloques.
  • Teóricamente, su programa debería poder trabajar en una cuadrícula de cualquier tamaño, pero para este desafío nunca será mayor que 21 × 21.
  • Puede tomar la cuadrícula como entrada o el nombre de un archivo que contiene la cuadrícula.
  • Tome la entrada de stdin o los argumentos de línea de comando y la salida a stdout.
  • Si lo prefiere, puede usar una función con nombre en lugar de un programa, tomando la cuadrícula como un argumento de cadena y generando un entero o una cadena a través de stdout o retorno de función.

Casos de prueba

  1. Entrada:

        #
        #
        #
    

    Salida: 7(Hay cuatro espacios antes de cada uno #. El resultado sería el mismo si se eliminara cada signo de número, pero Markdown elimina espacios de líneas vacías).

  2. Entrada:

    ##
     #
    ##
    

    Salida: 0(Las palabras de una letra no cuentan).

  3. Entrada:

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

    Salida: 4

  4. Entrada: ( rompecabezas del Sunday NY Times del 10 de mayo )

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

    Salida: 140

Puntuación

El código más corto en bytes gana. Tiebreaker es la publicación más antigua.

NinjaOsoMono
fuente

Respuestas:

7

CJam, 18 17 13 11 bytes

2 bytes guardados por Dennis.

Utiliza espacios para celdas llenas y 1para celdas vacías:

qN/_z+:~1-,

Pruébalo aquí.

Explicación

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
fuente
9

Slip , 18 + 3 = 21 bytes

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

Corre con las banderas no(de ahí el +3), y usa espacio / en Xlugar de espacio / #. Molesto, esto es más largo que CJam / Pyth, pero supongo que Slip no fue diseñado para ser un golf particular ...

Pruébalo en línea . Tenga en cuenta que al primer ejemplo le faltan espacios en algunas líneas.

Explicación

>?           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

La nbandera hace que la salida imprima el número de coincidencias, y la obandera permite coincidencias superpuestas comenzando desde el mismo cuadrado. La razón de la ida y vuelta es porque Slip intenta coincidencias comenzando desde cada casilla, y queremos asegurarnos de que solo coincidamos con una fila completa en lugar de una parcial. El deslizamiento solo devuelve coincidencias únicas, incluso si comenzaron desde diferentes posiciones.

Nota: Originalmente tenía >?( +(X|$^)<<){2}, con el primer espacio en el interior. Esto pasaría por alto algunos casos con 2 palabras largas en el borde, ya que el puntero sería así:

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

[sp]    [sp]+$^    <<[sp]    [sp]+   (uh oh match fails)
Sp3000
fuente
¿Por qué las dos banderas son tres bytes?
lirtosiast
@ThomasKwa Creo que la política actual con banderas de línea de comando es esta meta publicación , que cuenta el número de bytes como la diferencia de la invocación habitual del código. Así que aquí la diferencia es entre py -3 slip.py regex.txt input.txty py -3 slip.py regex.txt input.txt no, que son tres bytes (incluido el espacio anterior n)
Sp3000
Eso tiene sentido. Lo estaba pensando desde una perspectiva de entropía; a veces olvido que son los personajes los que contamos.
lirtosiast
4

Haskell, 81 bytes

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

Utiliza espacios como caracteres de bloque y cualquier otro carácter (no espacios en blanco) como una celda vacía.

Cómo funciona: divide la entrada en una lista de palabras en espacios. Tome un 1por cada palabra con al menos 2 caracteres y sume esos 1s. Aplique el mismo procedimiento a la transposición (división en \n) de la entrada. Añade ambos resultados.

nimi
fuente
4

JavaScript ( ES6 ) 87 121 147

Construya la transposición de la cadena de entrada y añádala a la entrada, luego cuente las cadenas de 2 o más espacios.

Ejecute el fragmento en Firefox para probar.

Créditos @IsmaelMiguel, una solución 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
fuente
1
¿Qué hay de 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]}? Tiene 113 bytes de longitud. Su expresión regular se reemplazó con / +/(2 espacios), j=0se agregó The en el forciclo 'padre' y en lugar de usar la sintaxis obj.length, cambié a usar L='length'; ... obj[L], que se repite 3 veces.
Ismael Miguel
Lo hice funcionar en es6fiddle.net/iakdcpdh (en lugar de F=z=>, tuve que usar var F=(z,i,L,j,r)=>). Lo probé en IE11 y funciona!
Ismael Miguel
@IsmaelMiguel bien hecho! y mejor para ES5. Al mirarlo de nuevo, encontré algo más ES6ish y más corto. Tal vez podría publicar su solución para ES5.
edc65
No está bien. Fue su solución, simplemente la reduje. No me parece justo responder como si fuera mío.
Ismael Miguel
Ahora que lo pienso, puede reemplazar /\n/con una cadena de plantilla con una nueva línea real entre ellas. Eso ahorra 1 byte ya que no tiene que escribir la secuencia de escape.
Ismael Miguel
3

Pyth, 15 14 13 bytes

lftTcjd+.zC.z

Estoy usando como separador y #como caracteres de relleno en lugar de su significado opuesto del OP. Pruébelo en línea: demostración

En lugar de #como carácter de relleno, esto también acepta letras. Por lo tanto, podría tomar el crucigrama resuelto, e imprimiría la cantidad de palabras. Y si elimina el lcomando, incluso imprime todas las palabras. Pruébalo aquí: el rompecabezas del Sunday NY Times del 10 de mayo

Explicación

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