Kelime Arama Yapboz


29

Kelime arama bulmacası ve arama dizesi olarak dikdörtgen bir metin verildiğinde, metnin arama dizesini içerip içermediğini belirleyin. Arama dizgisi görünebilir:

  • yatay, dikey veya çapraz olarak
  • ileri veya geri

Bir fonksiyon veya program yazabilir ve ARGV veya STDIN fonksiyon argümanı üzerinden giriş olarak iki karakter atabilirsiniz. Çıktı bir truthy veya sahte olmalı sonuç olmalıdır.

Metnin isteğe bağlı yazdırılabilir ASCII karakterleri (onaltılık kodlar 20 ila 7E) ve satır sonu karakterleri içereceğini varsayalım. Harfler büyük / küçük harfe duyarlıdır. Giriş metninin dikdörtgen olduğunu, yani tüm satırların aynı uzunlukta olduğunu varsayabilirsiniz. Girişin sondaki bir yeni satırla bitip bitmeyeceğini (gönderiminiz için önemliyse) yapabilirsiniz.

Bu kod golf, en kısa cevap (bayt cinsinden) kazanır.

Örnekler

Vikipedi'nin kelime aramadaki makalesinden bu kılavuzu ilk girdi olarak kullanmak:

WVERTICALL
ROOAFFLSAB
ACRILIATOA
NDODKONWDC
DRKESOODDK
OEEPZEGLIW
MSIIHOAERA
ALRKRRIRER
KODIDEDRCD
HELWSLEUTH

Aşağıdaki arama dizeleri sırasıyla sıra dışı veya sahte sonuçlar vermelidir:

Truthy: RANDOM, VERTICAL, HORIZONTAL, WORDSEARCH, WIKIPEDIA, TAIL
Falsy:  WordSearch, CODEGOLF, UNICORN

Alternatif olarak, bu giriş metnini kullanma

Lorem ipsum dolor sit amet consectetu
r adipisicing elit sed do eiusmod tem
por incididunt ut labore et dolore ma
gna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco lab
oris nisi ut aliquip ex ea commodo co
nsequat. Duis aute irure dolor in rep
rehenderit in voluptate velit esse ci
llum dolore eu fugiat nulla pariatur.

Aşağıdaki arama sonuçlarını alıyoruz (şimdi alıntıları kullanarak, çünkü bazı arama dizelerinde boşluklar var):

Truthy: "Lorem", "mine", "uma bop", "tuetdod", "snol,a", "texas", "pii.d  v", "vexta"
Falsy:  "lorem", "wordsearch", "pii.d v", "mute"

Yanıtlar:


7

CJam, 46 37 bayt

qN%{_zW%__,N**2$2$+,)/z\}4*]:+N*eas#)

Izgarayı STDIN'den ve kelimeyi komut satırı argümanı olarak okur. Eşleşmeler için pozitif, eşleşmeyenler için 0 olarak yazdırır.

İki ekstra bayt pahasına, her iki dize de (word, linefeed, grid) STDIN'den okunabilir:

