Tolong, saya terjebak dalam segitiga Sierpinski!

44

Menggambar segitiga Sierpinski telah dilakukan sampai mati . Ada hal menarik lain yang bisa kita lakukan dengannya. Jika kita menyipit cukup keras pada segitiga, kita dapat melihat segitiga terbalik sebagai simpul dari grafik fraktal. Ayo temukan jalan kita di sekitar grafik itu!

Pertama, mari kita berikan nomor untuk setiap node. Segitiga terbalik terbesar adalah simpul nol, dan kemudian kita turunkan lapis demi lapis (lebar-pertama), dengan menetapkan angka berurutan dalam urutan atas-kiri-kanan:

masukkan deskripsi gambar di sini
Klik untuk versi yang lebih besar di mana angka-angka kecil agak kurang buram.

(Tentu saja, pola ini terus tak terhingga di dalam segitiga biru.) Cara lain untuk menentukan penomoran adalah bahwa simpul pusat memiliki indeks 0, dan anak-anak dari simpul i(segitiga yang berdekatan dari-kecil selanjutnya skala) memiliki indeks 3i+1, 3i+2dan 3i+3.

Bagaimana kita bergerak di sekitar grafik ini? Ada hingga enam langkah alami yang bisa diambil dari setiap segitiga:

  • Satu selalu dapat bergerak melalui titik tengah dari salah satu tepi ke salah satu dari tiga anak dari simpul saat ini. Kami akan menunjuk gerakan ini sebagai N, SWdan SE. Misalnya jika kita saat ini simpul 2, ini akan menyebabkan node 7, 8, 9, masing-masing. Bergerak lain melalui tepi (ke keturunan tidak langsung) dilarang.
  • Satu juga dapat bergerak melalui salah satu dari tiga sudut, asalkan tidak menyentuh tepi segitiga, baik ke induk langsung atau salah satu dari dua leluhur tidak langsung. Kami akan menunjuk gerakan ini sebagai S, NEdan NW. Misal jika kita saat ini di node 31, Sakan mengarah ke 10, NEakan menjadi tidak valid dan NWakan mengarah ke 0.

Tantangan

Diberi dua bilangan bulat non-negatif xdan y, cari jalur terpendek dari xke y, hanya menggunakan enam gerakan yang dijelaskan di atas. Jika ada beberapa jalur terpendek, output salah satunya.

Perhatikan bahwa kode Anda harus berfungsi lebih dari 5 level yang digambarkan dalam diagram di atas. Anda mungkin menganggap itu x, y < 1743392200. Ini memastikan bahwa mereka masuk di dalam integer bertanda 32-bit. Perhatikan bahwa ini sesuai dengan 20 level pohon.

Kode Anda harus memproses setiap input yang valid dalam waktu kurang dari 5 detik . Walaupun ini mengesampingkan pencarian brute force pertama, itu harus menjadi kendala yang cukup longgar - implementasi referensi saya menangani input sewenang-wenang untuk kedalaman 1000 dalam setengah detik (itu ~ angka 480-digit untuk node).

Anda dapat menulis suatu program atau fungsi, mengambil input melalui STDIN (atau alternatif terdekat), argumen baris perintah atau argumen fungsi dan mengeluarkan hasilnya melalui STDOUT (atau alternatif terdekat), nilai pengembalian fungsi atau parameter fungsi (keluar).

Output harus datar, daftar ambigu dari string N, S, NE, NW, SE, SW, menggunakan pemisah wajar (spasi, linefeeds, koma, ","...).

Aturan standar berlaku.

Uji Kasus

Beberapa kasus uji pertama dapat dikerjakan dengan tangan menggunakan diagram di atas. Yang lain memastikan bahwa jawabannya cukup efisien. Bagi mereka, mungkin ada solusi lain dengan panjang yang sama yang tidak terdaftar.

0 40                    => N N N N
66 67                   => S SW N N N
30 2                    => NW NW -or- NE SW
93 2                    => NE SW
120 61                  => NW NW NW NW N SE SW N
1493682877 0            => S S NW NW
0 368460408             => SW SW N N SW SW SE SW SW N SE N N SW SW N SE SE
1371432130 1242824      => NW NW NE NW N SE SW SW SW SE SE SW N N N N SW
520174 1675046339       => NE NW NE NE SE SE SW SW N SE N SW N SW SE N N N N SE SE SW SW
312602548 940907702     => NE NW S SW N N SW SE SE SE SW SE N N SW SE SE SE SW
1238153746 1371016873   => NE NE NE SE N N SW N N SW N SE SE SW N SW N N SE N SE N
547211529 1386725128    => S S S NE NW N N SE N SW N SE SW SE SW N SE SE N SE SW SW N
1162261466 1743392199   => NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE
Martin Ender
sumber

