Рубін, 272 байти
Дві непотрібні рядки додаються до коду з будь-якої сторони вкладеної функції gдля поліпшення читабельності. Вони виключені з балу. Символи, f=які присвоюють анонімну функцію змінній, також виключаються.
Формат виводу - це 0або 1за запитанням замість рідного 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}}
Вихідні дані
Після приблизно 50 дзвінків, як це:
f[4,['PPCG','CODE','GOLF','ANT','CAN','CUBE','WORD','WALK','SPELL']]
Нарешті я отримав наступний результат з 2 хітами. ANTзнаходиться внизу праворуч, піднімаючись вгору, і ANрозділяється з 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
Пояснення
Конкретне розгортання вибраного куба було обрано частково для його простоти малювання, але головним чином для його простоти пошуку.
Неабетичні символи (крапки плюс новий рядок в кінці кожного рядка) є важливою частиною поля, куди мураха можна знайти ходити.
Пошук виконується за допомогою рекурсивної функції g, яка вкладена у функцію f. Якщо слово, що передається, є порожнім рядком, пошук завершений і $rвстановлено значення 1. Якщо мурашка знаходиться на літерному квадраті, що відповідає першій букві слова, пошук продовжується у всіх чотирьох напрямках: функція викликається знову при цьому слово скорочено, видаливши його першу букву. У цьому випадку параметр напряму ігнорується. Переміщення відбувається за допомогою рекурсивного виклику з індексом комірки, зміненим значеннями в. x.В результаті додавання приймається модуль розміром сітки плюс додаткова половина рядка. Це означає, що нижня лінія обертається круглою до верхньої та навпаки, з правильним горизонтальним зміщенням.
Якщо мурашка знаходиться на не буквеному квадраті, вона повинна зигзагувати рухом сходів, поки не знайде буквеного квадрата. Вона буде зизагувати в південно-східному або північно-західному напрямку. Це моделюється рекурсивними дзвінками, dпараметр XORed з 1 кожного разу для відстеження її руху. До тих пір, поки вона не дістанеться до наступної літери, немає скорочення вхідного слова. Зручно, що це може бути зроблено за допомогою тієї ж рекурсії, яка використовується, коли ми шукаємо в районі букви. Різниця полягає в тому, що рекурсія має лише одну гілку, коли мураха знаходиться в області пробілів, на відміну від 4 у літерній області.
Коментований код
->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
}