qN%(\{_zW%__,N**2$2$+,)/z\}4*](\:+N*\#)

Bu sürümü CJam tercümanı ile çevrimiçi olarak deneyebilirsiniz .

Örnek çalışma

$ for W in Lorem mine uma\ bop tuetdod snol,a texas pii.d\ \ v vexta WordSearch CODEGOLF UNICORN; do echo -e "$(cjam wordsearch.cjam "$W" < grid)\t$W"; done
1       Lorem
3085    mine
2055    uma bop
5142    tuetdod
3878    snol,a
1426    texas
5371    pii.d  v
2536    vexta
0       WordSearch
0       CODEGOLF
0       UNICORN

Arka fon

Girişin aşağıdaki ızgara olduğunu varsayalım:

ABCD
EFGH
IJKL

Satır beslemelerinde bölerek şu diziyi elde ederiz:

A := [
         "ABCD"
         "EFGH"
         "IJKL"
     ]

Bu Doğu kelimelerini kapsar (soldan sağa giden kelimeler).

Şimdi, ayırıcı olarak Abir dizi len(A)satır besleme kullanma öğelerine katılıyoruz :

"ABCD⏎⏎⏎EFGH⏎⏎⏎IJKL"

Ardından, sonuçta elde edilen dizgiyi uzunluk bölümlerinde keseriz len(A) + len(A[0]) + 1:

[
    "ABCD⏎⏎⏎E"
    "FGH⏎⏎⏎IJ"
    "KL"
]

Diziyi "zip" edersek (devrik satırları ve sütunları), şunları elde ederiz:

[
    "AFK"
    "BGL"
    "CH"
    "D⏎"
    "⏎⏎"
    "⏎⏎"
    "I⏎"
    "EJ"
]

Bu Güney Doğu kelimelerini kapsar.

A'yı sıkıştırıp sonucun satırlarının sırasını tersine çevirirsek, şunları elde ederiz:

[
    "DHL"
    "CGK"
    "BFJ"
    "AEI"
]

Bu Güney'i kapsar ve - köşegenlerin işlemlerini tekrarladıktan sonra - Güney Batı sözleri.

Tekrar sıkıştırma ve geri alma işlemlerini elde ediyoruz:

[
    "LKJI"
    "HGFE"
    "DCBA"
]

Bu, Batı'yı ve - köşegenlerin işlemlerini tekrar ettikten sonra - Kuzey Batı sözlerini kapsar.

Bir kez daha sıkıştırıp geri alırsak aşağıdakileri elde ederiz:

[
    "IEA"
    "JFB"
    "KGC"
    "LHD"
]

Bu Kuzey'i kapsar ve - köşegenlerin işlemlerini tekrarladıktan sonra - Kuzey Doğu kelimeleri.

Nasıl çalışır

Kod, önceki bölümde açıklandığı gibi iki küçük farkla yapılır:

  • En baştan bir kez sıkıştırır ve tersine çevirir.
  • len(A) + len(A[0])Olarak hesaplar len(A + zip(A)).

Son olarak, ayırıcı olarak satır besleyicileri kullanarak oluşturulan tüm dizilerin tüm satırlarını birleştirir ve elde edilen dizgede sözcüğü arar.

qN%                                   " A := split(input(),'\n')                          ";
   {                    }4*           " Do 4 times:                                       ";
    _zW%                              "   B := reverse(zip(A))                            ";
        __,N**                        "   C := B.join(len(B) * '\n')                      ";
              2$2$+,)/z               "   D := zip(C.chunks(len(A + B) + 1))              ";
                       \              "   A := B                                          ";
                           ]          " Collect all values of A and D in an array R.      ";
                            :+        " R := flatten(R)                                   ";
                              N*      " R := R.join('\n')                                 ";
                                eas   " I := flatten(ARGV)                                ";
                                   #) " print R.index(I) + 1                              ";

7

Java: 183 211 321

boolean s(char[]w,char[]s){int j,z,a=s.length,i=a*9,f=1,q=0;for(;s[q++]>10;);for(;i-->0;)for(j=w.length,z=i/9;i%9!=4&j-->0&z>=0&z<a&&s[z]==w[j];z+=q*(i/3%3)+i%3-q-1)f*=j;return f==0;}

Temel bir kaba kuvvet. Söyleyecek fazla bir şey yok sanırım. Giriş ilk önce iğne ve ikinci samanlıkta. Kılavuzun yeni satır sonlandırılmış olduğunu varsayar .

Gösterilen test durumuyla birlikte biraz daha okunabilir bir sürüm:

public class WordSearch {
    static String grid = "WVERTICALL\nROOAFFLSAB\nACRILIATOA\nNDODKONWDC\nDRKESOODDK\nOEEPZEGLIW\nMSIIHOAERA\nALRKRRIRER\nKODIDEDRCD\nHELWSLEUTH";
    static String search = "RANDOM";

    public static void main(String[] args) {
        System.out.println(new WordSearch().s(search.toCharArray(),grid.toCharArray()));
    }

    boolean s(char[]w,char[]s){
        int j,z,a=s.length,i=a*9,f=1,q=0;
        for(;s[q++]>10;);
        for(;i-->0;)
            for(j=w.length,z=i/9;
                i%9!=4&j-->0&z>=0&z<a&&s[z]==w[j];
                z+=q*(i/3%3)+i%3-q-1)
                f*=j;
        return f==0;
    }
}

