Policz przekraczające słowa

10

Rozważ następującą standardową siatkę krzyżówek 15 × 15 .

Krzyżówka

Możemy to przedstawić w sztuce ASCII za pomocą #bloków i (spacji) białych kwadratów.

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

     ##   #    
   #       #   
    #   ##     

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

Biorąc pod uwagę siatkę krzyżówek w formacie graficznym ASCII powyżej, określ, ile słów zawiera. (Powyższa tabela ma 78 słów. Zdarza się, że jest to łamigłówka New York Times z ostatniego poniedziałku .)

Słowo to grupa dwóch lub więcej następujących po sobie spacji biegnących pionowo lub poziomo. Słowo zaczyna się i kończy blokiem lub krawędzią siatki i zawsze biegnie od góry do dołu lub od lewej do prawej, nigdy po przekątnej lub do tyłu. Pamiętaj, że słowa mogą obejmować całą szerokość układanki, tak jak w szóstym rzędzie układanki powyżej. Słowo nie musi być połączone z innym słowem.

Detale

  • Dane wejściowe zawsze będą prostokątem zawierającym znaki #lub (spację), z wierszami oddzielonymi znakiem nowej linii ( \n). Możesz założyć, że siatka składa się z 2 różnych drukowalnych znaków ASCII zamiast #i .
  • Możesz założyć, że istnieje opcjonalny znak nowej linii. Znaki końcowe spacji są liczone, ponieważ wpływają na liczbę słów.
  • Siatka nie zawsze będzie symetryczna i mogą to być wszystkie spacje lub wszystkie bloki.
  • Twój program powinien teoretycznie być w stanie pracować na siatce dowolnego rozmiaru, ale w przypadku tego wyzwania nigdy nie będzie większy niż 21 × 21.
  • Możesz wziąć samą siatkę jako dane wejściowe lub nazwę pliku zawierającego siatkę.
  • Weź dane wejściowe z argumentów stdin lub wiersza poleceń i wyślij je na standardowe wyjście.
  • Jeśli wolisz, możesz użyć funkcji o nazwie zamiast programu, biorąc siatkę za argument ciągu i wyprowadzając liczbę całkowitą lub ciąg znaków przez stdout lub return funkcji.

Przypadki testowe

  1. Wejście:

        #
        #
        #
    

    Wyjście: 7(Przed każdym są cztery spacje #. Wynik byłby taki sam, gdyby każdy znak liczbowy został usunięty, ale Markdown usuwa spacje z innych pustych linii).

  2. Wejście:

    ##
     #
    ##
    

    Wyjście: 0(Słowa jednoliterowe się nie liczą.)

  3. Wejście:

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

    Wynik: 4

  4. Dane wejściowe: ( układanka z niedzieli NY Times z 10 maja )

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

    Wynik: 140

Punktacja

Najkrótszy kod w bajtach wygrywa. Tiebreaker to najstarszy post.

NinjaBearMonkey
źródło

Odpowiedzi:

7

CJam, 18 17 13 11 bajtów

2 bajty zapisane przez Dennisa.

Używa spacji dla wypełnionych komórek i 1dla pustych komórek:

qN/_z+:~1-,

Sprawdź to tutaj.

Wyjaśnienie

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
źródło
9

Poślizg , 18 + 3 = 21 bajtów

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

Uruchom z flagami no(stąd +3) i używa spacji / Xzamiast spacji / #. Irytujące jest to dłuższe niż CJam / Pyth, ale myślę, że Slip nie został zaprojektowany specjalnie do gry w golfa ...

Wypróbuj online . Zauważ, że w pierwszym przykładzie brakuje spacji w kilku wierszach.

Wyjaśnienie

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

nFlag sprawia wydruk liczbę meczów, a oflaga umożliwia nakładających mecze począwszy od samego placu. Powodem do przodu i do tyłu jest to, że Slip próbuje dopasować, zaczynając od każdego kwadratu, i chcemy mieć pewność, że dopasowujemy tylko pełny wiersz, a nie częściowy. Poślizg zwraca tylko niepowtarzalne dopasowania, nawet jeśli rozpoczęły się z różnych pozycji.

Uwaga: pierwotnie miałem >?( +(X|$^)<<){2}, z pierwszym miejscem w środku. Pominąłoby to niektóre przypadki z 2 długimi spacjami na krawędzi, ponieważ wskaźnik wyglądałby tak:

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

[sp]    [sp]+$^    <<[sp]    [sp]+   (uh oh match fails)
Sp3000
źródło
Dlaczego te dwie flagi to trzy bajty?
lirtosiast
@ThomasKwa Myślę, że obecna polityka z flagami wiersza poleceń to ten meta post , który liczy liczbę bajtów jako różnicę od zwykłego wywołania kodu. Więc tutaj różnica jest między py -3 slip.py regex.txt input.txti py -3 slip.py regex.txt input.txt no, czyli trzy bajty (w tym spacja wcześniej n)
Sp3000,
To ma sens. Myślałem o tym z perspektywy entropii; czasami zapominam, że liczymy postacie.
lirtosiast
4

Haskell, 81 bajtów

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

Używa spacji jako znaków blokowych i dowolnego innego (niebiałego) znaku jako pustej komórki.

Jak to działa: podziel wprowadzanie na listę słów w spacjach. Weź 1za każde słowo z co najmniej 2 znakami i zsumuj je 1. Zastosuj tę samą procedurę do transpozycji (split at \n) wejścia. Dodaj oba wyniki.

nimi
źródło
4

JavaScript ( ES6 ) 87 121 147

Zbuduj transpozycję ciągu wejściowego i dołącz go do wejścia, a następnie policz ciągi 2 lub więcej spacji.

Uruchom fragment w przeglądarce Firefox, aby go przetestować.

Kredyty @ IsmaelMiguel, rozwiązanie dla ES5 (122 bajty):

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
źródło
1
Co 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]}? Ma długość 113 bajtów. Twój regex został zastąpiony / +/(2 spacje), j=0został dodany w forpętli „nadrzędnej” i zamiast korzystać ze składni obj.length, zmieniłem na use L='length'; ... obj[L], który powtarza się 3 razy.
Ismael Miguel
Mam go do pracy na es6fiddle.net/iakdcpdh (zamiast F=z=>, musiałem użyć var F=(z,i,L,j,r)=>). Przetestowałem to na IE11 i działa!
Ismael Miguel
@IsmaelMiguel dobrze zrobione! i najlepiej pasuje do ES5. Patrząc na to ponownie, znalazłem coś bardziej ES6ish i krótszego. Może mógłbyś opublikować swoje rozwiązanie dla ES5.
edc65
Nie, jest w porządku. To było twoje rozwiązanie, właśnie je zmniejszyłem. Nie wydaje mi się uczciwe odpowiadanie, jakby to było moje własne.
Ismael Miguel
Teraz, gdy o tym myślę, możesz zastąpić /\n/ciągiem szablonu z prawdziwą nową linią między. To oszczędza 1 bajt, ponieważ nie musisz pisać sekwencji ucieczki.
Ismael Miguel
3

Pyth, 15 14 13 bajtów

lftTcjd+.zC.z

Używam jako separatora i #jako znaków wypełniających zamiast ich przeciwnego znaczenia niż OP. Wypróbuj online: demonstracja

Zamiast #znaku wypełnienia przyjmuje także litery. Możesz wziąć rozwiązaną krzyżówkę i wydrukować liczbę słów. A jeśli usuniesz lpolecenie, drukuje nawet wszystkie słowa. Przetestuj tutaj: puzzle z 10 maja w niedzielę NY Times

Wyjaśnienie

        .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
źródło