Uma formiga pode soletrar palavras andando no cubo?


10

Escreva uma função que aceite dois parâmetros: um número inteiro positivo n e uma lista de palavras.

Dado um cubo de unidades n- por- n- por- n , atribua uma letra aleatória (AZ) a cada unidade de superfície. (Para um cubo 3x3x3, haveria 9 unidades de superfície em cada face.)

Em seguida, determine se é possível que uma formiga caminhe pela superfície (com a capacidade de cruzar faces) soletrar cada uma das palavras fornecidas. Suponha que para escrever uma palavra, as letras devem estar para cima / baixo ou esquerda / direita adjacentes, mas não necessariamente na mesma face. [ Editar, para maior clareza: a formiga pode reverter seu caminho e usar letras mais de uma vez. Cada unidade de superfície conta como um caractere; portanto, para escrever uma palavra com letras repetidas (por exemplo, "ver"), a formiga deve visitar três unidades adjacentes.]

A função deve gerar duas coisas:

1) Cada uma das letras em cada face, de forma que a topologia possa ser inferida. Por exemplo, para um cubo 2x2x2, uma saída aceitável seria semelhante a:

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

2) Cada uma das palavras, juntamente com um booleano, representa se é possível que a formiga soletre a palavra caminhando pela superfície do cubo. Por exemplo:

1 ask
0 practical
1 pure
0 full

Desafio de bônus (não será considerado na pontuação, apenas por diversão): em vez de n representar apenas o tamanho do cubo, deixe n também representar a dimensionalidade da forma. Portanto, um n de 2 produziria um quadrado 2x2; um n de 3 produziria um cubo 3x3x3; e um n de 4 produziria um efeito tesseract 4x4x4x4.


11
Eu acho que você precisa fornecer mais especificações sobre como o cubo deve ser produzido. Por exemplo, todas as letras podem estar em uma linha, desde que sempre saibamos como elas devem ser organizadas?
Maçaneta da porta

11
Contanto que a topologia possa ser inferida, não quero colocar nenhuma limitação adicional em como as letras são exibidas. Meu exemplo de várias linhas na descrição foi ilustrativo, e não proscritivo.
jawns317

3
Parece que a formiga é capaz de mudar de direção; isso deve ser declarado explicitamente. Pode fazer uma curva de 180 graus e usar a mesma letra duas vezes seguidas? Em outras palavras, você pode encontrar qwqou qqno cubo de exemplo?
Zgarb

3
Além disso, a formiga pode usar uma carta mais de uma vez?
Lirtosiast

11
Quais são as regras para distribuição das letras aleatórias? Seu exemplo não mostra letras repetidas, mas com um algoritmo simples em que cada letra é escolhida independentemente dentre 26 possibilidades, as chances de repetições zero são altamente improváveis. Obviamente, com N> 2, haverá repetições. Você deve especificar isso mais claramente, caso alguém tente um cubo com apenas duas letras diferentes distribuídas aleatoriamente por todo o cubo.
Level River St

Respostas:


3

Ruby, 272 bytes

Duas novas linhas desnecessárias são adicionadas ao código em ambos os lados da função aninhada gpara melhorar a legibilidade. Estes são excluídos da pontuação. Os caracteres f=que atribuem a função anônima a uma variável também são excluídos.

O formato de saída é 0ou 1por pergunta, em vez do nativo truee do Ruby false. Uma nova linha (em vez de um espaço) é usada para separar o booleano e a palavra. Meu entendimento é que essa é uma interpretação aceitável dos requisitos de saída, mas, se não, o impacto na contagem de bytes seria 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}}

Resultado

Após cerca de 50 chamadas como esta:

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

Finalmente consegui a seguinte saída com 2 hits. ANTfica no canto inferior direito, subindo, e ANé compartilhado por CAN, com o Ccontorno redondo para o canto superior esquerdo.

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

Explicação

O desdobramento particular do cubo selecionado foi escolhido em parte por sua facilidade de desenho, mas principalmente por sua facilidade de pesquisa.

Os caracteres que não são do alfabeto (os pontos mais a nova linha no final de cada linha) são uma parte importante do campo em que a formiga pode ser encontrada andando.

A pesquisa é realizada pela função recursiva g, que está aninhada na função f. Se a palavra passada for uma sequência vazia, a pesquisa será concluída e $rdefinida como 1. Se a formiga estiver em um quadrado de letras correspondente à primeira letra da palavra, a pesquisa continuará nas quatro direções: a função é chamada novamente com a palavra abreviada removendo sua primeira letra. Nesse caso, o parâmetro de direção é ignorado. O movimento é feito chamando recursivamente com o índice de células alterado pelos valores em x.O resultado da adição é obtido pelo módulo do tamanho da grade mais uma meia linha extra. Isso significa que a linha de baixo passa para o topo e vice-versa, com o deslocamento horizontal correto.

Se a formiga estiver em um quadrado que não seja uma letra, ela deverá zigue-zague em um movimento de escada até encontrar um quadrado de letras. Ela zizag na direção sudeste ou noroeste. Isso é simulado por chamadas recursivas, com o dparâmetro sendo XOR com 1 a cada vez para acompanhar o movimento dela. Até que ela atinja o próximo quadrado da letra, não há encurtamento da palavra de entrada. Convenientemente, isso pode ser feito pela mesma recursão usada quando estamos pesquisando na área com letras. A diferença é que a recursão tem apenas um ramo quando a formiga está na área de espaço em branco, em oposição a 4 na área da 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
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.