if(e<1)return 1>0;olabilir return e<1;mi?
FryAmTheEggman

@FryAmTheEggman Hayır, ilk başarısızlığı bulduktan sonra geri dönecek, böylece tüm ızgarayı aramayacaktı.
Geobits

1
Ah üzgünüm, orada biraz kayboldu; _;
FryAmTheEggman

4
Yapacağın yerine nedenle döngüleri için ikiye dışarı birine kısaltılmış olabilir i=a*9,ve for(;i-->0;)daha sonra ve z=i/9;ve i%a!=4&ve bu yüzden?
Will

1
Vay, bu benimkine çok benziyor. Ve ben sadece çoktan başladıktan sonra baktım. Nasıl çalıştığını görmek için zaman almadım. +1.
Seviye Nehri St

6

JavaScript (E6) 111 116

Her yönde her karakter için kaba kuvvet arama - olabildiğince golf

F=(b,w)=>
  [1,-1,r=b.search('\n'),-r,++r,-r,++r,-r].some(d=>
    [...b].some((_,p)=>
      [...w].every(c=>c==b[p+=d],p-=d)
    )
  )

FireFox / Firebug konsolunda test edin

;["RANDOM", "VERTICAL", "HORIZONTAL", "WORDSEARCH", "WIKIPEDIA", "TAIL",
"WordSearch", "CODEGOLF", "UNICORN"]
.forEach(w=>console.log('\n'+ w +' -> '+
  F("WVERTICALL\nROOAFFLSAB\nACRILIATOA\nNDODKONWDC\nDRKESOODDK\nOEEPZEGLIW\nMSIIHOAERA\nALRKRRIRER\nKODIDEDRCD\nHELWSLEUTH",w)))

Çıktı

RANDOM -> true
VERTICAL -> true
HORIZONTAL -> true
WORDSEARCH -> true
WIKIPEDIA -> true
TAIL -> true
WordSearch -> false
CODEGOLF -> false
UNICORN -> false

5

Python, 175

Çok ilham almadım, ama işte:

def s(h,n):
 l=h.find('\n')+2;h+='\n'*l;L=i=len(h)
 while i>0:
  i-=1
  for d in[-l,1-l,2-l,-1,1,l-2,l-1,l]:
    j=i;m=len(n)
    for c in n:m-=c==h[j%L];j+=d
    if m<1:i=-1
 return-i

İlk argüman samanlık, ikincisi iğnedir.


Bence h,n=input()ve kullanarak 6 karakter kaydedebilirsiniz print. Ayrıca, bu kare olmayan girdilerle çalışıyor mu? (m = len (n)? Ne yaptığınızı tam olarak anlamadığınızı itiraf ediyorum, bu yüzden tamamen yanlış olabilirim!)
FryAmTheEggman 18:14

@FryAmTheEggman: Evet, kare olmayan girdilerle çalışır.
Ell

1
Bazı standart Python optimizasyonları: while i>0için while i:(çünkü i, negatif hale gelemez) if m<1:i=-1için i-=m<1.
xnor

1
@xnor sana yanlış okumuş olabilir düşünüyorum if m<1:i=-1olarak if m<1:i-=1o ayarlıyor çünkü Bunların hiçbiri çalışacaktır olarak inegatif olmak.
FryAmTheEggman

@FryAmTheEggman Oh, evet, bunu tamamen yanlış yaptım.
xnor

5

Bash + coreutils, 214 169 bayt

r()(tee >(rev) $@)
t()(eval paste -d'"\0"' `sed 's/.*/<(fold -1<<<"&")/'`)
d()(while IFS= read l;do echo "$a$l";a+=_;done|t)
r<<<"$2"|r >(d) >(r|t) >(r|d)|r|grep -q "$1"

Kullanım 3 fonksiyonu dönüşümü r, tve dgerekli olan tüm kombinasyonlarda, devrik ve çapraz kayma ters.

Güncelleme - rfonksiyon şimdi ekstra golf için ters ve ters çıktı üretiyor

