Hitung kata-kata persimpangan

10

Pertimbangkan standar teka-teki silang 15x15 berikut.

Kotak teka-teki silang

Kita dapat mewakili ini dalam seni ASCII dengan menggunakan #untuk blok dan (spasi) untuk kotak putih.

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

     ##   #    
   #       #   
    #   ##     

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

Diberi kisi silang dalam format seni ASCII di atas, tentukan berapa banyak kata yang dipegangnya. (Kisi-kisi di atas memiliki 78 kata. Itu adalah teka-teki New York Times Senin lalu .)

Kata adalah sekelompok dua atau lebih ruang berturut-turut yang berjalan secara vertikal atau horizontal. Sebuah kata dimulai dan diakhiri dengan salah satu blok atau tepi kisi dan selalu berjalan dari atas ke bawah atau kiri ke kanan, tidak pernah diagonal atau mundur. Perhatikan bahwa kata-kata dapat menjangkau seluruh lebar puzzle, seperti pada baris keenam dari puzzle di atas. Sebuah kata tidak harus terhubung dengan kata lain.

Detail

  • Input akan selalu berupa kotak yang berisi karakter #atau (spasi), dengan baris yang dipisahkan oleh baris baru ( \n). Anda dapat mengasumsikan bahwa kisi tersebut terbuat dari 2 karakter ASCII yang dapat dicetak dan bukan #dan .
  • Anda dapat mengasumsikan ada baris tambahan opsional. Karakter spasi tambahan tidak dihitung, karena memengaruhi jumlah kata.
  • Grid tidak akan selalu simetris, dan mungkin semua spasi atau semua blok.
  • Program Anda secara teoritis harus dapat bekerja pada kisi-kisi ukuran apa pun, tetapi untuk tantangan ini tidak akan pernah lebih besar dari 21 × 21.
  • Anda dapat menggunakan kisi itu sendiri sebagai input atau nama file yang berisi kisi.
  • Ambil input dari stdin atau argumen baris perintah dan output ke stdout.
  • Jika Anda lebih suka, Anda dapat menggunakan fungsi bernama daripada program, mengambil grid sebagai argumen string dan menghasilkan integer atau string melalui stdout atau fungsi kembali.

