Yakut, 272 bayt
g
Okunabilirliği artırmak için iç içe işlevin her iki tarafındaki koda iki gereksiz satır eklenir . Bunlar puanın dışında tutulur. f=
Bir değişkene anonim işlev atayan karakterler de hariç tutulur.
Çıktı biçimi, Ruby'nin yerel ve yerine soru başına 0
veya 1
sorudur . Boole ve kelimeyi ayırmak için satır başı yerine satırsonu kullanılır. Anladığım kadarıyla, bunun çıktı gereksinimlerinin kabul edilebilir bir yorumu olduğu, ancak değilse, bayt sayısı üzerindeki etkinin küçük olacağı yönündedir.true
false
f=->n,l{c=''
x=[p=6*n,1,-p,-1]
(m=3*p*n).times{|i|c<<(5+i/n%6-i/n/p&6==6?65+rand(26):i%p==p-1?10:46)}
q=m+3*n
puts c
g=->w,i,d{w==''?$r=1:c[i]<?A?g[w,(i+x[d])%q,d^1]:w[0]==c[i]&&4.times{|j|g[w[1..-1],(i+x[j])%q,j^1]}}
l.each{|w|$r=0
m.times{|i|c[i]>?@&&g[w,i,0]}
puts $r,w}}
Çıktı
Bunun gibi yaklaşık 50 çağrıdan sonra:
f[4,['PPCG','CODE','GOLF','ANT','CAN','CUBE','WORD','WALK','SPELL']]
Sonunda 2 hit ile aşağıdaki çıktı aldım. ANT
sağ altta yukarı doğru gider ve sarma yuvarlak sola üst solda ile AN
paylaşılır .CAN
C
....KCAAXRHT...........
....ALRZXRKL...........
....NDDLCMCT...........
....ETQZHXQF...........
........FYYUSRZX.......
........CFNPAUVX.......
........ZTJVHZVQ.......
........AUWKGVMC.......
............XWKSDWVZ...
............DPLUVTZF...
............DMFJINRJ...
............ZRXJIAFT...
0
PPCG
0
CODE
0
GOLF
1
ANT
1
CAN
0
CUBE
0
WORD
0
WALK
0
SPELL
açıklama
Seçilen küpün belirli bir şekilde açılması, kısmen çizim kolaylığı için, ancak esas olarak arama kolaylığı için seçildi.
Alfabe dışı karakterler (noktalar ve her satırın sonundaki yeni satır), karıncanın yürürken bulunabileceği alanın önemli bir parçasıdır.
Arama, işlevde g
yuvalanmış özyinelemeli işlev tarafından gerçekleştirilir f
. Geçilen kelime boş bir dizeyse arama tamamlanır ve 1 $r
olarak ayarlanır. Karınca kelimenin ilk harfine karşılık gelen bir harf karesinde ise, arama dört yönde de devam eder: işlev tekrar çağrılır kelimesi ilk harfini kaldırarak kısaltılmıştır. Bu durumda, yön parametresi dikkate alınmaz. Hareket, değerlerle değiştirilen hücre indeksi ile tekrar tekrar çağrılarak yapılır x.
. Eklemenin sonucu, modulo ızgarasının büyüklüğü artı ekstra bir yarım çizgi alınır. Bu, alt çizginin yukarı doğru ve tam tersi şekilde doğru yatay ofset ile sarıldığı anlamına gelir.
Eğer karınca mektup olmayan bir karede ise, bir mektup karesi bulana kadar merdiven hareketiyle zikzak yapması gerekir. Güneydoğu veya kuzeybatı yönünde zizag yapacak. Bu, d
hareketini takip etmek için parametre her seferinde 1 ile XORed olacak şekilde yinelemeli çağrılarla simüle edilir . Bir sonraki harf karesine ulaşıncaya kadar, giriş kelimesinde kısalma olmaz. Uygun bir şekilde, bu, bölgede harflerle arama yaparken kullanılanla aynı özyineleme ile yapılabilir. Fark, özyineleme, karınca boşluk alanındayken, mektup alanında 4'ün aksine, sadece bir dala sahiptir.
Yorumlanan kod
->n,l{ #n=square size, l=list of words to search
c='' #empty grid
x=[p=6*n,1,-p,-1] #offsets for south, east, north, west. p is also number of characters per line
(m=3*p*n).times{|i| #m=total cells in grid. for each cell
c<<(5+i/n%6-i/n/p&6==6? #apppend to c (according to the formula)
65+rand(26): #either a random letter
i%p==p-1?10:46) #or a "whitespace character" (newline, ASCII 10 or period, ASCII 46)
}
q=m+3*n #offset for vertical wraparound = grid size plus half a row.
puts c #print grid
g=->w,i,d{ #search function. w=word to search for, i=start index in grid, d=direction
w==''? #if length zero, already found,
$r=1: #so set flag to 1. Else
c[i]<?A? #if grid cell is not a letter
g[w,(i+x[d])%q,d^1]: #recursively call from the cell in front, with the direction reflected in NW-SE axis
w[0]==c[i]&& #else if the letter on the grid cell matches the start of the word
4.times{|j| #for each direction (iterate 4 times, each time a different direction is "in front")
g[w[1..-1],(i+x[j])%q,j^1]} #recursively call from the cell in front. Chop first letter off word.
} #Direction parameter is XORed (reflected in NW-SE axis) in case ant hits whitespace and has to zigzag.
l.each{|w| #for each word in the list
$r=0 #set global variable $r to zero to act as a flag
m.times{|i|c[i]>?@&&g[w,i,0]} #call g from all cells in the grid that contain a letter
puts $r,w} #output flag value and word
}