Komut satırı argümanları üzerinden giriş - arama dizesi, ardından (yeni satır ayrılmış) dikdörtgen kelime arama bloğu.

Çıktı deyimsel olarak doğru bir kabuk çıkış durum kodudur - 0, DOĞRU, 1 ise YANLIŞ anlamına gelir.

Çıktı:

$ for w in "Lorem" "mine" "uma bop" "tuetdod" "snol,a" "texas" "pii.d  v" "vexta" ; do ./ws.sh "$w" "Lorem ipsum dolor sit amet consectetu
r adipisicing elit sed do eiusmod tem
por incididunt ut labore et dolore ma
gna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco lab
oris nisi ut aliquip ex ea commodo co
nsequat. Duis aute irure dolor in rep
rehenderit in voluptate velit esse ci
llum dolore eu fugiat nulla pariatur."; echo $?; done
0
0
0
0
0
0
0
0
$ for w in WordSearch CODEGOLF UNICORN ; do ./ws.sh "$w" "Lorem ipsum dolor sit amet consectetu
r adipisicing elit sed do eiusmod tem
por incididunt ut labore et dolore ma
gna aliqua. Ut enim ad minim veniam, 
quis nostrud exercitation ullamco lab
oris nisi ut aliquip ex ea commodo co
nsequat. Duis aute irure dolor in rep
rehenderit in voluptate velit esse ci
llum dolore eu fugiat nulla pariatur."; echo $?; done
1
1
1
$ 

1. Önermek üzereydim T()(tee >(r) $@), ama bu daha da iyi. 2. Bu fonksiyon sözdizimini daha önce gördüğümü sanmıyorum. 3. Boş olmayan dizgilerin truthy ve boş dizgelerin sahte olması düşünüldüğünde, ihmal edebileceğinizi düşünüyorum -q.
Dennis,

Tanımlarsanız r()(tee >(rev) $@), r<<<"$2"|r >(d) >(r|t) >(r|d)|r|grep "$1"aynı zamanda çalışması gerekir.
Dennis,

Başka bir şey test etmedim, ancak söz konusu iki test olayı denediğimde kontrol etti.
Dennis,

@Dennis Güzel - evet şimdi çalışıyor. Martin ile kontrol ettim - o kalmak istiyor -q.
Dijital Travma

5

Cı, 163

f(char*h,char*n){int i,j,d,p,y=0,l=strlen(h),w=strchr(h,10)-h+1;for(i=l*9;i--;y+=d&&!n[j]){p=i/9;d=i%9/3*w-w+i%3-1;for(j=0;p>=0&p<l&h[p]==n[j];j++)p+=d;}return y;}

Şebekenin yeniden düzenlenmesi yok, her başlangıç ​​harfini her yöne doğru deniyorum ve ızgaradan çıkana veya bir uyuşmazlık bulana kadar yürüyorum.

Bir C dizesinin sıfır baytta sonlandırılması olgusundan faydalanırım. Izgarada sıfır bayt olmadığı için HER ZAMAN uyuşmazlık olacak. Fakat uyumsuzluk sıfır baytta meydana gelirse, aranacak dizgenin sonunu bulduğumuzu biliyoruz ve onu bir eşleşme olarak kaydediyoruz.

Bir test programında Ungolfed

char h[]="WVERTICALL\nROOAFFLSAB\nACRILIATOA\nNDODKONWDC\nDRKESOODDK\nOEEPZEGLIW\nMSIIHOAERA\nALRKRRIRER\nKODIDEDRCD\nHELWSLEUTH\n";

f(char*h,char*n){                                   //haystack,needle
  int i,j,d,p,y=0,l=strlen(h),w=strchr(h,10)-h+1;   //l=length of whole grid. w=width of row, including terminal newline ASCII 10
  for(i=l*9;i--;){                                  //for each start letter and direction
    p=i/9;                                          //pointer to start letter
    d=i%9/3*w-w+i%3-1;                              //9 possible values of direction vector {-w,0,w}+{-1,0,1}
    for(j=0;p>=0&p<l&h[p]==n[j];j++)p+=d;           //walk p in the direction defined by d until we walk off the top or bottom of the grid or a mismatch is fount
    y+=d&&!n[j];                                    //if we got all the way to the terminal 0, record it as a hit. If d=0, don't record as this is an invalid direction.
  }
  return y;   
}

