蟻は立方体の上を歩くことによって言葉を綴ることができますか?


10

正の整数nと単語のリストの2つのパラメーターを取る関数を記述します。

n x n x n単位の立方体が与えられた場合、各表面単位にランダムな文字(AZ)を割り当てます。(3x3x3の立方体の場合、各面に9つのサーフェスユニットがあります。)

次に、水面に沿って歩く(顔を横切ることができる)アリが、提供された各単語を綴ることができるかどうかを判断します。単語を綴るには、文字が上下または左右に隣接している必要がありますが、必ずしも同じ顔にある必要はありません。[ わかりやすくするために編集:アリはパスを逆にして、文字を複数回使用できます。各表面単位は1文字として数えるので、繰り返される文字で単語を綴る(「見る」など)には、蟻は隣接する3つの単位を訪問する必要があります。]

関数は次の2つを出力する必要があります。

1)トポロジーを推測できるように、各面の各文字。たとえば、2x2x2キューブの場合、許容される出力は次のようになります。

   QW
   ER
TY OP UI
DF JK XC
   AS
   GH
   LZ
   VB

2)各単語と、アリが立方体の表面に沿って歩くことによって単語を綴ることが可能かどうかを表すブール値。例えば:

1 ask
0 practical
1 pure
0 full

ボーナスチャレンジ(ちょうど楽しみのためのスコアへの要因、しません):代わりのn個の立方体のサイズのみを表し、聞かせてn個も形状の次元を表しています。したがって、nが2の場合、2x2の正方形になります。N 3は、3×3×3キューブをもたらすであろう。及びN 4は4x4x4x4のたTesseractをもたらすであろう。


1
キューブをどのように出力するかについて、さらに仕様を提供する必要があると思います。たとえば、すべての文字を1行に配置できますが、それらがどのように配置されることになっているのかが常にわかっている場合はどうでしょうか。
— ドアノブ

1
トポロジーを推測できる限り、文字の出力方法に追加の制限を加えたくありません。説明の私の複数行の例は、規範的というよりは説明的なものでした。
— jawns317 2015

3
アリは方向を変えることができるようです。これは明示的に述べられるべきです。180度回転できますか?また、同じ文字を2回続けて使用できますか?言い換えれば、あなたは見つけることができるqwqかqqの例キューブでは?
— Zgarb

3
さらに、アリは文字を複数回使用できますか?
— リルトシアスト2015

1
ランダムな文字の配布のルールは何ですか?あなたの例は繰り返される文字を示していませんが、各文字が26の可能性から独立して選択される単純なアルゴリズムでは、ゼロの繰り返しの可能性はほとんどありません。明らかにN> 2の場合、繰り返しが必要になります。キューブ全体にランダムに分散された2つの異なる文字のみで誰かがキューブを試す場合、これをより明確に指定する必要があります。
— Level River St

回答:


3

Ruby、272バイト

g読みやすさを向上させるために、ネストされた関数の両側に2つの不要な改行がコードに追加されています。これらはスコアから除外されます。f=匿名関数を変数に割り当てる文字も除外されます。

出力フォーマットはある0か1、質問の代わりに、Rubyのネイティブあたり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に設定されます。アリが単語の最初の文字に対応する四角形の上にある場合、検索は4方向すべてに継続されます。関数が再度呼び出されます。最初の文字を削除して単語を短くしました。この場合、方向パラメーターは無視されます。移動は、セルインデックスを変更したセルインデックスを使用して再帰的に呼び出すことによって行われます。x.加算の結果は、グリッドのサイズと追加の半分のラインのサイズを法としてとられます。これは、正しい水平オフセットを使用して、下の線が上に、またはその逆に折り返されることを意味します。

アリが非文字の四角形の上にいる場合、彼女は文字の四角形が見つかるまで階段状にジグザグに動く必要があります。彼女は南東または北西方向にジグザグになります。これはd、彼女の動きを追跡するためにパラメータを毎回1とXOR する再帰呼び出しによってシミュレートされます。彼女が次の文字の正方形に到達するまで、入力語の短縮はありません。便利なことに、これは文字でエリアを検索しているときに使用されるのと同じ再帰によって行われるかもしれません。違いは、アリが空白領域にある場合、再帰には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
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.