Zähle die sich kreuzenden Wörter

10

Betrachten Sie das folgende Standard-15 × 15- Kreuzworträtselraster .

Kreuzworträtselgitter

Wir können dies in der ASCII-Kunst darstellen, indem wir #für Blöcke und (Leerzeichen) für weiße Quadrate verwenden.

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

     ##   #    
   #       #   
    #   ##     

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

Bestimmen Sie anhand eines Kreuzworträtsels im obigen ASCII-Grafikformat, wie viele Wörter es enthält. (Das obige Raster enthält 78 Wörter. Es ist zufällig das New York Times- Puzzle vom letzten Montag .)

Ein Wort ist eine Gruppe von zwei oder mehr aufeinanderfolgenden Leerzeichen, die vertikal oder horizontal verlaufen. Ein Wort beginnt und endet entweder mit einem Block oder der Kante des Gitters und verläuft immer von oben nach unten oder von links nach rechts, niemals diagonal oder rückwärts. Beachten Sie, dass Wörter die gesamte Breite des Puzzles umfassen können, wie in der sechsten Zeile des Puzzles oben. Ein Wort muss nicht mit einem anderen Wort verbunden sein.

Einzelheiten

  • Die Eingabe ist immer ein Rechteck mit den Zeichen #oder (Leerzeichen), wobei die Zeilen durch eine neue Zeile ( \n) getrennt sind. Sie können davon ausgehen, dass das Raster aus 2 verschiedenen druckbaren ASCII- Zeichen anstelle von #und besteht .
  • Sie können davon ausgehen, dass es eine optionale nachfolgende Newline gibt. Nachgestellte Leerzeichen zählen, da sie die Anzahl der Wörter beeinflussen.
  • Das Gitter ist nicht immer symmetrisch und es können alle Leerzeichen oder alle Blöcke sein.
  • Ihr Programm sollte theoretisch in der Lage sein, an einem Raster beliebiger Größe zu arbeiten, aber für diese Herausforderung wird es niemals größer als 21 × 21 sein.
  • Sie können das Raster selbst als Eingabe oder den Namen einer Datei verwenden, die das Raster enthält.
  • Nehmen Sie Eingaben von stdin oder Befehlszeilenargumenten und geben Sie sie an stdout aus.
  • Wenn Sie möchten, können Sie anstelle eines Programms eine benannte Funktion verwenden, das Raster als Zeichenfolgenargument verwenden und eine Ganzzahl oder Zeichenfolge über stdout oder Funktionsrückgabe ausgeben.