main(int c, char**v){
  printf("%d",f(h,v[1]));  
}

Çıktı

İşlevin, ızgarada aranan dizenin toplam olay sayısını döndüreceğini unutmayın. Böylece OD6 döndürür. Hiçbir olay bulunmazsa, C'deki tek sahte değer olan 0 değerini döndürür. Değişiklik yapmak y|=d*!n[j], bir karakterin kaydedilmesini sağlar, ancak bu işlevi kaybeder.

$ ./a UNICORN
0

$ ./a CODEGOLF
0

$ ./a WordSearch
0

$ ./a RANDOM
1

$ ./a WORDSEARCH
1

$ ./a VERTICAL
1

$ ./a HORIZONTAL
1

$ ./a WIKIPEDIA
1

$ ./a TAIL
1

$ ./a OD
6

5

C # - 218 197 186 bayt

2 dizge alan C # işlevi, aranacak ilk sözcük, daha sonra satırlı kılavuz \nsatırlar arasında feed ( ). Artık işler çaresizleşiyor ... o kadar çaresiz ki önceki düzenlemem işe yaramadı!

Golf kodu:

bool F(string D,string S){int l=S.Length,i=l*13,r,p;for(S+="\n";i-->l*5;i=r<0?r:i)for(r=D.Length,p=i%l;p>-1&p<l&r-->0&&D[r]==S[p];p+=(S.IndexOf('\n')+1)*(i/l%9/3-1)+i/l%3-1);return i<0;}

Test kodu ile daha az golf oynadı:

class P
{
    static void Main()
    {
        System.Console.WriteLine(new P().F(System.Console.ReadLine(),System.Console.In.ReadToEnd())?"Truthy":"Falsy"); // because why not
    }

    bool F(string D,string S)
    {
        int l=S.Length,i=l*13,r,p;

        for(S+="\n";i-->l*5;i=r<0?r:i) // for each cell/direction
            for(r=D.Length,p=i%l;p>-1&p<l&r-->0&&D[r]==S[p];p+=(S.IndexOf('\n')+1)*(i/l%9/3-1)+i/l%3-1); // test against string (backwards)

        return i<0;
    }
}

4

Haskell - 173

Doğrudan ızgara üzerinde arama yapmak yerine, ızgarayı farklı şekillerde dönüştürürüm ve kelimeyi yeni kılavuzun her bir satırıyla eşleştiririm.

Örneğin,

G1    G2    G3       G4   G5

abcd  aA1   abcd     a..  ..1
ABCD  bB2   .ABCD    bA.  .A2
1234  cC3   ..1234   cB1  aB3
      dD4            dC2  bC4
                      D3  cD
                       4  d

Her bir G1, G2, G4 ve G5 satırındaki kelimeyi arayın, sonra işlem tamam. G3 kullanılmadığına dikkat edin, sadece örnek için buraya gönderdim.

Benzer bir fikir ileri ve geri arama için uygulanır: sadece orijinal kelime ve ters kelime arama.

Şimdi 8 yön araştırdık. İşte doğruluğu başka bir betik tarafından doğrulanan kod .

import Data.List
v=reverse
t=transpose
y=any
d r=zipWith(++)(scanr(\_->('\n':))[]r)r
g r w=y(y$y((==w).take(length w)).tails)[r,t r,t.d$r,t.d.v$r]
f r w=y(g(lines r))[w,v w]

Fonksiyon fne istediğimizdir ve argümanı rdikdörtgen dizesidir, aranacak wkelimedir.


4

Python 2 - 246 259 275 308 298 297 294 313 322

w,s=input()
r=range
d='\n'
I=''.join
w=w.split(d)
t,u=len(w),len(w[0])
v=d.join([I(x)for x in zip(*w)]+[d]+[I([w[i+j][i]for i in r(min(u,t-j))])+d+I([w[i][i+j]for i in r(min(t,u-j))])for j in r(max(t,u))]+[d]+w)
print s in v or s[::-1]in v