Jawaban:

5

Ruby, 195 194 190 184 byte

Asli: Dengan permintaan maaf kepada Ell , karena ini pada dasarnya adalah port jawaban mereka dan dengan banyak terima kasih kepada Doorknob atas bantuan mereka dalam men -debug jawaban ini. Mungkin ada algoritma lain untuk masalah ini - ada hubungannya dengan *f[x[0,**however far x matches with y**],y]- tapi saya akan menghemat itu untuk lain waktu.

a=->n{n<1?[]:a[~-n/3]+[-n%3]}
f=->x,y{j=x.size
(Array===x)?x==y[0,j]?y[j..-1].map{|m|%w[SE SW N][m]}:x.uniq.map{|m|[%w[NW NE S][m],*f[x[0,x.rindex(m)],y]]}.min_by(&:size):f[a[x],a[y]]}

EDIT: Algoritma serakah tidak bekerja untuk h[299792458, 1000000]. Saya telah mengembalikan jumlah byte ke 195, sementara saya memperbaiki algoritma saya sekali lagi. Memperbaikinya hanya agar jumlah byte naik ke 203. Sigh

Sedang dibangun: Program ini menggunakan algoritma serakah untuk menemukan leluhur yang sama x[0,j]==y[0,j](catatan: mungkin ada beberapa leluhur yang sama). Algoritma ini didasarkan sangat longgar pada pencarian nenek moyang rekursif Ell . Bagian pertama dari instruksi yang dihasilkan adalah bagaimana mencapai nenek moyang yang sama, dan yang kedua adalah berdasarkan y y[j..-1].

Catatan: di a[n]sini mengembalikan penomoran bijektif base-3 menggunakan digit 2,1,0sebagai ganti 1,2,3.

Sebagai contoh, mari kita jalankan melalui f[59,17]atau f[[2,0,2,1],[2,1,1]]. Di sini j == 1,. Untuk sampai ke sana x[0,j], kita pergi 0atau NW. Lalu, untuk sampai ke y, pergi [1,1]atauSW SW

a=->n{n<1?[]:a[~-n/3]+[-n%3]}
h=->m,n{x=a[m];y=a[n];c=[];j=x.size
(j=x.uniq.map{|m|k=x.rindex(m);x[0..k]==y[0..k]?j:k}.min
c<<%w[NW NE S][x[j]];x=x[0,j])until x==y[0,j]
c+y[j..-1].map{|m|%w[SE SW N][m]}}
Sherlock9
sumber
45

Python 2, 208 205 200 byte

A=lambda n:n and A(~-n/3)+[-n%3]or[]
f=lambda x,y:f(A(x),A(y))if x<[]else["SSNEW"[m::3]for m in
y[len(x):]]if x==y[:len(x)]else min([["NNSWE"[m::3]]+f(x[:~x[::-1].index(m)],y)for
m in set(x)],key=len)

Sebuah fungsi,, fmengambil sepasang nomor simpul, dan mengembalikan jalur terpendek sebagai daftar string.

Penjelasan

Kami mulai dengan menggunakan skema pengalamatan yang berbeda untuk segitiga; alamat setiap segitiga adalah string, didefinisikan sebagai berikut:

  • Alamat dari segitiga pusat adalah string kosong.

  • Alamat dari utara, selatan-barat, dan anak-anak selatan-timur dari setiap segitiga terbentuk menambahkan 0, 1, dan 2, masing-masing, ke alamat segitiga.

Pada dasarnya, alamat setiap segitiga mengkodekan jalur (terpendek) dari segitiga pusat ke sana. Hal pertama yang dilakukan oleh program kami adalah menerjemahkan angka segitiga input ke alamat yang sesuai.

Gambar 1

Klik gambar untuk versi yang lebih besar.

