Чи може мураха вимовляти слова, гуляючи по кубі?


10

Напишіть функцію, яка приймає два параметри: натуральне число n та список слів.

Давши куб n- by- n -by- n одиниць, призначте довільній букві (AZ) кожну поверхневу одиницю. (Для куба розміром 3x3x3 було б 9 поверхневих одиниць на кожній грані.)

Потім визначте, чи можливо мураха, що йде по поверхні (з можливістю перехрещувати обличчя), щоб написати кожне із поданих слів. Припустимо, що для написання слова букви повинні бути вгору / вниз або вліво / вправо примикають, але не обов'язково на одній грані. [ Редагувати, для наочності: Мураха може перевернути свій шлях і використовувати букви не один раз. Кожна одиниця поверхні вважається одним символом, тому для написання слова з повторними літерами (наприклад, "бачити") мурашник повинен був би відвідати три сусідні одиниці.]

Функція повинна виводити дві речі:

1) Кожна з букв на кожному обличчі таким чином, щоб можна було зробити висновок про топологію. Наприклад, для куба 2х2х2 прийнятний вихід виглядатиме так:

   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 дасть площу 2х2; п з 3 дало б 3x3x3 куб; і n з 4 дасть тессеракт 4x4x4x4.


1
Я думаю, вам потрібно надати додаткову специфікацію щодо виведення куба. Наприклад, чи всі букви можуть бути в одному рядку, якщо ми завжди знаємо, як вони повинні бути впорядковані?
Дверна ручка

1
Поки можна зробити висновок про топологію, я не хочу розміщувати додаткових обмежень щодо виведення букв. Мій багаторядковий приклад в описі був більш наочним, а не проскриптивним.
jawns317

3
Схоже, мурашка здатна змінювати напрямок; це слід сказати прямо. Чи може він зробити поворот на 180 градусів, і чи може він використовувати ту саму букву двічі поспіль? Іншими словами, ви можете знайти qwqчи qqв прикладі куба?
Згарб

3
Крім того, чи може мураха використовувати лист ще раз?
lirtosiast

1
Які правила розподілу випадкових букв? Ваш приклад не показує повторних літер, але при простому алгоритмі, коли кожна буква вибирається незалежно з 26 можливостей, шанси на нульове повторення вкрай малоймовірні. Очевидно, що з N> 2 доведеться повторювати. Ви повинні вказати це більш чітко, на випадок, якщо хтось спробує куб із лише двома різними літерами, розподіленими випадковим чином по всьому кубу.
Рівень р. Св.

Відповіді:


3

Рубін, 272 байти

Дві непотрібні рядки додаються до коду з будь-якої сторони вкладеної функції gдля поліпшення читабельності. Вони виключені з балу. Символи, f=які присвоюють анонімну функцію змінній, також виключаються.

Формат виводу - це 0або 1за запитанням замість рідного 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. Якщо мурашка знаходиться на літерному квадраті, що відповідає першій букві слова, пошук продовжується у всіх чотирьох напрямках: функція викликається знову при цьому слово скорочено, видаливши його першу букву. У цьому випадку параметр напряму ігнорується. Переміщення відбувається за допомогою рекурсивного виклику з індексом комірки, зміненим значеннями в. x.В результаті додавання приймається модуль розміром сітки плюс додаткова половина рядка. Це означає, що нижня лінія обертається круглою до верхньої та навпаки, з правильним горизонтальним зміщенням.

Якщо мурашка знаходиться на не буквеному квадраті, вона повинна зигзагувати рухом сходів, поки не знайде буквеного квадрата. Вона буде зизагувати в південно-східному або північно-західному напрямку. Це моделюється рекурсивними дзвінками, dпараметр XORed з 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
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.