Uji kasus

  1. Memasukkan:

        #
        #
        #
    

    Keluaran: 7(Ada empat ruang sebelum masing-masing #. Hasilnya akan sama jika setiap tanda nomor dihapus, tetapi Markdown menghapus spasi dari garis yang kosong.)

  2. Memasukkan:

    ##
     #
    ##
    

    Output: 0(Kata-kata satu huruf tidak masuk hitungan.)

  3. Memasukkan:

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

    Keluaran: 4

  4. Input: ( Teka-teki Minggu NY Times 10 Mei )

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

    Keluaran: 140

Mencetak gol

Kode terpendek dalam byte menang. Tiebreaker adalah posting tertua.

NinjaBearMonkey
sumber

Jawaban:

7

CJam, 18 17 13 11 byte

2 byte disimpan oleh Dennis.

Menggunakan spasi untuk sel terisi dan 1untuk sel kosong:

qN/_z+:~1-,

Uji di sini.

Penjelasan

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

Tergelincir , 18 + 3 = 21 byte

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

Jalankan dengan flag no(karenanya +3), dan gunakan spasi / Xbukan spasi / #. Mengganggu ini lebih panjang dari CJam / Pyth, tapi saya kira Slip tidak dirancang untuk menjadi golf tertentu ...

Cobalah online . Perhatikan bahwa contoh pertama adalah spasi yang hilang pada beberapa baris.

Penjelasan

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

The nflag membuat keluaran mencetak jumlah pertandingan, dan obendera memungkinkan tumpang tindih pertandingan mulai dari alun-alun yang sama. Alasan bolak-balik adalah karena Slip mencoba pertandingan mulai dari setiap kotak, dan kami ingin memastikan kami hanya mencocokkan satu baris penuh dan bukan sebagian. Slip hanya mengembalikan kecocokan unik, bahkan jika mereka memulai dari posisi yang berbeda.

Catatan: Awalnya saya punya >?( +(X|$^)<<){2}, dengan ruang pertama di bagian dalam. Ini akan melewatkan beberapa kasus dengan 2 kata spasi panjang di tepi, karena penunjuknya akan seperti ini:

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

[sp]    [sp]+$^    <<[sp]    [sp]+   (uh oh match fails)
Sp3000
sumber
Mengapa dua bendera itu tiga byte?
lirtosiast
@ThomasKwa Saya pikir kebijakan saat ini dengan bendera baris perintah adalah meta post ini , yang menghitung jumlah byte sebagai perbedaan dari permintaan kode yang biasa. Jadi di sini perbedaannya adalah antara py -3 slip.py regex.txt input.txtdan py -3 slip.py regex.txt input.txt no, yaitu tiga byte (termasuk spasi sebelumnya n)
Sp3000
Itu masuk akal. Saya memikirkannya dari sudut pandang entropi; terkadang saya lupa bahwa itu karakter yang kita hitung.
lirtosiast
4

Haskell, 81 byte

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

Menggunakan spasi sebagai karakter blok dan karakter lainnya (bukan spasi) sebagai sel kosong.

Cara kerjanya: membagi input menjadi daftar kata di spasi. Ambil a 1untuk setiap kata dengan sewa 2 karakter dan jumlah 1itu. Terapkan prosedur yang sama pada transposisi (pisah pada \n) dari input. Tambahkan kedua hasil.

nimi
sumber
4

JavaScript ( ES6 ) 87 121 147

Buat transposisi string input dan tambahkan ke input, lalu hitung string 2 ruang atau lebih.

Jalankan cuplikan di Firefox untuk menguji.

Kredit @IsmaelMiguel, solusi untuk ES5 (122 byte):

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
sumber
1
Bagaimana dengan 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]}? Panjangnya 113 byte. Regex Anda diganti dengan / +/(2 spasi), j=0ditambahkan dalam forloop 'parent' dan alih-alih menggunakan sintaks obj.length, saya mengubah untuk menggunakan L='length'; ... obj[L], yang diulang 3 kali.
Ismael Miguel
Saya mendapatkannya untuk bekerja di es6fiddle.net/iakdcpdh (bukannya F=z=>, saya harus menggunakan var F=(z,i,L,j,r)=>). Saya mengujinya di IE11 dan berhasil!
Ismael Miguel
@ IsmaelMiguel dilakukan dengan baik! dan paling cocok untuk ES5. Melihatnya lagi, saya menemukan sesuatu yang lebih ES6ish dan lebih pendek. Mungkin Anda bisa mempublikasikan solusi Anda untuk ES5.
edc65
Tidak, tidak apa-apa. Itu solusi Anda, saya baru saja menguranginya. Saya merasa tidak adil untuk menjawab seolah-olah itu milik saya.
Ismael Miguel
Sekarang saya berpikir tentang hal itu, Anda dapat mengganti /\n/dengan string template dengan baris baru yang nyata di antara. Itu menghemat 1 byte karena Anda tidak perlu menulis urutan melarikan diri.
Ismael Miguel
3

Pyth, 15 14 13 byte

lftTcjd+.zC.z

Saya menggunakan sebagai pemisah dan #mengisi karakter alih-alih makna yang berlawanan dari OP. Cobalah online: Peragaan

Alih-alih #sebagai karakter isi ini menerima juga surat. Jadi Anda benar-benar dapat mengambil teka-teki silang yang terselesaikan, dan itu akan mencetak jumlah kata. Dan jika Anda menghapus lperintah, itu bahkan mencetak semua kata. Uji di sini: Teka-teki Sunday NY Times 10 Mei

Penjelasan

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