Kemungkinan gerakan di setiap segitiga mudah ditentukan dari alamat:

  • Untuk pindah ke utara, selatan-barat, dan anak-anak selatan-timur, kita hanya append 0, 1dan 2, masing-masing, ke alamat.

  • Untuk pindah ke selatan, utara-timur, dan utara-barat nenek moyang, kita menemukan yang terakhir (paling kanan) terjadinya 0, 1dan 2, masing-masing, dan trim alamat ke kiri itu. Jika tidak ada 0,, 1atau 2di alamat, maka leluhur yang sesuai tidak ada. Misalnya, untuk pindah ke nenek moyang utara-barat dari 112(yaitu, induknya), kita menemukan kejadian terakhir 2di 112, yang merupakan karakter terakhir, dan trim alamat ke kiri itu, memberikan kita 11; untuk pindah ke nenek moyang utara-timur, kita menemukan kejadian terakhir 1di 112, yang merupakan karakter kedua, dan trim alamat ke kiri itu, memberikan kita 1; Namun, 112tidak memiliki leluhur selatan, karena tidak ada0 di alamatnya.

Catat beberapa hal tentang sepasang alamat, xdan y:

  • Jika xadalah substring awal y, maka yadalah keturunan x, dan karena itu jalur terpendek dari xke yhanya mengikuti sesuai anak masing-masing segitiga antara xdan y; dengan kata lain, kita bisa mengganti setiap 0, 1dan 2di y[len(x):]dengan N, SW, dan SEmasing-masing.

  • Kalau tidak, biarkan imenjadi indeks ketidakcocokan pertama antara xdan y. Tidak ada jalan dari xke yyang tidak melewati x[:i](yang sama dengan y[:i]), yaitu leluhur bersama pertama dari xdan y. Karenanya, jalan apa pun dari xke yharus tiba di x[:i], atau salah satu leluhurnya, sebut saja segitiga ini z, dan kemudian lanjutkan y. Untuk tiba dari xke z, kita mengikuti leluhur seperti dijelaskan di atas. Jalur terpendek dari zke ydiberikan oleh titik peluru sebelumnya.

Jika xmerupakan substring awal y, maka jalur terpendek dari xke ymudah diberikan oleh titik peluru pertama di atas. Jika tidak, kita membiarkan jmenjadi yang terkecil dari indeks kejadian terakhir 0, 1dan 2di x. Jika jlebih besar dari, atau sama dengan, indeks dari ketidakcocokan pertama antara xdan y, i, kita hanya menambahkan sesuai bergerak ( S, NE, atau NW, masing-masing) ke jalan, trim xke kiri dari j, dan terus. Hal mendapatkan rumit jika jkurang dari i, sejak saat itu kami mungkin bisa ytercepat dengan naik ke nenek moyang x[:j]langsung dan turun sampai key, atau kita mungkin dapat mencapai leluhur bersama yang berbeda xdan yyang lebih dekat ydengan naik ke leluhur yang berbeda dari xkanan i, dan pergi dari sana ke yang ylebih cepat. Misalnya, untuk beralih dari 1222ke 1, jalur terpendek adalah pertama naik ke segitiga pusat (yang alamatnya adalah string kosong), dan kemudian turun ke 1, yaitu, langkah pertama membawa kita ke kiri dari titik ketidakcocokan. Namun, untuk beralih dari 1222ke 12, jalan terpendek adalah naik ke 122, dan kemudian ke 12, yaitu, langkah pertama membuat kita ke kanan titik ketidakcocokan.

Jadi, bagaimana kita menemukan jalan terpendek? Program "resmi" menggunakan pendekatan brute-force-ish, mencoba semua gerakan yang mungkin dilakukan kepada leluhur kapan pun xbukan merupakan substring awal y. Ini tidak seburuk kedengarannya! Ini memecahkan semua kasus uji, dikombinasikan, dalam satu atau dua detik.

Tetapi, sekali lagi, kita dapat melakukan jauh lebih baik: Jika ada lebih dari satu leluhur yang dapat dijangkau secara langsung di sebelah kiri titik ketidaksesuaian, kita hanya perlu menguji yang paling kanan, dan jika ada lebih dari satu leluhur yang dapat dijangkau langsung ke tepat dari titik ketidakcocokan, kita hanya perlu menguji yang paling kiri. Ini menghasilkan algoritma waktu linier, wrt panjang x(yaitu, kedalaman segitiga sumber, atau waktu yang sebanding dengan logaritma nomor sumber segitiga), yang memperbesar bahkan melalui kasus uji yang jauh lebih besar. Program berikut mengimplementasikan algoritma ini, setidaknya pada intinya — karena golf, kompleksitasnya, pada kenyataannya, lebih buruk daripada linear, tetapi masih sangat cepat.

