¿Puede una hormiga deletrear palabras caminando sobre un cubo?

10

Escriba una función que tome dos parámetros: un entero positivo n y una lista de palabras.

Dado un cubo de n -by- n -by- n unidades, asigne una letra aleatoria (AZ) a cada unidad de superficie. (Para un cubo de 3x3x3, habría 9 unidades de superficie en cada cara).

Luego determine si es posible que una hormiga camine por la superficie (con la capacidad de cruzar caras) para deletrear cada una de las palabras proporcionadas. Suponga que para deletrear una palabra, las letras deben estar arriba / abajo o izquierda / derecha adyacentes, pero no necesariamente en la misma cara. [ Editar, para mayor claridad: la hormiga puede invertir su camino y usar letras más de una vez. Cada unidad de superficie cuenta como un carácter, por lo que para deletrear una palabra con letras repetidas (por ejemplo, "ver") la hormiga tendría que visitar tres unidades adyacentes.]

La función debería generar dos cosas:

1) Cada una de las letras en cada cara, de tal manera que se pueda inferir la topología. Por ejemplo, para un cubo de 2x2x2, un resultado aceptable se vería así:

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

2) Cada una de las palabras, junto con un booleano que representa si es posible que la hormiga deletree la palabra caminando a lo largo de la superficie del cubo. Por ejemplo:

1 ask
0 practical
1 pure
0 full

Desafío de bonificación (no tendrá en cuenta el puntaje, solo por diversión): en lugar de que n represente solo el tamaño del cubo, que n también represente la dimensionalidad de la forma. Entonces, un n de 2 produciría un cuadrado de 2x2; un n de 3 produciría un cubo de 3x3x3; y un n de 4 produciría un tesseract de 4x4x4x4.

jawns317
fuente
1
Creo que debe proporcionar especificaciones adicionales sobre cómo se debe generar el cubo. Por ejemplo, ¿pueden todas las letras estar en una línea, siempre que sepamos cómo se supone que están organizadas?
Pomo de la puerta
1
Mientras se pueda inferir la topología, no quiero establecer limitaciones adicionales sobre la forma en que se emiten las letras. Mi ejemplo de varias líneas en la descripción fue ilustrativo, más que proscriptivo.
jawns317
3
Parece que la hormiga puede cambiar de dirección; Esto debe declararse explícitamente. ¿Puede hacer un giro de 180 grados y puede usar la misma letra dos veces seguidas? En otras palabras, ¿puedes encontrar qwqo qqen el cubo de ejemplo?
Zgarb
3
Además, ¿puede la hormiga usar una letra más de una vez?
lirtosiast el
1
¿Cuáles son las reglas para la distribución de las letras aleatorias? Su ejemplo no muestra letras repetidas, sin embargo, con un algoritmo simple en el que cada letra se selecciona independientemente de 26 posibilidades, es muy poco probable que haya cero repeticiones. Obviamente con N> 2 tendrá que haber repeticiones. Debe especificar esto más claramente, en caso de que alguien pruebe un cubo con solo dos letras diferentes distribuidas aleatoriamente en todo el cubo.
Level River St

Respuestas:

3

Rubí, 272 bytes.

Se agregan dos líneas nuevas innecesarias al código a cada lado de la función anidada gpara mejorar la legibilidad. Estos están excluidos de la puntuación. Los caracteres f=que asignan la función anónima a una variable también están excluidos.

El formato de salida es 0o 1según la pregunta en lugar del nativo de Ruby truey false. Se utiliza una nueva línea (en lugar de un espacio) para separar el booleano y la palabra. Tengo entendido que esta es una interpretación aceptable de los requisitos de salida, pero si no, el impacto en el recuento de bytes sería menor.

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

Salida

Después de unas 50 llamadas como esta:

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

Finalmente obtuve el siguiente resultado con 2 hits. ANTestá en la parte inferior derecha hacia arriba, y ANes compartido por CAN, con la Cronda de ajuste hacia arriba a la izquierda.

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

Explicación

El despliegue particular del cubo seleccionado fue elegido en parte por su facilidad de dibujo, pero principalmente por su facilidad de búsqueda.

Los caracteres que no son del alfabeto (los puntos más la nueva línea al final de cada línea) son una parte importante del campo donde se puede encontrar a la hormiga caminando.

La búsqueda se realiza mediante la función recursiva g, que está anidada en la función f. Si la palabra pasada es una cadena vacía, la búsqueda está completa y $rse establece en 1. Si la hormiga está en un cuadrado de letra que corresponde a la primera letra de la palabra, la búsqueda continúa en las cuatro direcciones: la función se llama nuevamente con la palabra acortada quitando su primera letra. En este caso, se ignora el parámetro de dirección. El movimiento se realiza mediante una llamada recursiva con el índice de la celda alterado por los valores en x.El resultado de la adición se toma el módulo del tamaño de la cuadrícula más una media línea adicional. Esto significa que la línea inferior se ajusta a la parte superior y viceversa, con el desplazamiento horizontal correcto.

Si la hormiga está en un cuadrado que no es letra, debe zigzaguear en un movimiento de escalera hasta que encuentre un cuadrado de letra. Ella zizag en dirección sureste o noroeste. Esto se simula mediante llamadas recursivas con el dparámetro XORed con 1 cada vez para realizar un seguimiento de su movimiento. Hasta que llegue al siguiente cuadro de letras, no se acortará la palabra de entrada. Convenientemente, esto puede hacerse por la misma recursión que se utiliza cuando buscamos en el área con letras. La diferencia es que la recursión tiene solo una rama cuando la hormiga está en el área de espacios en blanco, en lugar de 4 en el área de la letra.

Código comentado

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