Comptez les mots croisés

10

Considérez la grille de mots croisés standard 15 × 15 suivante .

Grille de mots croisés

Nous pouvons représenter cela dans l'art ASCII en utilisant #pour les blocs et (espace) pour les carrés blancs.

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

     ##   #    
   #       #   
    #   ##     

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

Étant donné une grille de mots croisés au format ASCII ci-dessus, déterminez le nombre de mots qu'il contient. (La grille ci-dessus contient 78 mots. Il s'agit du puzzle du New York Times de lundi dernier .)

Un mot est un groupe de deux espaces consécutifs ou plus s'étendant verticalement ou horizontalement. Un mot commence et se termine par un bloc ou le bord de la grille et court toujours de haut en bas ou de gauche à droite, jamais en diagonale ou en arrière. Notez que les mots peuvent s'étendre sur toute la largeur du puzzle, comme dans la sixième rangée du puzzle ci-dessus. Un mot n'a pas besoin d'être connecté à un autre mot.

Détails

  • L'entrée sera toujours un rectangle contenant les caractères #ou (espace), avec des lignes séparées par une nouvelle ligne ( \n). Vous pouvez supposer que la grille est composée de 2 caractères ASCII imprimables distincts au lieu de #et .
  • Vous pouvez supposer qu'il existe une nouvelle ligne facultative. Les caractères d'espace de fin comptent, car ils affectent le nombre de mots.
  • La grille ne sera pas toujours symétrique et il peut s'agir de tous les espaces ou de tous les blocs.
  • Votre programme devrait théoriquement pouvoir fonctionner sur une grille de n'importe quelle taille, mais pour ce défi, il ne sera jamais plus grand que 21 × 21.
  • Vous pouvez prendre la grille elle-même comme entrée ou le nom d'un fichier contenant la grille.
  • Prenez les entrées de stdin ou des arguments de ligne de commande et sortez vers stdout.
  • Si vous préférez, vous pouvez utiliser une fonction nommée au lieu d'un programme, en prenant la grille comme argument de chaîne et en sortant un entier ou une chaîne via stdout ou retour de fonction.

Cas de test

  1. Contribution:

        #
        #
        #
    

    Sortie: 7(Il y a quatre espaces avant chacun #. Le résultat serait le même si chaque signe numérique était supprimé, mais Markdown supprime les espaces des lignes autrement vides.)

  2. Contribution:

    ##
     #
    ##
    

    Sortie: 0(les mots d'une lettre ne comptent pas.)

  3. Contribution:

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

    Production: 4

  4. Entrée: ( puzzle du Sunday NY Times du 10 mai )

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

    Production: 140

Notation

Le code le plus court en octets gagne. Tiebreaker est le plus ancien poste.

NinjaBearMonkey
la source

Réponses:

7

CJam, 18 17 13 11 octets

2 octets enregistrés par Dennis.

Utilise des espaces pour les cellules remplies et 1pour les cellules vides:

qN/_z+:~1-,

Testez-le ici.

Explication

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
la source
9

Glissement , 18 + 3 = 21 octets

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

Exécute avec les drapeaux no(d'où le +3) et utilise espace / Xau lieu de l'espace / #. Chose ennuyeuse, c'est plus long que CJam / Pyth, mais je suppose que Slip n'a pas été conçu pour être un golfeur particulier ...

Essayez-le en ligne . Notez que le premier exemple manque d'espaces sur quelques lignes.

Explication

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

Le ndrapeau fait imprimer en sortie le nombre de correspondances, et le odrapeau permet les correspondances qui se chevauchent à partir du même carré. La raison du va-et-vient est que Slip essaie les correspondances à partir de chaque carré, et nous voulons nous assurer que nous ne correspondons qu'à une ligne complète plutôt qu'à une ligne partielle. Slip ne renvoie que des matchs uniques, même s'ils ont commencé à partir de positions différentes.

Remarque: à l'origine, j'avais >?( +(X|$^)<<){2}, avec le premier espace à l'intérieur. Cela manquerait certains cas avec 2 mots longs sur le bord, car le pointeur se présenterait comme suit:

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

[sp]    [sp]+$^    <<[sp]    [sp]+   (uh oh match fails)
Sp3000
la source
Pourquoi les deux drapeaux sont-ils trois octets?
lirtosiast
@ThomasKwa Je pense que la politique actuelle avec les drapeaux de ligne de commande est cette méta-publication , qui compte le nombre d'octets comme la différence par rapport à l'invocation habituelle du code. Voici donc la différence entre py -3 slip.py regex.txt input.txtet py -3 slip.py regex.txt input.txt no, qui est de trois octets (y compris l'espace avant n)
Sp3000
Ça a du sens. J'y pensais dans une perspective d'entropie; parfois j'oublie que ce sont des personnages que l'on compte.
lirtosiast
4

Haskell, 81 octets

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

Utilise les espaces comme caractères de bloc et tout autre caractère (non blanc) comme cellule vide.

Comment ça marche: divisez la saisie en liste de mots dans les espaces. Prenez un 1pour chaque mot avec au moins 2 caractères et additionnez ces 1s. Appliquez la même procédure à la transposition (divisée en \n) de l'entrée. Ajoutez les deux résultats.

nimi
la source
4

JavaScript ( ES6 ) 87 121 147

Construisez la transposition de la chaîne d'entrée et ajoutez-la à l'entrée, puis comptez les chaînes de 2 espaces ou plus.

Exécutez l'extrait dans Firefox pour tester.

Crédits @IsmaelMiguel, une solution pour ES5 (122 octets):

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
la source
1
Et alors 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]}? Il fait 113 octets de long. Votre expression régulière a été remplacée par / +/(2 espaces), le a j=0été ajouté dans la forboucle «parent» et au lieu d'utiliser la syntaxe obj.length, j'ai changé pour utiliser L='length'; ... obj[L], qui est répété 3 fois.
Ismael Miguel
Je l'ai fait fonctionner sur es6fiddle.net/iakdcpdh (au lieu de F=z=>, je devais l'utiliser var F=(z,i,L,j,r)=>). Je l'ai testé sur IE11 et ça marche!
Ismael Miguel
@IsmaelMiguel bien joué! et le mieux adapté pour ES5. En le regardant à nouveau, j'ai trouvé quelque chose de plus ES6ish et plus court. Vous pourriez peut-être publier votre solution pour ES5.
edc65
Non, c'est bon. C'était votre solution, je l'ai juste réduite. Je ne trouve pas juste de répondre comme si c'était la mienne.
Ismael Miguel
Maintenant que j'y pense, vous pouvez remplacer /\n/par une chaîne de modèle avec une vraie nouvelle ligne entre. Cela économise 1 octet puisque vous n'avez pas à écrire la séquence d'échappement.
Ismael Miguel
3

Pyth, 15 14 13 octets

lftTcjd+.zC.z

J'utilise comme séparateur et #comme caractères de remplissage au lieu de leur signification opposée de l'OP. Essayez-le en ligne: Démonstration

Au lieu d'un #caractère de remplissage, cela accepte également les lettres. Ainsi, vous pourriez réellement prendre le puzzle de mots croisés résolu et imprimer le nombre de mots. Et si vous supprimez la lcommande, elle imprime même tous les mots. Testez-le ici: le puzzle du Sunday Times du 10 mai

Explication

        .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
la source