Python 2, 271 266 261 byte

def f(x,y):
 exec"g=f;f=[]\nwhile y:f=[-y%3]+f;y=~-y/3\ny=x;"*2;G=["SSNEW"[n::3]for
n in g];P=G+f;p=[];s=0
 while f[s:]:
    i=len(f)+~max(map(f[::-1].index,f[s:]));m=["NNSWE"[f[i]::3]]
    if f[:i]==g[:i]:P=min(p+m+G[i:],P,key=len);s=i+1
    else:p+=m;f=f[:i]
 return P

Perhatikan bahwa, tidak seperti versi yang lebih pendek, versi ini ditulis khusus untuk tidak menggunakan rekursi dalam konversi nilai input ke alamat yang sesuai, sehingga dapat menangani nilai yang sangat besar tanpa meluap tumpukan.

Hasil

Cuplikan berikut dapat digunakan untuk menjalankan tes, untuk versi mana pun, dan menghasilkan hasilnya:

def test(x, y, length):
    path = f(x, y)
    print "%10d %10d  =>  %2d: %s" % (x, y, len(path), " ".join(path))
    assert len(path) == length

#         x           y        Length
test(          0,          40,    4   )
test(         66,          67,    5   )
test(         30,           2,    2   )
test(         93,           2,    2   )
test(        120,          61,    8   )
test( 1493682877,           0,    4   )
test(          0,   368460408,   18   )
test( 1371432130,     1242824,   17   )
test(     520174,  1675046339,   23   )
test(  312602548,   940907702,   19   )
test( 1238153746,  1371016873,   22   )
test(  547211529,  1386725128,   23   )
test( 1162261466,  1743392199,   38   )

Versi Golf

         0         40  =>   4: N N N N
        66         67  =>   5: S SW N N N
        30          2  =>   2: NE SW
        93          2  =>   2: NE SW
       120         61  =>   8: NW NW NW NW N SE SW N
1493682877          0  =>   4: S S NW NW
         0  368460408  =>  18: SW SW N N SW SW SE SW SW N SE N N SW SW N SE SE
1371432130    1242824  =>  17: NW NW NE NW N SE SW SW SW SE SE SW N N N N SW
    520174 1675046339  =>  23: NE NE NE NE SE SE SW SW N SE N SW N SW SE N N N N SE SE SW SW
 312602548  940907702  =>  19: NE NW S SW N N SW SE SE SE SW SE N N SW SE SE SE SW
1238153746 1371016873  =>  22: NE NE NE SE N N SW N N SW N SE SE SW N SW N N SE N SE N
 547211529 1386725128  =>  23: S S S S NW N N SE N SW N SE SW SE SW N SE SE N SE SW SW N
1162261466 1743392199  =>  38: NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE

Versi Efisien

         0         40  =>   4: N N N N
        66         67  =>   5: S SW N N N
        30          2  =>   2: NW NW
        93          2  =>   2: NE SW
       120         61  =>   8: NW NW NW NW N SE SW N
1493682877          0  =>   4: NE S NW NW
         0  368460408  =>  18: SW SW N N SW SW SE SW SW N SE N N SW SW N SE SE
1371432130    1242824  =>  17: NW NW NE NW N SE SW SW SW SE SE SW N N N N SW
    520174 1675046339  =>  23: NE NW NE NE SE SE SW SW N SE N SW N SW SE N N N N SE SE SW SW
 312602548  940907702  =>  19: NE NW S SW N N SW SE SE SE SW SE N N SW SE SE SE SW
1238153746 1371016873  =>  22: NE NE NE SE N N SW N N SW N SE SE SW N SW N N SE N SE N
 547211529 1386725128  =>  23: S S S S NW N N SE N SW N SE SW SE SW N SE SE N SE SW SW N
