Complete o meandro de preenchimento da grade

18

Um meandro de preenchimento de grade é um caminho fechado que visita todas as células de uma grade quadrada pelo menos uma vez, nunca cruzando nenhuma borda entre células adjacentes mais de uma vez e nunca cruzando a si próprio. Por exemplo:N×N

Uma vez preenchidas, cada célula da grade pode ser representada por um dos 8 blocos a seguir:

Numerados dessa maneira, os ladrilhos do meandro acima podem ser representados por esta matriz:

5 6 5 6
4 8 3 2
5 7 6 2
4 3 4 3

Sua tarefa é concluir um meandro de preenchimento de grade, devido a um conjunto incompleto de peças. Por exemplo, o meandro incompleto:

... que pode ser representado usando 0s para blocos ausentes:

5 0 0 0 6
0 0 7 0 0
0 0 0 0 3
2 4 0 0 0
0 0 3 0 0

... poderia ser concluído assim:

... ou seja:

5 6 5 1 6
4 8 7 6 2
5 7 7 7 3
2 4 8 8 6
4 1 3 4 3

Especificações

  • A entrada sempre terá pelo menos 1 e, no máximo , blocos N2 (não vazios), onde 2N7 .
  • Você pode usar qualquer conjunto de valores para representar os blocos, desde que especificados em sua resposta.
  • Sua entrada e saída podem estar em qualquer formato e ordem, desde que especificadas na sua resposta.
  • Pelo menos uma solução válida existirá para todas as entradas (ou seja, você não precisa lidar com entradas inválidas).
  • Aplicam- se as regras de E / S padrão .
  • As brechas padrão são proibidas.
  • Explicações, mesmo para idiomas "práticos", são incentivadas.

Casos de teste

Entrada ( Θ ):

0 6
0 0

Saída ( Θ ):

5 6
4 3

Entrada ( Θ ):

5 6 5 6
4 0 3 2
5 7 6 2
4 3 4 3

Saída ( Θ ):

5 6 5 6
4 8 3 2
5 7 6 2
4 3 4 3

Entrada ( Θ ):

5 0 0 0 6
0 0 7 0 0
0 0 0 0 3
2 4 0 0 0
0 0 3 0 0

Saída ( Θ ):

5 6 5 1 6
4 8 7 6 2
5 7 7 7 3
2 4 8 8 6
4 1 3 4 3
Jordânia
fonte
1
@ Arnauld Você está correto; não é válido. Um meandro é um único caminho fechado.
Jordan em
1
@ Arnauld Obrigado, eu fiz essa mudança. Não sabia que o MathJax estava ativado neste site!
Jordan em

Respostas:

11

JavaScript (ES7),  236 ... 193  185 bytes

Saídas modificando a matriz de entrada.

m=>(g=(d,x,y,v,r=m[y],h=_=>++r[x]<9?g(d,x,y,v)||h():r[x]=0)=>r&&1/(n=r[x])?x|y|!v?n?g(d='21100--13203-32-21030321'[n*28+d*3+7&31],x+--d%2,y+--d%2,v+=n<7||.5):h():!m[v**.5|0]:0)(0,0,0,0)

Experimente online!

(inclui algum código de pós-processamento para imprimir o resultado como uma matriz e como uma lista simples compatível com a ferramenta de visualização fornecida pelo OP)

Resultados

Quão?

Variáveis

gd(x,y)v

g

  • r

    r = m[y]
  • h é uma função auxiliar que tenta todos os valores de18gg0 0

    h = _ => ++r[x] < 9 ? g(d, x, y, v) || h() : r[x] = 0

Verificações iniciais

n

r && 1 / (n = r[x]) ? ... ok ... : ... failed ...

(0 0,0 0)v>0 0

x | y | !v ? ... no ... : ... yes ...

Por enquanto, vamos supor que não estamos de volta ao ponto de partida.

Procurando um caminho

n0 0h

n0 0

As conexões de bloco são codificadas em uma tabela de pesquisa, cujo índice é calculado com ndd

d = '21100--13203-32-21030321'[n * 28 + d * 3 + 7 & 31]

As últimas 8 entradas são inválidas e omitidas. As outras 4 entradas inválidas são explicitamente marcadas com hífens.

Para referência, abaixo estão a tabela decodificada, a bússola e o conjunto de peças fornecidas no desafio:

   | 1 2 3 4 5 6 7 8
---+-----------------
 0 | 0 - - 1 3 - 3 1          1
 1 | - 1 - - 2 0 2 0        0 + 2
 2 | 2 - 1 - - 3 1 3          3
 3 | - 3 0 2 - - 0 2

Fazemos uma chamada recursiva para g com a nova direção e as novas coordenadas. Nós adicionamos 1/2 para v se estivéssemos em uma telha do tipo 781

g(d, x + --d % 2, y + --d % 2, v += n < 7 || .5)

Se dxy

Validando o caminho

Por fim, quando voltarmos a (0 0,0 0)v>0 0

Cada bloco deve ser visitado uma vez, exceto os blocos 7 e 8 que devem ser visitados duas vezes. É por isso que adicionamos apenas1/2v

v=N2v>N2v<N2kk=v

Daí o código JS:

!m[v ** .5 | 0]

Fonte formatada

m => (
  g = (
    d,
    x, y,
    v,
    r = m[y],
    h = _ => ++r[x] < 9 ? g(d, x, y, v) || h() : r[x] = 0
  ) =>
    r && 1 / (n = r[x]) ?
      x | y | !v ?
        n ?
          g(
            d = '21100--13203-32-21030321'[n * 28 + d * 3 + 7 & 31],
            x + --d % 2,
            y + --d % 2,
            v += n < 7 || .5
          )
        :
          h()
      :
        !m[v ** .5 | 0]
    :
      0
)(0, 0, 0, 0)
Arnauld
fonte
Bom trabalho. Eu adoraria ler uma explicação do código.
Jordan em
@ Arnauld você está forçando brutalmente ou usando outro algoritmo?
Jonah
1
@Jonah Atualmente, estou escrevendo uma explicação. Basicamente, sim, é uma abordagem de força bruta, mas o algoritmo retrocede assim que alguma inconsistência é detectada, em vez de tentar cada placa possível.
Arnauld