Рубин, 272 байта
Два ненужных символа новой строки добавляются в код по обе стороны от вложенной функции g
для улучшения читабельности. Они исключены из оценки. Символы, f=
которые присваивают анонимную функцию переменной, также исключаются.
Выходной формат 0
или 1
на вопрос вместо родного true
и Ruby 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
}