1162261466 1743392199  =>  38: NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE NE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE SE
Elo
sumber
6
Sialan itu cepat. Saya tidak bisa memberi tahu Anda betapa bahagianya itu membuat saya setiap kali saya membuat Anda menjawab salah satu tantangan saya. :)
Martin Ender
2
@ MartinBüttner Terima kasih, itu pujian yang luar biasa! FWIW, saya sangat menikmati menyelesaikan tantangan Anda. Saya mungkin, atau mungkin tidak, sudah mulai mengerjakan yang ini ketika masih di dalam kotak pasir ... :)
Ell
2
Skema pengalamatannya brilian. Ini luar biasa.
BrainSteel
1
@BrainSteel Hal pertama yang terjadi pada saya adalah mencoba skema pengalamatan itu, tetapi untuk melihat semuanya dikonseptualisasikan, diimplementasikan, dan ditulis dalam waktu kurang dari satu jam adalah luar biasa. +1
Level River St
1
@Zymus Saya tidak yakin saya mengikuti, tetapi jika Anda mengacu pada gambar, itu tidak seharusnya cocok dengan OP — ini adalah skema pengalamatan yang berbeda, seperti dijelaskan dalam posting.,
Ell
3

APL (Dyalog Unicode) , 144 132 129 118 133 132 130 124 117 byte SBCS

Terima kasih banyak kepada Ven dan ngn atas bantuan mereka dalam bermain golf di The APL Orchard , tempat yang bagus untuk belajar bahasa APL. ⎕IO←0. Saran golf diterima.

Sunting: -12 bytes berkat Ven dan ngn dengan mengubah cara ndidefinisikan dan beralih dari pengindeksan 1 ke pengindeksan. -3 karena memperbaiki bug di mana tidak semuanya dialihkan ke pengindeksan 0. -11 byte karena mengubah cara Pdan Qdidefinisikan. +15 byte karena memperbaiki masalah di mana algoritma saya salah dengan banyak terima kasih kepada ngn untuk bantuan dengan mencari s[⊃⍋|M-s]bagian. -2 byte dari mengatur ulang metode untuk menemukan jalur backtracking dan +1 byte untuk memperbaiki bug. -2 byte terima kasih kepada Adám untuk mengatur ulang definisi I. -6 byte terima kasih kepada Ngn dari mengatur ulang definisi 'S' 'NE' 'NW' 'N' 'SW' 'SE'dan dari mengatur ulang bagaimana tdidefinisikan (itu bukan lagi variabel yang terpisah). -7 byte berkat ngn dari golf bagaimana sdidefinisikan.

{M←⊃⍸≠⌿↑1+P Q←⍵{(⍵/3)⊤⍺-+/3*⍳⍵}¨⌊31+⍵×2⋄(∪¨↓6 2'SSNENWNNSWSE')[P[I],3+Q↓⍨⊃⌽I←⍬{M≥≢⍵:⍺⋄(⍺∘,∇↑∘⍵)s[⊃⍋|M-s←⌽⊢.⊢⌸⍵]}P]}

Cobalah online!

Penjelasan bug dalam algoritma

Masalah mendasarnya adalah saya pergi berpikir bahwa jalan terpendek melewati langsung leluhur bersama, dan pada kenyataannya, tidak bisa melalui leluhur leluhur yang sama. Ini tidak benar karena contoh berikut akan menunjukkan.

Dari 66 hingga 5

66  0 2 2 2  0 2 2 2
5   0 1      0 1
       common ancestor

The two ancestors of 0 2 2 2 are:
0 2 2
(empty)

(empty) has the shorter path back to 0 1 as it only needs two forward moves,
while 0 2 2 requires two more backtracks and one more forward move.

Dari 299792458 hingga 45687

299792458  0 2 1 1 0 1 1 2 1 1 1 2 1 0 2 2 2 0
45687      0 2 1 1 0 1 1 1 2 2
                          common ancestor

The three ancestors of 299792458 are:
0 2 1 1 0 1 1 2 1 1 1 2 1 0 2 2 2
0 2 1 1 0 1 1 2 1 1 1 2             choose this one
0 2 1 1 0 1 1 2 1 1 1 2 1 0 2 2

And the three ancestors of 0 2 1 1 0 1 1 2 1 1 1 2 are:
0 2 1 1
0 2 1 1 0 1 1 2 1 1
0 2 1 1 0 1 1 2 1 1 1

0 2 1 1 0 1 1 1 2 2     45687 for reference
              common ancestor

While it seems like `0 2 1 1` is the shorter path,
it actually results in a path that is 8 steps long
(2 backtracks, 6 forward steps to 45687).

