Ukończ meander wypełniający siatkę

18

Wypełniający siatkę meander to zamknięta ścieżka, która co najmniej raz odwiedza każdą komórkę kwadratowej siatki , nigdy nie przekraczając żadnej krawędzi między sąsiednimi komórkami więcej niż jeden raz i nigdy nie przekraczając siebie. Na przykład:N×N

Po wypełnieniu każda komórka siatki może być reprezentowana przez jeden z następujących 8 kafelków:

Ponumerowane w ten sposób kafelki powyższego meandra mogą być reprezentowane przez tę macierz:

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

Twoim zadaniem jest ukończenie meandra wypełniającego siatkę, biorąc pod uwagę niekompletny zestaw płytek. Na przykład niepełny meander:

... które można przedstawić za pomocą 0s dla brakujących kafelków:

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

... można wykonać w następujący sposób:

...to znaczy:

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

Dane techniczne

  • Dane wejściowe zawsze będą miały co najmniej a najwyżej (niepuste) kafelki, gdzie1N22N7 .
  • Możesz użyć dowolnego zestawu wartości do przedstawienia kafelków, o ile jest to określone w odpowiedzi.
  • Twoje dane wejściowe i wyjściowe mogą być w dowolnym formacie i kolejności, o ile jest to określone w odpowiedzi.
  • Dla wszystkich danych wejściowych istnieje co najmniej jedno prawidłowe rozwiązanie (tzn. Nie trzeba obsługiwać nieprawidłowych danych wejściowych).
  • Obowiązują standardowe zasady we / wy .
  • Standardowe luki są zabronione.
  • Zachęca się do wyjaśnień, nawet w przypadku „praktycznych” języków.

Przypadki testowe

Wejście ( Θ ):

0 6
0 0

Wyjście ( Θ ):

5 6
4 3

Wejście ( Θ ):

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

Wyjście ( Θ ):

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

Wejście ( Θ ):

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

Wyjście ( Θ ):

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
Jordania
źródło
1
@Arnauld Masz rację; to nie jest poprawne. Meander to pojedyncza zamknięta ścieżka.
Jordan
1
@Arnauld Dzięki, wprowadziłem tę zmianę. Nie wiedziałem, że MathJax został włączony na tej stronie!
Jordan

Odpowiedzi:

11

JavaScript (ES7),  236 ... 193  185 bajtów

Wyjścia poprzez modyfikację macierzy wejściowej.

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)

Wypróbuj online!

(zawiera część kodu końcowego do wydrukowania wyniku zarówno w postaci matrycy, jak i płaskiej listy zgodnej z narzędziem do wizualizacji udostępnianym przez PO)

Wyniki

W jaki sposób?

Zmienne

gd(x,y)v

g

  • r

    r = m[y]
  • h18gg0

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

Wstępne kontrole

n

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

(0,0)v>0

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

Na razie załóżmy, że nie wróciliśmy do punktu wyjścia.

Poszukuję ścieżki

n0h aby wypróbować wszystkie możliwe wartości dla tego kafelka.

n0 , próbujemy przejść do następnego kafelka.

ndd

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

Ostatnie 8 wpisów jest niepoprawnych i pominiętych. Pozostałe 4 nieprawidłowe wpisy są wyraźnie oznaczone łącznikami.

Dla porównania poniżej znajduje się dekodowana tabela, kompas i zestaw kafelków podane w wyzwaniu:

   | 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

g1/2v781

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

dxy , zmuszając następnej iteracji natychmiast zawiedzie.

Sprawdzanie poprawności ścieżki

(0,0)v>0 , niekoniecznie oznacza to, że znaleźliśmy prawidłową ścieżkę, ponieważ mogliśmy skorzystać ze skrótu. Musimy sprawdzić, czy odwiedziliśmy prawidłową liczbę komórek.

781/2v kiedy taka płytka jest odwiedzana.

v=N2v>N2v<N2kk=v .

Stąd kod JS:

!m[v ** .5 | 0]

Sformatowane źródło

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
źródło
Dobra robota. Chciałbym przeczytać wyjaśnienie kodu.
Jordan
@Arnauld, czy brutalnie wymuszasz to, czy używasz innego algorytmu?
Jonasz
1
@Jonah Obecnie piszę wyjaśnienie. Zasadniczo tak, jest to podejście oparte na brutalnej sile, ale algorytm cofa się, gdy tylko wykryta zostanie pewna niespójność, zamiast wypróbowywać każdą możliwą kartę.
Arnauld