Порахуйте перекресні слова


10

Розглянемо наступну стандартну сітку кросвордів розміром 15 × 15 .

Кросвордна сітка

Ми можемо представити це в мистецтві ASCII, використовуючи #для блоків та (пробіл) для білих квадратів.

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

     ##   #    
   #       #   
    #   ##     

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

Надавши сітку кросворду у форматі мистецтва ASCII вище, визначте, скільки слів він містить. (Наведена вище сітка має 78 слів. Це, мабуть, головоломка New York Times минулого понеділка .)

Слово - це група з двох або більше послідовних пробілів, що працюють вертикально або горизонтально. Слово починається і закінчується блоком або краєм сітки і завжди проходить зверху вниз або вліво-вправо, ніколи не по діагоналі або назад. Зауважте, що слова можуть охоплювати всю ширину головоломки, як у шостому ряду головоломки вище. Слово не повинно бути пов'язане з іншим словом.

Деталі

  • Введенням завжди буде прямокутник, що містить символи #або (пробіл), рядки розділені новим рядком ( \n). Ви можете припустити, що сітка складається з будь-яких 2 відмінних символів для друку ASCII замість #та .
  • Ви можете припустити, що є необов'язковий затримка нового рядка. Символи пробілів, що знаходяться в пробілі, НЕ рахуються, оскільки вони впливають на кількість слів.
  • Сітка не завжди буде симетричною, і це можуть бути всі пробіли або всі блоки.
  • Ваша програма теоретично повинна мати змогу працювати над сіткою будь-якого розміру, але для цього завдання вона ніколи не буде більше 21 × 21.
  • Ви можете взяти саму сітку як вхід або назву файла, що містить сітку.
  • Візьміть введення аргументів stdin або командного рядка та виведіть у stdout.
  • Якщо ви віддаєте перевагу, ви можете використовувати іменовану функцію замість програми, приймаючи сітку як аргумент рядка та виводячи ціле число чи рядок через stdout або return return.

Тестові справи

  1. Вхід:

        #
        #
        #
    

    Вихід: 7(Перед кожним є чотири пробіли #. Результат був би однаковий, якби кожен знак числа був видалений, але Маркдаун знімає пробіли з інших порожніх рядків.)

  2. Вхід:

    ##
     #
    ##
    

    Вихід: 0(Однолітерні слова не враховуються.)

  3. Вхід:

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

    Вихід: 4

  4. Вхід: ( пазл 10 травня в неділю NY Times )

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

    Вихід: 140

Оцінка балів

Виграє найкоротший код у байтах . Tiereaker - найстаріший пост.

Відповіді:


7

CJam, 18 17 13 11 байт

Денніс врятував 2 байти.

Використовує пробіли для заповнених комірок і 1для порожніх комірок:

qN/_z+:~1-,

Тестуйте це тут.

Пояснення

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.

9

Ковзання , 18 + 3 = 21 байт

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

Запустіть прапорами no(звідси +3) і використовуйте пробіл / Xзамість місця / #. Прикро, що це довше, ніж CJam / Pyth, але я думаю, Slip не був розроблений, щоб бути особливим гольфу ...

Спробуйте в Інтернеті . Зауважте, що в першому прикладі відсутні пробіли в декількох рядках.

Пояснення

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

nПрапора робить висновок на друк кількості збігів, і oпрапор дозволяє перекриваються матчі , починаючи з однієї і тієї ж площі. Причиною тому і назад є те, що Slip намагається відповідати матчам, починаючи з кожного квадрата, і ми хочемо переконатися, що ми відповідаємо лише повному, а не частковому. Slip повертає лише унікальні матчі, навіть якщо вони розпочалися з різних позицій.

Примітка: Спочатку у мене був >?( +(X|$^)<<){2}перший пробіл на внутрішній стороні. Це пропустить деякі випадки з двома пробілами довгих слів на краю, оскільки вказівник піде так:

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

[sp]    [sp]+$^    <<[sp]    [sp]+   (uh oh match fails)

Чому у двох прапорів три байти?
lirtosiast

@ThomasKwa Я думаю, що поточна політика з прапорами командного рядка - це метапост , який рахує кількість байтів як різницю від звичайного виклику коду. Тож тут різниця між py -3 slip.py regex.txt input.txtі py -3 slip.py regex.txt input.txt no, що становить три байти (включаючи пробіл раніше n)
Sp3000

Що має сенс. Я думав про це з точки зору ентропії; іноді я забуваю, що ми рахуємо символів.
lirtosiast

4

Haskell, 81 байт

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

Використовує пробіли як символи блоків та будь-який інший символ (не пробіл) як порожню клітинку.

Як це працює: розділіть введення на список слів у пробілах. Візьміть 1за кожне слово з орендою 2 символи та підсумовуйте ці 1s. Застосуйте ту саму процедуру для переміщення (розділення на \n) вводу. Додайте обидва результати.


4

JavaScript ( ES6 ) 87 121 147

Побудуйте транспозицію вхідного рядка та додайте його до вводу, а потім підрахуйте рядки з 2 або більше пробілів.

Запустіть фрагмент у Firefox для тестування.

Credits @IsmaelMiguel, рішення для ES5 (122 байти):

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>


1
Про що 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]}? Це довжина 113 байт. Ваш регулярний вираз було замінено на / +/(2 пробіли), The j=0додано у forциклі 'батьків' і замість синтаксису obj.lengthя змінив на використання L='length'; ... obj[L], що повторюється 3 рази.
Ісмаель Мігель

Я змусив його працювати на es6fiddle.net/iakdcpdh (замість цього F=z=>я повинен був використовувати var F=(z,i,L,j,r)=>). Я тестував його на IE11 і він працює!
Ісмаїл Мігель

@IsmaelMiguel молодець! і найкраще підходить для ES5. Подивившись ще раз, я знайшов щось більш ES6ish і коротше. Можливо, ви могли б опублікувати своє рішення для ES5.
edc65

Ні, це гаразд. Це було ваше рішення, я просто скоротив його. Я не вважаю справедливим відповідати так, ніби це було моє власне.
Ісмаель Мігель

Тепер, коли я замислююся над цим, ви можете замінити /\n/рядок шаблону на справжній новий рядок між ними. Це економить 1 байт, оскільки вам не доведеться писати послідовність.
Ісмаїл Мігель

3

Pyth, 15 14 13 байт

lftTcjd+.zC.z

Я використовую як сеператор і #як заповнення символів замість їх протилежного значення від ОП. Спробуйте в Інтернеті: Демонстрація

Замість #символу заповнення він приймає також букви. Таким чином, ви могли реально взяти розв’язану кросворд, і вона надрукувала б кількість слів. А якщо ви видалите lкоманду, вона навіть надрукує всі слова. Перевірте це: пазл 10 травня в неділю NY Times

Пояснення

        .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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.