Bir karınca küp üzerinde yürerek kelimeleri heceleyebilir mi?


10

İki parametre alan bir işlev yazın: pozitif bir tamsayı n ve sözcük listesi.

N -by- n -by- n biriminden oluşan bir küp verildiğinde , her bir yüzey birimine rastgele bir harf (AZ) atayın. (3x3x3 küp için, her yüzünde 9 yüzey birimi olacaktır.)

Ardından, yüzey boyunca yürüyen bir karıncanın (yüzleri çaprazlama kabiliyeti ile) verilen kelimelerin her birini hecelemesinin mümkün olup olmadığını belirleyin. Bir kelimeyi hecelemek için, harflerin yukarı / aşağı veya sola / sağa bitişik olması gerektiğini, ancak aynı yüzde olması gerekmediğini varsayın. [ Netlik için düzenleyin: Karınca yolunu tersine çevirebilir ve harfleri birden fazla kullanabilir. Her bir yüzey birimi bir karakter olarak sayılır, bu nedenle tekrarlanan harflerle (örneğin, bkz. ") Bir kelimeyi hecelemek için karıncanın bitişik üç birimi ziyaret etmesi gerekir.]

İşlev iki şey çıkarmalıdır:

1) Her bir yüzdeki harflerin her biri, topoloji çıkarılabilecek şekilde. Örneğin, 2x2x2'lik bir küp için kabul edilebilir bir çıktı şöyle görünür:

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

2) Kelimelerin her biri, karınca için küpün yüzeyi boyunca yürürken kelimeyi hecelemenin mümkün olup olmadığını temsil eden bir boole ile birlikte. Örneğin:

1 ask
0 practical
1 pure
0 full

Bonus meydan (sadece eğlence için, skor içine faktör olmaz): Yerine n küpün sadece boyutunu temsil eden let n da şeklin boyutluluk temsil eder. Bu nedenle, bir n- 2 'lik bir 2x2 kare doğuracak; 3'lük bir n , 3x3x3'lük bir küp verir; ve 4'lük bir n , 4x4x4x4 tesserat verir.


1
Bence küpün nasıl çıkması gerektiği konusunda daha fazla bilgi vermeniz gerekiyor. Örneğin, nasıl düzenlenmeleri gerektiğini her zaman bildiğimiz sürece, tüm harfler tek bir satırda olabilir mi?
Kapı tokmağı

1
Topoloji çıkarılabildiği sürece, harflerin çıktısı için herhangi bir ek sınırlama getirmek istemiyorum. Açıklamadaki çok satırlı örneğim, yasaklayıcı değil açıklayıcıydı.
jawns317

3
Karınca yön değiştirebilir gibi görünüyor; bu açıkça belirtilmelidir. 180 derecelik bir dönüş yapabilir ve aynı harfi arka arkaya iki kez kullanabilir mi? Başka bir deyişle, örnek küpü içinde qwqveya qqiçinde bulabilir misiniz ?
Zgarb

3
Ayrıca, karınca birden fazla kez bir mektup kullanabilir mi?
lirtosiast

1
Rastgele harflerin dağıtım kuralları nelerdir? Örneğinizde yinelenen harfler gösterilmiyor, ancak her harfin 26 olasılıktan bağımsız olarak seçildiği basit bir algoritma ile sıfır tekrarlama olasılığı oldukça düşük. Açıkçası N> 2 ile tekrarlar olmalı. Birisinin tüm küpün üzerinde rastgele dağılmış iki farklı harfli bir küpü denemesi durumunda bunu daha net belirtmelisiniz.
Level River St

Yanıtlar:


3

Yakut, 272 bayt

gOkunabilirliği artırmak için iç içe işlevin her iki tarafındaki koda iki gereksiz satır eklenir . Bunlar puanın dışında tutulur. f=Bir değişkene anonim işlev atayan karakterler de hariç tutulur.

Çıktı biçimi, Ruby'nin yerel ve yerine soru başına 0veya 1sorudur . Boole ve kelimeyi ayırmak için satır başı yerine satırsonu kullanılır. Anladığım kadarıyla, bunun çıktı gereksinimlerinin kabul edilebilir bir yorumu olduğu, ancak değilse, bayt sayısı üzerindeki etkinin küçük olacağı yönündedir.truefalse

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}}

Çıktı

Bunun gibi yaklaşık 50 çağrıdan sonra:

f[4,['PPCG','CODE','GOLF','ANT','CAN','CUBE','WORD','WALK','SPELL']]

Sonunda 2 hit ile aşağıdaki çıktı aldım. ANTsağ altta yukarı doğru gider ve sarma yuvarlak sola üst solda ile ANpaylaşılır .CANC

....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

açıklama

Seçilen küpün belirli bir şekilde açılması, kısmen çizim kolaylığı için, ancak esas olarak arama kolaylığı için seçildi.

Alfabe dışı karakterler (noktalar ve her satırın sonundaki yeni satır), karıncanın yürürken bulunabileceği alanın önemli bir parçasıdır.

Arama, işlevde gyuvalanmış özyinelemeli işlev tarafından gerçekleştirilir f. Geçilen kelime boş bir dizeyse arama tamamlanır ve 1 $rolarak ayarlanır. Karınca kelimenin ilk harfine karşılık gelen bir harf karesinde ise, arama dört yönde de devam eder: işlev tekrar çağrılır kelimesi ilk harfini kaldırarak kısaltılmıştır. Bu durumda, yön parametresi dikkate alınmaz. Hareket, değerlerle değiştirilen hücre indeksi ile tekrar tekrar çağrılarak yapılır x.. Eklemenin sonucu, modulo ızgarasının büyüklüğü artı ekstra bir yarım çizgi alınır. Bu, alt çizginin yukarı doğru ve tam tersi şekilde doğru yatay ofset ile sarıldığı anlamına gelir.

Eğer karınca mektup olmayan bir karede ise, bir mektup karesi bulana kadar merdiven hareketiyle zikzak yapması gerekir. Güneydoğu veya kuzeybatı yönünde zizag yapacak. Bu, dhareketini takip etmek için parametre her seferinde 1 ile XORed olacak şekilde yinelemeli çağrılarla simüle edilir . Bir sonraki harf karesine ulaşıncaya kadar, giriş kelimesinde kısalma olmaz. Uygun bir şekilde, bu, bölgede harflerle arama yaparken kullanılanla aynı özyineleme ile yapılabilir. Fark, özyineleme, karınca boşluk alanındayken, mektup alanında 4'ün aksine, sadece bir dala sahiptir.

Yorumlanan kod

->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
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.