Siga os pontos

22

O desafio

Dada uma grade retangular de caracteres

ABCDE
FGHIJ
KLMNO
PQRST

e uma grade com as mesmas dimensões de pontos e espaços

. . .
  . . .
  . .  
  . . .  

Emita a sequência que é gerada seguindo os pontos na grade, começando no canto superior esquerdo. Este exemplo renderiaABGLQRSNIJE

Notas

  • Você pode considerar as grades de entrada como matrizes 2D ou a alternativa mais próxima do seu idioma, em vez de uma sequência de múltiplas linhas.
  • Você pode usar o valor NULL do seu idioma em vez de espaços. Mas você precisa usar pontos para marcar o caminho.
  • Você não precisa separar pontos na mesma linha com espaços. Eu apenas os adicionei para facilitar a leitura.
  • A menor grade possível tem o tamanho 1x1.
  • O ponto inicial e final terá apenas um vizinho. Os pontos entre eles sempre terão exatamente dois vizinhos verticais ou horizontais. Isso garante que o caminho seja inequívoco.
  • O caminho não ficará na diagonal.
  • Os caracteres na grade serão todos os caracteres maiúsculos ou minúsculos no intervalo, o [a-z]que for mais conveniente para você.
  • O caminho sempre começará no canto superior esquerdo.

Regras

  • Função ou programa completo permitido.
  • Regras padrão para entrada / saída.
  • Aplicam-se brechas padrão .
  • Isso é , portanto, a menor contagem de bytes vence. O desempate é uma submissão anterior.

Casos de teste

Grade # 1

ABCABCW
DEFGHUQ
XLUSDQZ
ASUKWXI
WUKOAIM
AIAIOUP
. .          
  . . .      
      .      
. . . .      
.            
.            
=> ABEFGSKUSAWA
. . . . . . .
            .
. . . .
. . . .
. .
. . . . . . .
=> ABCABCWQZIMPUOIAIAWAXLUUK

Posição de largada 2

Observe os espaços triplos nas segundas linhas do primeiro e do segundo exemplos.

AB
CD
.  
   
=> A
. .
   
=> AB
.  
. .
=> ACD

Grade # 3

UMA
.
=> A

Feliz codificação!

Denker
fonte
Tem certeza de que o segundo caso de teste da Grade 1 está correto? Eu acho que a saída deveria ser ABCABCUQXIUOIAIAWAXLUUK.
vaultah
@vaultah Thaks pela dica, corrigida. Tinha os pontos na grade uma coluna à extrema esquerda.
Denker
Precisamos aceitar a entrada com todos os outros caracteres um espaço, como aqui, ou podem ser apenas letras e novas linhas (e sem espaços extras na matriz de pontos)?
Msh210
@ msh210 Como dito no desafio, você pode usar algum tipo de valor NULL em vez de espaços, desde que você aceite a entrada como uma matriz 2D.
Denker
Eu quis dizer, com nada, nem mesmo um byte nulo.
Msh210 #

Respostas:

4

APL, 63 bytes

{⍺[(⊂1 1){×≢⍵:⍺,(V/⍵)∇⍵/⍨~V←(+=⌊/)+/¨2*⍨⍺-⍵⋄⍺}1↓(,⍵='.')/,⍳⍴⍵]}

Essa é uma função que utiliza duas matrizes de caracteres (elas devem ser matrizes), a grade de caracteres como argumento à esquerda e a grade de pontos como argumento à direita. A matriz de pontos pode ser menor que a matriz de caracteres.

