#Ruby, 272 bytes#
Ruby, 272 bytes
#Ruby, 272 bytes#
Ruby, 272 bytes
f[4,['PPCG','CODE','GOLF','ANT','CAN','CUBE','WORD','WALK','SPELL']]
If the ant is on a non-letter square, she must zigzag in a staircase motion until she finds a letter square. She will zizag in southeast or northwest direction. This is simulated by recursive calls with the d parameter being XORed with 1 each time to keep track of her movement. Until she reaches the next letter square, there is no shortening of the input word. Conveniently, this may be done by the same recursion as is used when we are searching in the area with letters. The difference is, the recursion has only one branch when the ant is in the whitespace area, as opposed to 4 in the letter area.
Commented code
->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
}
If the ant is on a non-letter square, she must zigzag in a staircase motion until she finds a letter square. She will zizag in southeast or northwest direction. This is simulated by recursive calls with the d parameter being XORed with 1 each time to keep track of her movement. Until she reaches the next letter square, there is no shortening of the input word. Conveniently, this may be done by the same recursion as is used when we are searching in the area with letters. The difference is, the recursion has only one branch when the ant is in the whitespace area, as opposed to 4 in the letter area.
f[4,['PPCG','CODE','GOLF','ANT','CAN','CUBE','WORD','WALK','SPELL']]
If the ant is on a non-letter square, she must zigzag in a staircase motion until she finds a letter square. She will zizag in southeast or northwest direction. This is simulated by recursive calls with the d parameter being XORed with 1 each time to keep track of her movement. Until she reaches the next letter square, there is no shortening of the input word. Conveniently, this may be done by the same recursion as is used when we are searching in the area with letters. The difference is, the recursion has only one branch when the ant is in the whitespace area, as opposed to 4 in the letter area.
Commented code
->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
}
#Ruby, 370 bytes ungolfed#272 bytes#
Here'sTwo unnecessary newlines are added to the complete ungolfed program with some brief commentscode either side of nested function (score excludes comments, some whitespace, andg to improve readability. These are excluded from the 5-byte function call atscore. The characters f= which assign the bottomanonymous function to a variable are also excluded.)
Output format is 0 or 1 per the valuequestion instead of ́n ́Ruby's native true and false. A newline (rather than a space) is passedused to separate the function as a parameter, but I've taken a liberty withboolean and the word input: these are passed from stdin in an infinite loop. ThisMy understanding is more practical for testingthat this is an acceptable interpretation of the output requirements, as you need to know whatbut if not, the grid looks like before you pick your test words. I'll fix this when I golfimpact on the byte count would be minor.
f=->n,l{c='' #empty grid
x=[p=6*n,1,-p,-1] #offsets for South, East, North, West
#compose and draw grid
(m=18*n*nm=3*p*n).times{|i|c<<((3+i5+i/n%6-i/n/p)/2==2p&6==6?(65+rand(26)):(i+1)%p==0i%p==p-1?10:46)}
q=m+3*n
puts c
#search function (word, index in grid of last letter, direction)
g=->w,i,d{w==''?($r=1):c[i]<'A'c[i]<?A?g[w,(i+x[d])%(m+3*n)%q,d^1]:
(w[-1]==c[i]&&4w[0]==c[i]&&4.times{|j|g[w[0|j|g[w[1..-2]1],(i+x[j])%(m+3*n)%q,j^1]})
}
#loop infinitely, set global variable $r to zero and perform search starting at each letter-containing cell of the grid. If found, $r is set to 1l.
loopeach{
w=gets.chomp
$r=0|w|$r=0
m.times{|i|c[i]>'@'&&g[w|i|c[i]>?@&&g[w,i,0]}
puts $r,w}}
f[4]
Typical grid output, N=4Output
After about 50 calls like this:
I finally got the following output with 2 hits. ANT is at the bottom right going upwards, and the AN is shared by CAN, with the C wrapping round to top left.
....RGPQMXHOKCAAXRHT...........
....NDVIEPVBALRZXRKL...........
....CUJTTWRENDDLCMCT...........
....YTLUKBDIETQZHXQF...........
........KKRNVQOQFYYUSRZX.......
........QBITMZFDCFNPAUVX.......
........GYMKCIPRZTJVHZVQ.......
........TPTLBYFVAUWKGVMC.......
............TRMZBMRSXWKSDWVZ...
............XQMHPMPSDPLUVTZF...
............LBFFERCSDMFJINRJ...
............TCESTMESZRXJIAFT...
0
PPCG
0
CODE
0
GOLF
1
ANT
1
CAN
0
CUBE
0
WORD
0
WALK
0
SPELL
Searching is performed by the recursive function ́g ́g, which is nested in function ́f ́f. If the word passed is an empty string the search is complete and $r is set to 1. If the ant is on a letter square which corresponds to the lastfirst letter of the word, the search is continued in all four directions: the function is called again with the word shortened by removing its lastfirst letter. In this case the direction parameter is ignored. The moving is done by recursively calling with the cell index altered by the values in x. The result of the addition is taken modulo the size of the grid plus an extra half line. This means that the bottom line wraps round to the top and vice versa, with the correct horizontal offset.
#Ruby, 370 bytes ungolfed#
Here's the complete ungolfed program with some brief comments (score excludes comments, some whitespace, and the 5-byte function call at the bottom.) the value of ́n ́ is passed to the function as a parameter, but I've taken a liberty with the word input: these are passed from stdin in an infinite loop. This is more practical for testing, as you need to know what the grid looks like before you pick your test words. I'll fix this when I golf.
f=->nc='' #empty grid
x=[p=6*n,1,-p,-1] #offsets for South, East, North, West
#compose and draw grid
(m=18*n*n).times{|i|c<<((3+i/n%6-i/n/p)/2==2?(65+rand(26)):(i+1)%p==0?10:46)}
puts c
#search function (word, index in grid of last letter, direction)
g=->w,i,d{w==''?($r=1):c[i]<'A'?g[w,(i+x[d])%(m+3*n),d^1]:
(w[-1]==c[i]&&4.times{|j|g[w[0..-2],(i+x[j])%(m+3*n),j^1]})
}
#loop infinitely, set global variable $r to zero and perform search starting at each letter-containing cell of the grid. If found, $r is set to 1.
loop{
w=gets.chomp
$r=0
m.times{|i|c[i]>'@'&&g[w,i,0]}
puts $r,w}}
f[4]
Typical grid output, N=4
....RGPQMXHO...........
....NDVIEPVB...........
....CUJTTWRE...........
....YTLUKBDI...........
........KKRNVQOQ.......
........QBITMZFD.......
........GYMKCIPR.......
........TPTLBYFV.......
............TRMZBMRS...
............XQMHPMPS...
............LBFFERCS...
............TCESTMES...
Searching is performed by the recursive function ́g ́, which is nested in function ́f ́. If the word passed is an empty string the search is complete and $r is set to 1. If the ant is on a letter square which corresponds to the last letter of the word, the search is continued in all four directions: the function is called again with the word shortened by removing its last letter. In this case the direction parameter is ignored. The moving is done by recursively calling with the cell index altered by the values in x. The result of the addition is taken modulo the size of the grid plus an extra half line. This means that the bottom line wraps round to the top and vice versa, with the correct horizontal offset.
#Ruby, 272 bytes#
Two unnecessary newlines are added to the code either side of nested function g to improve readability. These are excluded from the score. The characters f= which assign the anonymous function to a variable are also excluded.
Output format is 0 or 1 per the question instead of Ruby's native true and false. A newline (rather than a space) is used to separate the boolean and the word. My understanding is that this is an acceptable interpretation of the output requirements, but if not, the impact on the byte count would be minor.
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}}
Output
After about 50 calls like this:
I finally got the following output with 2 hits. ANT is at the bottom right going upwards, and the AN is shared by CAN, with the C wrapping round to top left.
....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
Searching is performed by the recursive function g, which is nested in function f. If the word passed is an empty string the search is complete and $r is set to 1. If the ant is on a letter square which corresponds to the first letter of the word, the search is continued in all four directions: the function is called again with the word shortened by removing its first letter. In this case the direction parameter is ignored. The moving is done by recursively calling with the cell index altered by the values in x. The result of the addition is taken modulo the size of the grid plus an extra half line. This means that the bottom line wraps round to the top and vice versa, with the correct horizontal offset.