Anda harus menulis sebuah program atau fungsi yang menggunakan integer non-negatif N
sebagai input dan output atau mengembalikan dua integer (negatif, nol atau positif) X
dan Y
.
Bilangan bulat dimaksudkan dalam arti matematika karena ada banyak dari mereka.
Fungsi yang diimplementasikan harus bijective . Ini berarti bahwa untuk setiap pasangan harus N
mengeluarkan X
Y
pasangan yang berbeda dan setiap X
Y
pasangan harus dikeluarkan untuk beberapa input N
yaitu semua pasangan berikut harus dikeluarkan untuk beberapa N
:
...
┌─────┬─────┬────┬────┬────┐
│-2 -2│-2 -1│-2 0│-2 1│-2 2│
├─────┼─────┼────┼────┼────┤
│-1 -2│-1 -1│-1 0│-1 1│-1 2│
├─────┼─────┼────┼────┼────┤
... │0 -2 │0 -1 │0 0 │0 1 │0 2 │ ...
├─────┼─────┼────┼────┼────┤
│1 -2 │1 -1 │1 0 │1 1 │1 2 │
├─────┼─────┼────┼────┼────┤
│2 -2 │2 -1 │2 0 │2 1 │2 2 │
└─────┴─────┴────┴────┴────┘
...
Perhatikan bahwa U V
dan V U
adalah pasangan yang berbeda jika U!=V
.
Detail
- Jika bahasa Anda tidak mendukung bilangan bulat besar yang sewenang-wenang, itu bagus, tetapi algoritme Anda harus bekerja dengan tipe data bilangan bulat besar yang sewenang-wenang. Kode Anda setidaknya harus mendukung nilai input
2^31-1
. - Jika Anda memilih untuk mencetak atau mengembalikan output sebagai string, tidak ada tanda
0
atau+
tanda-tanda yang diizinkan. Kalau tidak, representasi integer standar bahasa Anda baik-baik saja.
Contoh
Jika tugasnya adalah membuat fungsi bijective mengambil integer non-negatif N
dan output satu integer X
solusi bisa menjadi fungsi
if (input mod 2 == 0) return N/2 else return -(N+1)/2
,
diimplementasikan dalam beberapa bahasa. Fungsi ini kembali X = 0 -1 1 -2 2...
untuk N = 0 1 2 3 4...
.
10=>11 12, 9=>10 11
apakah ini tidak valid karena 11 diulang?Jawaban:
Pyth, 15
Cobalah online.
Terjemahan Python:
atau secara iteratif:
di mana
binlist
mengkonversi nomor ke daftar digit sepertibinlist(4) = [1,0,0]
.Jadi, bagaimana cara kerjanya? Ini menginterpretasikan digit biner dari angka sebagai dua angka yang disisipkan dalam basis negatif dua seperti dalam solusi Python saya .n
Angka biner sesuai dengan pasangan ( x , y ) = ( b 0 - 2 b 2 + 4 b 4 - 8 b 6 + ⋯ , b 1 - 2 b 3 + 4 b 5 - 8 b 7 + ⋯ )
Jika kita belum memproses digit terakhir dari n , kita akan memiliki semua indeks lebih tinggi dengan $ 1 $, n ′ = ... b 5 b 4 b 3 b 2 b 1 yang sesuai dengan pasangan ( x ′ , y ′ ) = ( b 1 - 2 b 3 + 4 b 5 - 8 b 7 + ⋯ , b 2 - 2 b 4b0 n
Kami kemudian dapat mengekspresikan nilai-nilai baru setelah dibaca dalam hal nilai-nilai lamab0
Jadi, dengan berulang kali melakukan transformasi pada setiap bit b dari n berturut-turut , kami membangun titik ( x , y ) yang berasal dari mengekstraksi digit-digitnya.(x,y)→(b−2y,x) b n (x,y)
sumber
CJam,
242221 byteOtak saya kesulitan memahami matematika yang digunakan solusi lain. Tapi otak saya pasti mengerti biner, jadi inilah soultion yang didasarkan pada manipulasi bit!
Cobalah online.
Penjelasan
Pendekatan ini memperlakukan input sebagai dua nilai biner yang disisipkan, satu untuk setiap nomor output. Semua kecuali bit paling signifikan dari masing-masing mengkodekan sebuah magnitudo, dan bit paling signifikan menandakan apakah akan mengambil komplemen bitwise dari magnitudo ini. Dalam implementasi ini, bit yang diposisikan ganjil sesuai dengan nomor output pertama (dan bit yang diposisikan sama dengan yang kedua) dan LSB
0
sinyal untuk mengambil komplemen.Sebagai contoh, diberi input
73
, uninterleaving representasi biner dari1001001b
menghasilkan0 1|0
(bit posisi aneh) dan1 0 0|1
(bit posisi genap). Nilai pertama memiliki besaran01b = 1
dan harus dilengkapi dengan nilai akhir~1 = -2
, dan nilai kedua memiliki besarnya100b = 4
dan tidak harus dilengkapi.Demonstrasi informal tentang kebenaran
Saya membuat program pengujian yang menempatkan setiap input dari nol ke angka yang ditentukan pengguna dikurangi satu di lokasi outputnya pada kisi 2D. Anda dapat mencobanya secara online juga. Berikut ini adalah output dari program ini yang menunjukkan bagaimana algoritma memetakan
0-99
:Pola isian terlihat sedikit aneh, tetapi sebenarnya bersifat kata sifat! Dengan masing-masing kekuatan berturut-turut dari 4, itu mengisi persegi dengan dua kali lipat panjang sisi sebelumnya. Misalnya, inilah cara algoritma memetakan
0-15
:Ini membentuk kotak 4x4 di tengah-tengah kotak 8x8
0-63
:Yang membentuk kotak 8x8 di tengah kotak 16x16
0-255
:sumber
li4b2fmd2/
alih-alih0li2b+W%2/W%
. Ini memberikan bilangan bulat yang sama, tetapi dalam urutan terbalik.Python 2, 49
Sunting: Ditingkatkan ke 49 dengan menggunakan rekursi satu langkah yang lebih baik untuk basis -2.
Inilah versi Pyth yang digunakan
reduce
.Sunting: Ditingkatkan ke 52 dengan beralih ke basis -2 dari terner seimbang .
Python 2, 52
Python 2, 54
Ini menggunakan interleaving digit seperti solusi Runer112 , tetapi dengan biner seimbang daripada biner yang ditandatangani. Python tidak memiliki konversi basis bawaan, jadi kode mengimplementasikannya secara rekursif.
Fungsi helper
h
(dengan3
menggantikan9
) mengambil angka alami dan mengubahnya dari ternary ke terner seimbang dengan penggantian digitJadi, misalnya, 19, yang merupakan pangkalan 201, menjadi (-1) (0) (+ 1) dalam terner seimbang, yaitu (-1) * 3 ^ 2 + (0) * 3 ^ 1 + (+ 1) * 3 ^ 0 = -8.
Terner seimbang cukup untuk menyandikan setiap bilangan bulat, sehingga memberikan pemetaan dari bilangan asli ke bilangan bulat.
Untuk memetakan ke pasangan bilangan bulat, kami interleave digit
n
. Untuk melakukannya, kita harush
melihat setiap digit lainnya dengan melakukann/9
sebagai langkah rekursif daripadan/3
. Kemudian, untuk satu koordinat, kami bergesern
dengan pembagian lantai dengan3
.Berikut adalah 81 keluaran pertama, yang mencakup wilayah [-4,4] ^ 2.
Pengodean alternatif dengan kuartal-imajiner ternyata lebih lama, meskipun sangat cantik.
Python 2, 63
Dalam bahasa dengan penanganan konversi kompleks yang kurang kikuk, ini mungkin akan menjadi pendekatan yang lebih baik. Jika kita bisa menampilkan bilangan kompleks, kita bisa melakukan
Python 2, 38
sumber
L&b-%b2*2y/b4,yQy/Q2
panjangnya hanya 20 byte.Python 2, 98 byte
Mari kita mulai dengan pendekatan sederhana:
Itu hanya membentuk
N
unit spiral persegi panjang pada grid 2d, mulai dari asal, dan mengembalikan koordinat titik terakhir.Fungsi ini bersifat obyektif karena:
Spiral terlihat seperti ini (kecuali mulai dari 0 daripada 1):
sumber
0**0 == 1
dengan python, jadi sama saja denganif a == 0: a = b/2
a=a or b/2
lebih pendek0^0=1
dalam semua matematika, bukan hanya python.0**0
sebenarnya adalah bentuk tak tentu dalam matematikadc, 49
Ini dimulai dengan mengatur bilangan bulat non-negatif pada kisi sebagai berikut:
Perhatikan bahwa bagaimana posisi kisi diisi secara diagonal dengan kenaikan N. Perhatikan garis Y = 0 berisi urutan bilangan segitiga, yang diberikan oleh
N = X(X+1)/2
. Ini adalah persamaan kuadrat yang diselesaikan dengan menggunakan rumus normal, hanya menggunakan + ve root, sehingga kita dapat menentukan X dari N ketika Y = 0. Berikutnya adalah beberapa pengocokan aritmatika sederhana untuk memberikan {X, Y} unik untuk setiap N.Ini memberikan kualitas bijective yang diperlukan, tetapi X dan Y hanya non-negatif, tetapi pertanyaannya membutuhkan semua bilangan bulat yang mungkin. Jadi X dan Y dipetakan menggunakan
((t+1)/2)*((t+1)~2*2-1)
untuk memberikan semua kemungkinan integer.dc
memiliki angka presisi yang berubah-ubah, sehingga rentang input2^31-1
tidak menjadi masalah. Perhatikan juga bahwa presisi standar adalah 0 angka desimal, dansqrt()
dan/
bulatkan yang merupakan perilaku yang diperlukan di sini.Keluaran:
sumber
Matlab, 54 byte
Kuncinya di sini adalah
spiral
, ini menciptakan matriks spiral dari ukuran yang sewenang-wenang.kembali
spiral
sumber
Haskell,
7874 byteUji coba:
Cara kerjanya: daftarkan semua pasangan di kuadran pertama dengan urutan sebagai berikut
mirror setiap titik ke kuadran lain untuk membuat daftar 4 daftar elemen. Gabungkan semuanya menjadi satu daftar dan ambil
n
elemen th.Sunting: fungsi tidak perlu nama, matematika yang disusun ulang. ekspresi.
sumber
do
-notation: Coba online!Haskell , 50 byte
Cobalah online atau coba dengan kebalikannya!
Tidak disatukan
Penjelasan
(!)
l
xCounter
y
Perhatikan bahwa fungsi aktual
f
(ntoN2
) menambah input sebelum memulai dengan prosedur.sumber
05AB1E , 35 byte
Cobalah online! atau sebagai Test suite
Penjelasan
Mempertimbangkan
sumber
Mathematica, 46
Urutkan vektor norma mereka, lalu ambil yang
n
ke-1.sumber
JavaScript, 166
168byte / karakterPendekatan baru menggunakan spiral persegi panjang seperti yang digunakan orang lain.
Saya menggunakan jawaban ini pada Math.SE, menerjemahkannya ke JS dan mengompresnya menggunakan UglifyJS .
Pendekatan ini tidak menggunakan loop apa pun juga tidak menciptakan spiral dengan cara apa pun.
Perbarui: Disimpan 2 karakter dengan menyimpan
Math
dalamb
.t-=1
t+=4
sumber