Explicação:

  • (,⍵='.')/,⍳⍴⍵: obtém as posições dos pontos, em ordem de coluna de linha
  • 1↓: solte o primeiro (é conhecido por estar 1 1)
  • (⊂1 1){... }: a partir de 1 1, execute a seguinte função, que segue o caminho (seu argumento esquerdo é sua posição atual, seu argumento direito são posições não visitadas). Funciona selecionando o ponto não visitado mais próximo de cada vez. (Se as suposições da pergunta persistirem, isso está correto.)
    • ×≢⍵:: se ainda houver posições não visitadas:
      • +/¨2*⍨⍺-⍵: encontre a distância de Manhattan entre cada posição e a posição atual
      • V←(+=⌊/): para cada posição, veja se a distância é igual à menor distância e armazene-a V.
      • ⍵/⍨~: selecione todas as posições para as quais esse não é o caso, esses são os campos a serem visitados a seguir
      • (V/⍵): encontre a posição em que é o caso, este será o próximo campo
      • : execute a função novamente com esses novos argumentos
      • ⍺,: o resultado é a posição atual, seguida pelo resultado disso no restante da lista
    • ⋄⍺: caso contrário, basta retornar a posição atual e parar (é a última)
  • ⍺[... ]: para cada posição, selecione o elemento correspondente na grade de caracteres.

Casos de teste:

      f←{⍺[(⊂1 1){×≢⍵:⍺,(V/⍵)∇⍵/⍨~V←(+=⌊/)+/¨2*⍨⍺-⍵⋄⍺}1↓(,⍵='.')/,⍳⍴⍵]}
      ⍝ example
      g0  ← 4 5⍴'ABCDEFGHIJKLMNOPQRST'
      d0  ← 4 5⍴'..  . . .. . .  ... '
      ⍝ test case 1
      g1  ← 6 7⍴'ABCACBWDEFGHUQXLUSDQZASUKWXIWUKOAIMAIAIOUP'
      d1a ← 6 7⍴'..      ...      .   ....   .      .      '
      d1b ← 6 7⍴'.......      ....   .. ..  ..     ........'
      ⍝ test case 2
      g2  ← 2 2⍴'ABCD'
      d2a ← 1 1⍴'.'
      d2b ← 1 2⍴'..'
      d2c ← 2 2⍴'. ..'
      ⍝ test case 3
      g3  ← 1 1⍴'A'
      d3  ← 1 1⍴'.'

      g0 f d0
ABGLQRSNIJE
      (⊂g1) f¨ d1a d1b
┌────────────┬─────────────────────────┐
│ABEFGSKUSAWA│ABCACBWQZIMPUOIAIAWAXLUUK│
└────────────┴─────────────────────────┘
      (⊂g2) f¨ d2a d2b d2c
┌─┬──┬───┐
│A│AB│ACD│
└─┴──┴───┘
      g3 f d3
A
marinus
fonte
3

JavaScript (ES6), 122 bytes

c=>g=>c[l=~c.search`
`,i=p=0]+[...g].map(_=>i|!p?c[i=(d=n=>g[i-n-p?i-n:c]>" "&&(p=i)-n)(1)||d(-1)||d(l)||d(-l)]:"").join``

Explicação

Toma as grades como cadeias de linhas múltiplas.

Parece uma tentativa decente, mas fiquei sem tempo enquanto jogava golfe, então provavelmente poderia ser melhorado.

var solution =

c=>g=>
  c[                            // add the starting letter to the output
    l=~c.search`
`,                              // l = line length
    i=p=0                       // i = current index, p = previous index
  ]+
  [...g].map(_=>                // loop
    i|!p?                       // if we have not finished yet
      c[i=                      // find the next index and return it's letter
        (d=n=>                  // d = function to check for a dot at offset n
          g[
            i-n-p?i-n           // if i - n != p, get the character at index i - n
            :c                  // else get index "c" (will return undefined, not a dot)
          ]>" "                 // if the character is a dot
          &&(p=i)-n             // set p to i and return i - n
        )
        (1)||d(-1)||d(l)||d(-l) // search for the next adjacent dot
      ]
    :""                         // if we have finished, return no letter
  )
  .join``                       // output all the returned letters
<textarea id="Characters" rows="6" cols="30">ABCABCW
DEFGHUQ
XLUSDQZ
ASUKWXI
WUKOAIM
AIAIOUP</textarea>
<textarea id="Grid" rows="6" cols="30">.......
      .
...   .
. ..  .
.     .
.......</textarea><br />
<button onclick="result.textContent=solution(Characters.value)(Grid.value)">Go</button>
<pre id="result"></pre>

user81655
fonte