Meanwhile, `0 2 1 1 0 1 1 2 1 1` is at an equal distance
to the common ancestor and has the following ancestors:
0 2 1 1
0 2 1 1 0 1 1 2 1
0 2 1 1 0 1 1

0 2 1 1 0 1 1 1 2 2     45687 for reference
              common ancestor

Clearly, this is the superior path, as with three backtracks, we have reached
the point of the common ancestor. With 3 backtracks and 3 forward moves,
we have a path that is 6 steps long.

Penjelasan kode

                         should be an array of 2 integers, x y
SierpinskiPath←{⎕IO0   0-indexing
         P Q←{...}¨⍵   First, the bijective base-3 numeration of x and y
    P Q←{
        n←⌊31+⍵×2   The number of digits in the numeration
        z←+/3*⍳⍵     The number of numerations with  n digits
        (n/3)⊤⍵-z    And a simple decode  (base conversion) of ⍵-z
    }¨⍵              gets us our numerations, our paths

    A←↑1+P Q       We turn (1+P Q) into an 2-by-longest-path-length array 
                    pads with 0s and our alphabet also uses 0s
                   So we add 1 first to avoid erroneous common ancestor matches
    Common←⊃⍸≠⌿A   We find the length of the common ancestor, Common

         I←⍬{...}P   Now we get the shortest backtracking path from P
    I←⍬{
        Common=≢⍵:⍺        If P is shorter than Common, return our backtrack path
        s←⌽⊢.⊢⌸⍵           Get the indices of the most recent N SW SE
        ts[⊃⍋|Common-s]   and keep the index that is closest to Common
                           and favoring the ancestors to the right of
                           Common in a tiebreaker (which is why we reverse ⊢.⊢⌸⍵)
        (⍺,t)∇t↑⍵          Then repeat this with each new index to backtrack
    }P                     and the path left to backtrack through

    BacktrackP[I]    We get our backtrack directions
    Forward←(⊃⌽I)↓Q   and our forward moves to Q
                      starting from the appropriate ancestor
    (∪¨↓6 2'SSNENWNNSWSE')[Backtrack,Forward]     'S' 'NE' 'NW' 'N' 'SW' 'SE'
}                     and return those directions

Solusi alternatif menggunakan Dyalog Extended dan dfns

Jika kita menggunakan ⎕CY 'dfns''s adicfungsi, menerapkan kami bijective dasar-n penomoran (yang merupakan inspirasi bagi saya gunakan versi) untuk byte jauh lebih sedikit. Beralih ke Dyalog Extended juga menghemat banyak byte dan jadi di sinilah kita. Terima kasih banyak kepada Adám atas bantuannya dalam bermain golf ini. Selamat datang saran bermain golf!

Edit: -8 byte karena mengubah cara Pdan Qdidefinisikan. -14 byte karena beralih ke Dyalog Extended. -2 karena menggunakan program lengkap untuk menghapus tanda kurung dfn {}. +17 byte karena memperbaiki masalah di mana algoritma saya salah dengan banyak terima kasih kepada ngn untuk bantuan dengan mencari s[⊃⍋|M-s]bagian. +1 byte untuk memperbaiki bug. -2 byte terima kasih kepada Adám dari mengatur ulang definisi I dan -1 byte dari mengingat untuk meletakkan golf saya di kedua solusi . -3 byte berkat ngn dengan mengatur ulang generasi arah mata angin, +1 byte dari mengoreksi golf buggy, dan -3 byte berkat ngn dengan mengatur ulang cara tdidefinisikan (tidak lagi merupakan variabel terpisah). -7 byte berkat ngn dengan mengatur ulang cara sdidefinisikan.

APL (Dyalog Extended) , 123 115 101 99 116 117 114 109 102 byte

M←⊃⍸≠⌿↑1+P Q←(⍳3)∘⌂adic¨⎕⋄(∪¨↓6 2'SSNENWNNSWSE')[P[I],3+Q↓⍨⊃⌽I←⍬{M≥≢⍵:⍺⋄(⍺∘,∇↑∘⍵){⍵[⊃⍋|M-⍵]}⌽⊢.⊢⌸⍵}P]

Cobalah online!

Sherlock9
sumber
Untuk 66 dan 1, ini tidak menemukan cara terpendek melalui 0.
Christian Sievers
@ChristianSievers Anda benar sekali dan saya belum yakin bagaimana cara memperbaikinya. Terima kasih telah memberi tahu saya.
Sherlock9