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:
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+2
dan 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
,SW
danSE
. Misalnya jika kita saat ini simpul2
, ini akan menyebabkan node7
,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
,NE
danNW
. Misal jika kita saat ini di node31
,S
akan mengarah ke10
,NE
akan menjadi tidak valid danNW
akan mengarah ke0
.
Tantangan
Diberi dua bilangan bulat non-negatif x
dan y
, cari jalur terpendek dari x
ke 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 kode-golf 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