Bisakah semut mengeja kata dengan berjalan di atas kubus?

10

Tulis fungsi yang mengambil dua parameter: bilangan bulat positif n dan daftar kata-kata.

Mengingat kubus n -by- n -by- n unit, menetapkan huruf acak (AZ) untuk setiap unit permukaan. (Untuk kubus 3x3x3, akan ada 9 unit permukaan pada setiap wajah.)

Kemudian tentukan apakah semut dapat berjalan di sepanjang permukaan (dengan kemampuan untuk menyeberangi wajah) untuk mengeja setiap kata yang disediakan. Asumsikan bahwa untuk mengeja kata, huruf-huruf harus berada di atas / bawah atau berdekatan / kiri, tetapi tidak harus pada wajah yang sama. [ Sunting, untuk kejelasan: Semut dapat membalik jalurnya dan menggunakan huruf lebih dari satu kali. Setiap unit permukaan dihitung sebagai satu karakter, jadi untuk mengeja kata dengan huruf berulang (misalnya "lihat") semut harus mengunjungi tiga unit yang berdekatan.]

Fungsi harus menampilkan dua hal:

1) Masing-masing huruf di setiap wajah, sedemikian rupa sehingga topologi dapat disimpulkan. Misalnya, untuk kubus 2x2x2, output yang dapat diterima akan terlihat seperti:

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

2) Masing-masing kata, bersama dengan boolean yang mewakili apakah mungkin bagi semut untuk mengeja kata dengan berjalan di sepanjang permukaan kubus. Contohnya:

1 ask
0 practical
1 pure
0 full

Tantangan bonus (tidak akan menjadi faktor dalam skor, hanya untuk bersenang-senang): Alih-alih n hanya mewakili ukuran kubus, biarkan n juga mewakili dimensi bentuk. Jadi, n dari 2 akan menghasilkan 2x2 persegi; sebuah n dari 3 akan menghasilkan kubus 3x3x3; dan n dari 4 akan menghasilkan tesseract 4x4x4x4.

jawns317
sumber
1
Saya pikir Anda perlu memberikan spesifikasi lebih lanjut tentang bagaimana kubus harus menjadi output. Sebagai contoh, dapatkah semua huruf berada dalam satu baris, asalkan kita selalu tahu bagaimana seharusnya disusun?
Gagang Pintu
1
Selama topologi dapat disimpulkan, saya tidak ingin menempatkan batasan tambahan pada bagaimana surat-surat itu dihasilkan. Contoh multi-baris saya dalam uraian ini lebih bersifat ilustratif, bukan proskriptif.
jawns317
3
Sepertinya semut mampu mengubah arah; ini harus dinyatakan secara eksplisit. Bisakah itu berbelok 180 derajat, dan bisakah menggunakan huruf yang sama dua kali berturut-turut? Dengan kata lain, dapatkah Anda menemukan qwqatau qqdalam contoh kubus?
Zgarb
3
Selanjutnya, dapatkah semut menggunakan surat lebih dari satu kali?
lirtosiast
1
Apa aturan untuk distribusi huruf acak? Contoh Anda tidak menunjukkan huruf yang diulang, namun dengan algoritma sederhana di mana setiap huruf dipilih secara independen dari 26 kemungkinan, kemungkinan nol pengulangan sangat kecil kemungkinannya. Tentunya dengan N> 2 harus ada pengulangan. Anda harus menentukan ini lebih jelas, jika seseorang mencoba sebuah kubus dengan hanya dua huruf berbeda yang didistribusikan secara acak ke seluruh kubus.
Level River St

Jawaban:

3

Ruby, 272 byte

Dua baris baru yang tidak perlu ditambahkan ke kode di kedua sisi fungsi bersarang guntuk meningkatkan keterbacaan. Ini dikecualikan dari skor. Karakter f=yang menetapkan fungsi anonim ke variabel juga dikecualikan.

Format output adalah 0atau 1per pertanyaan, bukan asli truedan Ruby false. Baris baru (bukan spasi) digunakan untuk memisahkan boolean dan kata. Pemahaman saya adalah bahwa ini adalah interpretasi yang dapat diterima dari persyaratan output, tetapi jika tidak, dampak pada jumlah byte akan kecil.

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

Keluaran

Setelah sekitar 50 panggilan seperti ini:

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

Saya akhirnya mendapatkan output berikut dengan 2 hit. ANTberada di kanan bawah naik ke atas, dan ANdibagikan oleh CAN, dengan Cputaran pembungkus ke kiri atas.

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

Penjelasan

Terungkapnya kubus yang dipilih, dipilih sebagian karena kemudahan menggambar, tetapi terutama karena kemudahan pencarian.

Karakter non-alfabet (titik-titik ditambah baris baru di akhir setiap baris) adalah bagian penting dari bidang di mana semut dapat ditemukan berjalan.

Pencarian dilakukan oleh fungsi rekursif g, yang bersarang dalam fungsi f. Jika kata yang dilewatkan adalah string kosong pencarian selesai dan $rdiatur ke 1. Jika semut pada kotak huruf yang sesuai dengan huruf pertama dari kata, pencarian dilanjutkan di keempat arah: fungsi dipanggil lagi dengan kata yang disingkat dengan menghapus huruf pertama. Dalam hal ini parameter arah diabaikan. Pemindahan dilakukan dengan pemanggilan berulang dengan indeks sel diubah oleh nilai-nilai dalam x.. Hasil penambahan diambil modulo ukuran grid ditambah setengah garis tambahan. Ini berarti bahwa garis bawah membungkus putaran ke atas dan sebaliknya, dengan offset horizontal yang benar.

Jika semut berada di bujur sangkar non-huruf, ia harus zig-zag dalam gerakan tangga sampai ia menemukan bujur sangkar huruf. Dia akan zizag di arah tenggara atau barat laut. Ini disimulasikan oleh panggilan rekursif dengan dparameter sedang XOR dengan 1 setiap kali untuk melacak pergerakannya. Sampai dia mencapai kotak huruf berikutnya, tidak ada pemendekan kata input. Mudahnya, ini dapat dilakukan dengan rekursi yang sama seperti yang digunakan ketika kita mencari di daerah dengan surat. Perbedaannya adalah, rekursi hanya memiliki satu cabang ketika semut berada di area spasi, berbeda dengan 4 di area huruf.

Kode yang dikomentari

->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
}
Level River St
sumber