Rubino, 272 byte
Due righe inutili vengono aggiunte al codice ai lati della funzione nidificata gper migliorare la leggibilità. Questi sono esclusi dal punteggio. f=Sono esclusi anche i caratteri che assegnano la funzione anonima a una variabile.
Il formato di output è 0o in 1base alla domanda anziché al nativo di Ruby truee false. Una nuova riga (anziché uno spazio) viene utilizzata per separare il booleano e la parola. La mia comprensione è che questa è un'interpretazione accettabile dei requisiti di output, ma in caso contrario, l'impatto sul conteggio dei byte sarebbe minore.
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}}
Produzione
Dopo circa 50 chiamate in questo modo:
f[4,['PPCG','CODE','GOLF','ANT','CAN','CUBE','WORD','WALK','SPELL']]
Alla fine ho ottenuto il seguente output con 2 hit. ANTè in basso a destra andando verso l'alto, e ANè condiviso da CAN, con il Cgiro avvolgente in alto a sinistra.
....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
Spiegazione
Il particolare sviluppo del cubo selezionato, è stato scelto in parte per la sua facilità di disegno, ma principalmente per la sua facilità di ricerca.
I caratteri non alfabetici (i punti più la nuova riga alla fine di ogni riga) sono una parte importante del campo in cui si trova la formica che cammina.
La ricerca viene eseguita dalla funzione ricorsiva g, che è nidificata nella funzione f. Se la parola passata è una stringa vuota la ricerca è completa ed $rè impostata su 1. Se la formica si trova su un quadrato di lettere che corrisponde alla prima lettera della parola, la ricerca continua in tutte e quattro le direzioni: la funzione viene richiamata di nuovo con la parola abbreviata rimuovendo la sua prima lettera. In questo caso il parametro direction è ignorato. Lo spostamento viene effettuato chiamando ricorsivamente con l'indice della cella modificato dai valori in x.Il risultato dell'aggiunta viene preso come modulo della dimensione della griglia più una mezza linea aggiuntiva. Ciò significa che la linea di fondo si avvolge verso l'alto e viceversa, con l'offset orizzontale corretto.
Se la formica si trova su un quadrato senza lettere, deve zigzagare con un movimento di scala finché non trova un quadrato di lettere. Zizag andrà in direzione sud-est o nord-ovest. Questo è simulato da chiamate ricorsive con il dparametro XORed con 1 ogni volta per tenere traccia del suo movimento. Fino a quando non raggiunge la lettera successiva, non c'è accorciamento della parola di input. Convenientemente, questo può essere fatto con la stessa ricorsione usata quando stiamo cercando nell'area con le lettere. La differenza è che la ricorsione ha un solo ramo quando la formica si trova nell'area degli spazi bianchi, invece di 4 nell'area delle lettere.
Codice commentato
->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
}