Will'in baskı ve başa çıkma konusunda yardımları için teşekkürler.

Bana golf alanlarını doğru şekilde hatırlattığım için yeraltı demiryolu sayesinde;

Sınırlayıcı olarak ',' kullanımı nedeniyle hatalı eşleşmeler için düzeltildi.

Anlaşılan golf oynamak için en iyi yol, tonlarca yatay kaydırma eklemektir.

Beyaz boşluk olarak gir patlama satırsonu tırnak içinde çizgiler ayrılmış: "WVERTICALL \ nROOAFFLSAB \ nACRILIATOA \ nNDODKONWDC \ nDRKESOODDK \ nOEEPZEGLIW \ nMSIIHOAERA \ nALRKRRIRER \ nKODIDEDRCD \ nHELWSLEUTH", "RANDOM"


1
L=len;J=''.joinvb ve print any(s in(v,d,w,r...))? Ben seni ilan ederken gördüm aynı çizgide gidiyordum :)
Will

@ Will Yardımınız için teşekkürler! Len maliyetlerini kaydettiği kadar karakter tanımlamak ve en iyi bir şekilde nasıl birleştirme yapılacağından emin değilim (bazıları virgüllere sahiptir), bu yüzden onu biraz yapacağım.
FryAmTheEggman

Sahip olduğunuz )veya ]takip ettiğiniz herhangi bir yerde , bu alanı kaldırabilirsiniz.
undergroundmonorail

2

APL (Dyalog Klasik) , 44 bayt

1∊⍞⍷↑{⍉0,⍵,↑(0,⊢)\↓0,⍵}¨{⍉⌽⍵}\4⍴⊂↑a⊆⍨a≠⊃⌽a←⎕

Çevrimiçi deneyin!


Üzgünüm, ama burada böyle bir giriş yapamazsınız , ayrıştırılması gerekiyor \n(yani, ⎕TC[2]ayırıcı olarak sahip olmanız gerekiyor ).
Outgolfer Erik,

@EriktheOutgolfer oh bok ... Daha sonra tamir edeceğim. Teşekkürler.
ngn

şimdi düzeltildi, ne yazık ki çok daha uzun
ngn

0

J , 60 53 bayt

<@[e.[:,[:(;|.)@>[:<\\.@>[:(<"1,</.)@>@(;|.@|:)[;.2@]

Çevrimiçi deneyin!

Yeni satır içermeyen ilk giriş gerektirir.

Açıklama:

linkrotate=: ;|.@|:     NB. link with itself rotated 90° ccw
infixes   =: <\\.       NB. list of boxes containing the infixes
lines     =: <"1 , </.  NB. horizontal and diagonal lines, boxed
linkrev   =: ;|.        NB. link with itself reversed
appearin  =: <@[ e. [: , [: linkrev@> [: infixes@> [: lines@>@linkrotate [;.2@]

Çevrimiçi deneyin!

Kancalar faydalıdır.


Bu da işe yarıyor gibi görünüyor . (51 bayt)
user202729

0

Jöle , 16 bayt

Kodun çekirdeği olarak bu 16 bayttan 15'iyle ilgili (muhtemelen yinelenen) bir sorun çözüldü ...

ỴZU$3С;ŒD$€Ẏw€Ẹ

Soldaki bir karakter listesini ve sağdaki 1 ise ve eğer değilse 0 döndüren bir karakter listesini kabul eden ikili bir bağlantı.

Çevrimiçi deneyin!

Nasıl?

ZU$3С;ŒD$€Ẏw€Ẹ - Link: words, grid
   3С          - repeat three times and collect the results (inc input):
  $             -   last two links as a monad:
Z               -     transpose
 U              -     upend     (together these rotate by a quarter)
          €     - for €ach:
         $      -   last two links as a monad:
       ŒD       -     get forward-diagonals
      ;         -     concatenate
           Ẏ    - tighten (to get all the runs across the grid) 
             €  - for €ach run:
            w   -   sublist-index (0 if not found)
              Ẹ - any truthy? (i.e. was the word found?)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.