Testfälle

  1. Eingang:

        #
        #
        #
    

    Ausgabe: 7(Vor jedem stehen vier Leerzeichen #. Das Ergebnis wäre dasselbe, wenn jedes Zahlenzeichen entfernt würde, aber Markdown entfernt Leerzeichen von ansonsten leeren Zeilen.)

  2. Eingang:

    ##
     #
    ##
    

    Ausgabe: 0(Ein-Buchstaben-Wörter zählen nicht.)

  3. Eingang:

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

    Ausgabe: 4

  4. Eingabe: (Sonntag, 10. Mai, Rätsel der NY Times )

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

    Ausgabe: 140

Wertung

Der kürzeste Code in Bytes gewinnt. Tiebreaker ist der älteste Beitrag.

NinjaBearMonkey
quelle

Antworten:

7

CJam, 18 17 13 11 Bytes

2 Bytes von Dennis gespeichert.

Verwendet Leerzeichen für gefüllte Zellen und 1für leere Zellen:

qN/_z+:~1-,

Testen Sie es hier.

Erläuterung

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

Slip , 18 + 3 = 21 Bytes

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

Führen Sie mit den Flags no(daher +3) aus und verwenden Sie Leerzeichen / Xanstelle von Leerzeichen / #. Ärgerlicherweise ist dies länger als CJam / Pyth, aber ich denke, Slip wurde nicht speziell für Golfspieler entwickelt ...

Probieren Sie es online aus . Beachten Sie, dass im ersten Beispiel in einigen Zeilen Leerzeichen fehlen.

Erläuterung

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

Das nFlag bewirkt, dass die Ausgabe die Anzahl der Übereinstimmungen druckt, und das oFlag ermöglicht überlappende Übereinstimmungen ab demselben Quadrat. Der Grund für das Hin und Her ist, dass Slip versucht, Übereinstimmungen von jedem Quadrat aus zu starten, und wir möchten sicherstellen, dass wir nur eine vollständige Zeile und keine teilweise übereinstimmen. Slip gibt nur eindeutige Übereinstimmungen zurück, auch wenn sie von verschiedenen Positionen aus gestartet wurden.

Hinweis: Ursprünglich hatte ich >?( +(X|$^)<<){2}mit dem ersten Leerzeichen innen. Dies würde einige Fälle mit 2 Leerzeichen langen Wörtern am Rand übersehen, da der Zeiger folgendermaßen aussehen würde:

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

[sp]    [sp]+$^    <<[sp]    [sp]+   (uh oh match fails)
Sp3000
quelle
Warum sind die beiden Flags drei Bytes?
Lirtosiast
@ThomasKwa Ich denke, die aktuelle Richtlinie mit Befehlszeilenflags ist dieser Meta-Post , der die Anzahl der Bytes als Differenz zum üblichen Aufruf des Codes zählt. Also hier ist der Unterschied zwischen py -3 slip.py regex.txt input.txtund py -3 slip.py regex.txt input.txt no, das sind drei Bytes (einschließlich des Leerzeichens vor n)
Sp3000
Das macht Sinn. Ich habe aus einer Entropieperspektive darüber nachgedacht; manchmal vergesse ich, dass es Zeichen sind, die wir zählen.
Lirtosiast
4

Haskell, 81 Bytes

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

Verwendet Leerzeichen als Blockzeichen und jedes andere Zeichen (kein Leerzeichen) als leere Zelle.

So funktioniert es: Teilen Sie die Eingabe in eine Liste von Wörtern an Leerzeichen auf. Nehmen Sie 1für jedes Wort ein mit mindestens 2 Zeichen und addieren Sie diese 1s. Wenden Sie das gleiche Verfahren auf die Transposition (Split at \n) des Eingangs an. Fügen Sie beide Ergebnisse hinzu.

Nimi
quelle
4

JavaScript ( ES6 ) 87 121 147

Erstellen Sie die Transposition der Eingabezeichenfolge, hängen Sie sie an die Eingabe an und zählen Sie dann die Zeichenfolgen mit 2 oder mehr Leerzeichen.

Führen Sie das Snippet in Firefox aus, um es zu testen.

Credits @IsmaelMiguel, eine Lösung für 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
quelle
1
Was ist mit 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]}? Es ist 113 Bytes lang. Ihr regulärer Ausdruck wurde durch / +/(2 Leerzeichen) ersetzt. Der j=0wurde in der übergeordneten forSchleife hinzugefügt. Statt die Syntax zu verwenden obj.length, habe ich die Verwendung geändert L='length'; ... obj[L], die dreimal wiederholt wird.
Ismael Miguel
Ich habe es auf es6fiddle.net/iakdcpdh zum Laufen gebracht (stattdessen F=z=>musste ich es verwenden var F=(z,i,L,j,r)=>). Ich habe es auf IE11 getestet und es funktioniert!
Ismael Miguel
@IsmaelMiguel gut gemacht! und am besten für ES5 geeignet. Als ich es mir noch einmal ansah, fand ich etwas ES6ischeres und kürzeres. Vielleicht könnten Sie Ihre Lösung für ES5 veröffentlichen.
edc65
Nein ist schon ok. Es war deine Lösung, ich habe sie nur reduziert. Ich finde es nicht fair zu antworten, als ob es meine eigene wäre.
Ismael Miguel
Jetzt, wo ich darüber nachdenke, können Sie durch /\n/eine Vorlagenzeichenfolge mit einer echten neuen Zeile dazwischen ersetzen. Das spart 1 Byte, da Sie die Escape-Sequenz nicht schreiben müssen.
Ismael Miguel
3

Pyth, 15 14 13 Bytes

lftTcjd+.zC.z

Ich verwende als Trennzeichen und #als Füllzeichen anstelle ihrer entgegengesetzten Bedeutung aus dem OP. Probieren Sie es online aus: Demonstration

Anstelle eines #Füllzeichens werden auch Buchstaben akzeptiert. Sie könnten also tatsächlich das gelöste Kreuzworträtsel lösen und die Anzahl der Wörter drucken. Wenn Sie den lBefehl entfernen , werden sogar alle Wörter gedruckt. Testen Sie es hier: Das Sunday NY Times-Puzzle vom 10. Mai

Erläuterung

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