Sebagian besar komputer menyimpan bilangan bulat dalam biner, tetapi mengeluarkannya dalam bentuk desimal. Namun, desimal hanyalah satu representasi, kami kebetulan merasa nyaman.
Tantangan ini adalah menulis beberapa kode untuk menghasilkan nilai integer dalam desimal shortlex .
Apa itu?
http://en.wikipedia.org/wiki/Shortlex_order
Shortlex mengambil panjang urutan angka sebagai penanda utama nilai. Urutannya, mulai dari string kosong yang mewakili nol, adalah ...
ε,0,1,...,8,9,00,01,...98,99,000,001,...,998,999,0000,...
(Pikirkan kolom Excel, tetapi hanya menggunakan angka desimal.)
Tulis program atau fungsi yang menerima integer dan mengembalikan string yang sesuai dengan representasi shortlex-desimal integer seperti yang dijelaskan di atas.
Nilai tes:
0 → "" (string kosong)
1 → "0"
10 → "9"
11 → "00"
42 → "31"
100 → "89"
800 → "689"
1060 → "949"
10270 → "9159"
100501 → "89390"
19, 20, 21, 22
dalam peta desimal menjadi08, 09, 10, 11
dalam waktu singkat. Itu sebabnya saya bingung dulu100 -> 89
!Jawaban:
JavaScript (ES6) 42
74Tes di konsol FireFox
Keluaran
Bagaimana saya memikirkan hal ini?
Dengan jumlah digit yang tetap, urutan output naik, sehingga ada delta tetap antara input dan output. Lihat:
Tetapi 0s terkemuka sulit untuk dikelola, jadi saya punya trik standar, tambahkan digit pertama dan modulo kerja (yaitu, potong digit pertama dalam output). Lalu -1-> +9, -11 -> +89, -111 -> +889 dan seterusnya.
Langkah terakhir: Saya tidak peduli apa angka pertama, jadi tidak perlu memeriksa apakah nomor iinput <atau> dari 111 ... (jujur saya menemukan ini dengan coba-coba)
Uji
sumber
n-~(n+'')
bukan hanyan-~n
?(n+'').replace(...)
, ganti bekerja pada string, bukan angka.Marbelous
177173170Ini hanya berfungsi untuk nilai di bawah 256 karena Marbelous adalah bahasa 8 bit.
Bagaimana itu bekerja
Marbelous adalah bahasa 2D dengan nilai-nilai yang diwakili oleh kelereng 8 bit yang jatuh satu sel pada setiap centang kecuali beberapa perangkat mencegahnya jatuh. Program Marbelous ini terdiri dari 3 papan; mari kita mulai dengan yang termudah:
:O
adalah nama papan (tepatnya, O adalah nama dan: memberi tahu yang ditafsirkan bahwa baris ini adalah nama. Dengan memberi papan nama, papan lain dapat memanggil mereka}0
adalah perangkat input, ini dapat dilihat sebagai argumen fungsi ini. Sel ini akan digantikan oleh marmer input (nilai) ketika fungsi dipanggil.+Z
Menambahkan 35 ke marmer yang melewatinya dan membiarkannya jatuh. Melakukan+C
hal yang sama tetapi hanya menambahkan 12.{0
adalah sel output , ketika marmer mencapai sel ini, fungsi akan keluar dan mengembalikan nilai pada perangkat output ini.Jadi, secara keseluruhan, board ini mengambil satu nilai dan kemudian menambahkan 47 nilai untuknya. Bagi kami, ini berarti mengubah angka satu digit menjadi kode ascii dari digit -1 (ini tentu saja juga berlaku untuk 10).
Papan ini terlihat sedikit lebih rumit. Anda harus dapat mengidentifikasi
:I
sebagai nama board dan telah melihat beberapa perangkat input dan output. Anda akan melihat bahwa kami memiliki dua perangkat input yang berbeda,}0
dan}1
. Ini berarti fungsi ini membutuhkan 2 input. Anda juga akan melihat bahwa ada dua contoh}1
perangkat. Saat memanggil fungsi, kedua sel ini akan berisi nilai yang sama. Perangkat}0
input langsung di atas\/
perangkat, ini bertindak sebagai tempat sampah dan menghilangkan marmer yang jatuh di atasnya segera.Mari kita lihat apa yang terjadi pada salah satu kelereng yang diletakkan di papan oleh
}1
perangkat input:Ini akan jatuh pada centang pertama dan tekan
=9
perangkat. Ini membandingkan nilai dari marmer sampai 9 dan membiarkan marmer itu jatuh jika pernyataannya=9
dievaluasi. Marmer didorong ke kanan jika tidak.&0
dan&1
merupakan sinkronisasi. Mereka berpegang pada kelereng yang jatuh ke mereka sampai semua&n
sinkronisasi lainnya diisi juga. Seperti yang dapat Anda harapkan, ini akan memicu perilaku yang berbeda pada beberapa bagian lain dari papan.Jika saya memberi tahu Anda bahwa itu
++
adalah incrementor, Anda seharusnya sudah dapat mengetahui apa yang akan diisi oleh berbagai sinkronisasi. Kiri&1
akan berisi nilai input}1
+ 1, di&0
sebelahnya akan berisi 0 (00
adalah bahasa literal, diwakili dalam heksadesimal). Yang kedua&1
akan berisi nilai 1 dan hak&0
terisi denganF7
, yang mengurangi 9 dari nilai karena penambahan di Marbelous adalah modulo 256.//
adalah alat deflektor, yang mendorong marmer ke kiri alih-alih membiarkannya jatuh.Menyatukan semua ini memberi Anda ini: jika marmer di
}1
angka 9,&0
sinkronisasi akan terisi. Ini akan menyebabkan nilai 0 jatuh ke dalam{0
output danF7
(atau -9) ke dalam{1
output. Jika}1
bukan 9,{0
akan diisi dengan}1
+1 dan{0
akan berisi 1. Ada juga{>
perangkat, ini adalah output khusus yang mengeluarkan marmer di sebelah papan sebagai ganti dari di bawahnya. Ini akan diisi}1
jika sama dengan 9.Oke, sekarang untuk yang besar. Papan ini tidak memiliki nama eksplisit, karena ini adalah papan utama file. Nama tersiratnya adalah
Mb
. Anda harus dapat mengenali beberapa sel. Ada perangkat input, beberapa literal bahasa (00
danFF
). Ada beberapa sinkronisasi dan ada deflektor. mari kita selangkah demi selangkah demi selangkah.Jadi nilai input (input baris perintah karena ini adalah papan utama) dimulai pada sel kedua dari atas di mana
}0
berada. Ini akan jatuh dan mencapai>0
perangkat, yang merupakan perangkat pembanding lain. setiap marmer yang lebih besar dari 0 jatuh, setiap marmer lainnya terdorong ke kanan. (Karena variabel Marbelous tidak ditandatangani, hanya tepat 0 yang akan didorong ke kanan). Marmer bernilai nol ini kemudian akan mengenai@6
perangkat. Ini adalah portal dan mengangkut marmer ke portal terkait lainnya, dalam hal ini tepat di atasnya. Marmer 0 kemudian akan mencapai&0
sinkronisasi dan memicu beberapa hal di tempat lain.Jika marmer bukan 0, jatuh, dibelokkan ke kanan oleh
\\
hit--
yang menurunkannya satu dan kemudian jatuh/\
, cloner. Perangkat ini mengambil marmer dan mengeluarkan satu salinannya ke kanan dan satu lagi ke kiri. Yang kiri akan dibawa ke atas ke yang lain di@0
mana marmer akan melalui urutan yang sama lagi. Yang kiri akan dibawa ke tempat lain. Ini memberi kita satu loop, yang mengurangi input baris perintah satu kali per loop dan memicu beberapa perilaku pada setiap loop hingga mencapai 0. Kemudian memicu beberapa perilaku lainnya.Mari kita lihat apa yang terjadi dengan marmer yang didorong ke dalamnya
@4
pada setiap loop.Ada 3 literal bahasa di sini (
FF
), yang akan segera jatuh ke portal. Portal-portal ini akan membawanya ke tigaII
perangkat.II
merujuk ke papan yang:I
kami definisikan lebih jauh di bawah file. Karena:I
memiliki 2 perangkat input yang berbeda, representasi di papan lain harus selebar 2 sel. Karena kami memiliki 6 sel yang mengandungII
, kami dapat memberi tahu kami memiliki 3 contoh fungsi ini di papan tulis.The
FF
(atau 256 atau -1 jika Anda akan) kelereng akan duduk di sel input dari:I
fungsi menunggu sampai ada cukup sto masukan marmer memulai fungsi (satu lagi yang). Di situlah@4
portal masuk. Salinan input baris perintah menurun jatuh di sana pada setiap loop. Ini akan memicu:I
papan paling kiri . Initialy dengan nilai 256 (atau -1) dan apa pun input baris perintah adalah -1. Marmer kiri akan dimasukkan ke dalam}0
perangkat:I
papan dan yang tepat ke dalam}1
. Jika Anda ingat apa yang dilakukan papan ini, Anda akan dapat mengetahui hasil apa yang dimilikinya. Ini akan menampilkan versi tambahan dari input kanan pada output kiri (dan mengubah 9 menjadi 0, bukan 10) dan menghasilkan 1 atau -9 di sebelah kanan.Nilai yang bertambah akan dibawa kembali ke sel input kanan oleh portal, dan nilai di sebelah kanan jatuh ke sinkronisasi. Jika sinkronisasi sudah memegang marmer, kedua kelereng akan bertabrakan. Kelereng yang bertabrakan dapat ditambahkan bersama-sama modulo 256. Jadi nilai-nilai di synchroizers akan melakukan berikut: Mereka mulai kosong, kemudian beralih ke 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, dan kemudian ke 1 lagi (sejak 247 ditambahkan modulo 256).
Anda juga mungkin ingat bahwa marmer mendapatkan output ke kanan ketika nilai input kembali ke 0. Karena
:I
papan tepat di sebelah satu sama lain, ini akan memicu papan ke kanan sekali. Ini akan mengisi tiga sinkronisasi dengan nilai-nilai yang satu lebih tinggi dari yang seharusnya menjadi representasi shortlex dari input baris perintah, pada saat ini telah diturunkan ke 0.Anda mungkin juga ingat bahwa
:O
fungsi mengubah nilai menjadi nilai ascii digit yang mewakili nilai -1. Output dariOO
sel - sel ini kemudian akan jatuh dari papan, yang mencetak karakter ascii yang sesuai untuk STDOUT.Jadi apa yang terjadi ketika marmer input baris perintah mencapai 0 dan mengisi
&0
sinkronisasi? nah, beberapa kelereng nilai 0 jatuh dan memicu tiga sinkronisasi yang menahan angka (+ 1) dari nomor shortlex di bagian bawah papan.&3
dipicu terlebih dahulu, karena mengandung digit paling signifikan, kemudian&2
diikuti oleh&1
. Marmer ini kemudian dipindahkan ke@5
perangkat lain sebelum akhirnya mengenai!!
sel, yang mengakhiri papan.sumber
CJam,
1411 byteCobalah online.
Bagaimana itu bekerja
Pendekatan ini sangat didasarkan pada jawaban edc65 (dengan izin eksplisitnya ):
Contoh dijalankan
sumber
Python 2 (38)
(43)Tidak ada substitusi karakter, hanya aritmatika.
Tidak Disatukan:
Saya tidak punya alasan bagus mengapa rekursi bekerja, saya hanya mencocokkan pola ini dengan daftar nilai. Jika Anda mengubah masing-masing
n-1
ken
, Anda akan mendapatkan representasi digit reguler.Untuk bermain golf, saya menggunakan
~-n
untuk menghitungn-1
dengan prioritas lebih tinggi dari/10
atau%10
, menghemat pada parens. Then*'_'
hanya untuk menghasilkan string kosong ketikan=0
dan string lain sebaliknya. The'_'
dapat berupa string apapun untuk tujuan ini.sumber
Ruby,
7068666457 byteMendefinisikan fungsi yang disebut like
f[42]
. Berikut adalah uraian kasar dari algoritma tersebut:0
secara terpisah.Kredit untuk gagasan menggunakan string format, buka Falko!
Atau, gunakan pendekatan edc65:
Itu 45 byte dan saya hanya memasukkannya, karena saya tidak mengalahkannya dengan itu. ;)
sumber
Haskell, 67 byte
solusi ini pada dasarnya menambahkan 1 berapa kali, dalam notasi shortlex.
pemakaian:
sumber
CJam, 16 byte
Cobalah online. Membutuhkan setidaknya O (n) waktu dan memori, jadi tinggalkan 100501 ke penerjemah offline ...
Bagaimana itu bekerja
Ide dasar di balik pendekatan ini adalah untuk menghitung setidaknya N desimal pendek dalam tatanan alami mereka dan membuang semua kecuali N. Tidak terlalu efisien, tetapi pendek.
Contoh dijalankan
sumber
Bash + coreutils, 27 byte
Port jawaban cerdas @ edc65 , dengan peningkatan @ Dennis :
Keluaran:
Jawaban sebelumnya:
Bash + coreutils,
7154 byteBerikut cara yang sedikit berbeda untuk melakukannya:
jot
output meningkatkan bilangan bulat heksadesimaltr
ubah ini menjadi (0,1, ..., 8,9, b, ... f, 0a, 00,01, ..., 99,9b, ..., ff, 0aa, ..., 000 , ...)grep
cukup filter semua garis yang mengandung digit untuk memberi (0,1, ..., 8,9,00, ..., 99.000 ....)sed
menghapus semua kecuali baris ke-nsed
menghitung angka garis mulai dari 1, jadi kesalahan jika 0 dilewatkan)grep
, kita perlu menghasilkan lebih banyak basis 11 integer denganseq
/dc
daripada nomor input. Mengulang digit n lebih dari cukup.Perhatikan bahwa setelah nomor shortlex dicetak,
seq
terus menghasilkan angka hingga$1$1
, yang lambat terutama untuk nomor input yang lebih besar - O (n²), saya pikir. Kita dapat mempercepat denganseq
menghentikannya segera setelah mencetak dengan biaya 7 byte:Tidak ada persyaratan kecepatan dalam pertanyaan, jadi saya akan menggunakan versi yang lebih pendek untuk jawaban utama saya.
sumber
s='jot -w%x $1$1|tr 0-9a a0-9|grep -P ^\\d+$|sed $1!d 2>-'; echo ${#s}
. Saya menduga Anda mungkin menggunakan python untuk mengukur panjang string, yang memperlakukan "\\" sebagai satu karakter.$a
tampaknya tidak perlu;cut -b2-<<<$[$1-~${1//?/8}]
harus bekerja dengan baik.Python 2 -
84, 7066Pendekatan alternatif (panjang yang sama):
sumber
Python 3, 107 karakter
Ini tidak berakhir dengan kemenangan tetapi saya pikir itu pintar:
Saya mendefinisikan generator untuk seluruh urutan dalam 64 karakter. Sayangnya, saya harus melalui beberapa contortions untuk mendapatkan elemen ke-n dari generator ... kalau saja saya bisa melakukannya
S=lambda n:G()[n]
.sumber
Pyth , 12
Port lain dari jawaban @ edc65, yang merupakan pemenang yang jelas (IMO):
Paket tes (Terima kasih kepada @DigitalTrauama):
Penjelasan:
sumber
[8, 8, 9] -> 889
). Bagaimana kamu melakukannya?jk
akan mengubah daftar Anda menjadi string, danv
akan mengubahnya menjadi int. Jadivjk[8 8 9]
akan memberikan nomor 889.[2 -1] -> 19
dan[1 11] -> 21
.Java 8, 60 byte
Port dari JavaScript menakjubkan (ES6) jawaban @ edc65 , karena saya ragu itu bisa dilakukan lebih pendek dengan cara aritmatika di Jawa.
Coba di sini.
sumber
Haskell , 57 byte
Cobalah online!
Buatlah daftar nomor pendek yang tak terhingga dan buat indeks untuk jawabannya.
g n
membangun "generasi" angka ke-n dengan memprioritaskan digit berikutnya di depan setiap angka pada generasi sebelumnya.sumber
05AB1E , 7 byte
Menggunakan edc65 diganti dengan 8 trik
Cobalah online!
Penjelasan
sumber
Excel, 37 byte
Menggunakan pendekatan @ edc65:
sumber
Jelly , 5 byte
Cobalah online!
Saya sangat baru mengenal Jelly, jadi jika Anda dapat meningkatkan ini, beri komentar!
Penjelasan:
(Menurut komentar res di atas, masalahnya setara dengan mengubah nomor menjadi basis bijective 10)
sumber