Saya telah menemukan pertanyaan di situs Tinjauan Kode yang sepertinya menarik. Saya pikir OP salah, tapi tidak bisa memastikan ... Jadi mari kita selesaikan untuknya! (menulis program, bukan fungsi / prosedur)
Input (stdin atau serupa):
Integer x
dalam notasi desimal. Ini lebih besar dari 1 dan kurang dari 2 ^ 31.
Output (stdout atau serupa):
Integer y
dalam notasi desimal. Produk x * y
dalam representasi desimal hanya boleh mengandung angka 0 dan 1. Harus minimal jumlah tersebut lebih besar dari 0.
Catatan: output tidak terbatas - jika minimalnya y
sekitar 10 ^ 100, program Anda harus mengeluarkan semua 100 digitnya (saya tidak tahu apakah ada batas yang masuk akal, seperti 2 ^ 64, aktif y
- tidak menyelesaikannya ).
Program Anda harus selesai dalam waktu yang wajar (1 detik? 1 jam? - sesuatu seperti itu) untuk semua yang ada x
dalam jangkauan.
Bonus:
Jika program Anda tidak memiliki batasan ukuran input (kecuali RAM), dan memiliki kompleksitas polinomial, gandakan jumlah byte program Anda dengan 0.8
dan bulatkan.
Contoh: Input 2
; output 5
, karena 2 * 5 = 10
Contoh: Input 21
; output 481
, karena 21 * 481 = 10101
Penafian: Saya tidak bertanggung jawab atas pertanyaan di situs Tinjauan Kode. Dalam hal terjadi perbedaan, hanya uraian di atas yang harus dianggap sebagai spesifikasi yang tepat.
Jawaban:
Pyth, 9 byte
Demonstrasi
Untuk setiap kelipatan, konversikan ke string, kurangi digit dalam
10
(menggunakan Pyth's int berguna untuk str cast dalam kasus ini) dan kemudian secara logis meniadakan hasilnya, mengakhiri pencarian hanya ketika kelipatan yang benar ditemukan.Solusi bonus, 10 byte:
Solusi ini benar-benar memeriksa apakah representasi string dari angka dapat diperlakukan sebagai angka biner (
i ... 2
) dan berakhir ketika kesalahan tidak dilemparkan pada upaya ini.sumber
Python 2, solusi efisien, 99
Terima kasih Sp3000 untuk beberapa tips golf.
Saya menantang semua orang untuk memposting (dalam jawaban mereka sendiri) berapa lama untuk mendapatkan hasil untuk input
72
atau99
:) Jika itu benar-benar cepat, coba sesuatu seperti yang79992
berikutnya (masih <1 detik di sini).Penjelasan:
Saya pikir ini tidak perlu (karena kode ini cukup mudah dibaca), tapi saya mendapat permintaan, jadi begini:
Gagasan pertama adalah bahwa angka yang tampak biner adalah jumlah dari 1 atau lebih dari 10 kekuatan yang berbeda. Oleh karena itu, kita dapat mencoba menambahkan berbagai kekuatan 10 dengan cara yang berbeda sampai kita mendapatkan sisa 0.
Jika kita melakukannya secara naif, itu sama dengan menghasilkan semua angka yang tampak biner dan mengujinya. Tetapi banyak sisa yang akan sama. Cara yang lebih baik adalah mencatat hanya angka terkecil yang memberikan sisa tertentu, dan berturut-turut menambahkan kekuatan 10 yang lebih besar ke angka yang kami rekam. Itulah yang dilakukan oleh program ini.
d
adalah kamus / peta di mana kunci adalah sisa dan nilai adalah angka yang tampak biner dengan sisanya. Inisialn:0
adalah kasus khusus: seharusnya0:0
jadi kita dapat mulai menambahkan kekuatan untuk itu, tetapi algoritma berhenti ketika menemukan kunci 0, jadi saya menggunakann
sebaliknya, yang dijamin memiliki efek yang sama dan tidak mengganggu nilai-nilai lainnya.Kemudian kami mulai menambahkan kekuatan 10 (disimpan dalam
k
) ke semua nomor yang ada dan merekam sisanya. Kami menambahk
sisanya:(x+k)%n
dan ke nomord[x]+k
:, dan merekamnya hanya jika itu adalah sisa baru:,d.setdefault(…)
kemudian pergi ke kekuatan berikutnya:k*=10
dan ulangi sampai kami mendapatkan kunci 0:while min(d)
Pada akhirnya,
d[0]
berikan angka yang tampak biner yang memiliki sisa 0 modn
, jadi kami membaginya dengann
untuk mendapatkan solusinya.Catatan: program ini dapat dibuat lebih efisien dengan menghindari sejumlah besar (merekam eksponen daripada kekuatan 10, dan menghitung sisa kekuatan dari nilai sebelumnya), tetapi kode golf, jadi ...
Bahkan, di sini, saya menulis versi yang lebih cepat:
sumber
Python 2, 47 byte
Melacak nomor input
n
dan multiple saat inia
. Ketikaa
terlihat seperti biner, hasilkan rasioa/n
. Untuk memeriksa apakah suatu angka terbuat dari0
dan1
, kita membandingkan karakter maksimum dalam representasi stringnya dengan'1'
.Penggunaan
str(a)
bukannya`a`
menghindari jangka waktu yang berakhir denganL
. Sayangnya,'L'
lebih besar dari'1'
.sumber
Perl, 27 byte
Menghitung shebang sebagai satu, input diambil dari stdin.
Contoh Penggunaan
Perl, 25 byte
Peningkatan dua byte oleh @skmrx .
Alih-alih memeriksa terhadap suatu regex, ini malah mencoba untuk mengevaluasi produk sebagai literal biner. Setelah gagal, ia beralih ke yang berikutnya. Biasanya
oct
fungsi tersebut akan digunakan untuk tujuan ini, tetapi fungsi ini diam-diam memotong angka yang tidak valid, yang tidak berguna dalam tantangan ini.Perl, 40 byte
Solusi yang jauh lebih efisien. Kami beralih dari representasi biner, menafsirkannya sebagai basis 10, dan kemudian memeriksa keterbagiannya. Runtime untuk semua nilai di bawah 100 dapat diabaikan.
Contoh Penggunaan
sumber
eval"0b".$_*++$\||redo}{
use bigint
untuk mendukung sejumlah besar yang telah diamanatkan OP untuk didukung :(oct'0b'.++$\*$_
, tetapi diam-diam memotong angka yang tidak valid. Saya tidak berpikir untuk menggunakannyaeval
sebagai gantinya.Javascript, 43 byte
Ini akhirnya jauh lebih pendek dari yang saya kira. Ini pada dasarnya meningkatkan
y
hingga 1y * (input number) = (binary-looking number)
. Jelas sangat tidak efisien.Javascript (solusi yang lebih efisien), 53 byte
Yang satu ini bertambah
y
dalam biner hinggay / (input number) = (number without a remainder)
. Maka itu output(number without a remainder)
.Javascript (solusi yang lebih efisien), 76 byte
Yang ini menggabungkan kedua metode sebelumnya yang dijelaskan di atas. Ia memeriksa kenaikan
y
sampai salah satuy * (input number) = (binary-looking number)
(artinya outputnyay
) ATAUy / (input number) = (number without a remainder)
(artinya outputnya(number without a remainder)
).sumber
Haskell,
7270646058 byteSunting: @Jan Dvorak membantu saya menghemat 4 byte.
Sunting: @BlackCap menyimpan 2 byte dengan beralih ke
do
notasi. Terima kasih!sumber
main=print.f=<<readLn
main=readLn>>= \x->print$[y|y<-[1..],all(<'2')$show$x*y]!!0
main=do x<-readLn;print$[y|y<-[1..],all(<'2')$show$x*y]!!0
Python 2,
67656360 byteBerkat Status untuk 2 byte dan Shebang untuk 5 byte!
sumber
b=1
any(c in`a*b`for c in'23456789')
not c in`a*b`for c in'10'
berhasil?set('a*b')&set('23456789')
.`
menghasilkanL
jangka panjang dan'L'>'1'
.JavaScript (ES6) 222
250Menggunakan matematika presisi arbitrer (beroperasi pada string angka desimal)
Ini bisa bermain golf sedikit lebih(selesai), tapi saya suka fakta bahwa itu tidak terbatas pada angka standar JS (17 digit desimal presisi) dan cepat.Tes menjalankan cuplikan di bawah ini di peramban yang mendukung EcmaScript 6. Waktu dapat diterima hingga 9998 - jangan coba 9999 dan bersabarlah dengan 999.
Lebih mudah dibaca
Ini adalah versi pertama, dengan modulus dan pembagian panjang sebagai fungsi yang terpisah.
sumber
Perl, 45 byte
sumber
Pyth, 10 byte
Jalankan kodenya.
Sebuah port jawaban Python saya , mengambil dari Maltysen penggunaan
f
untuk menemukan angka positif pertama yang memenuhi syarat.sumber
PHP, 50 byte
Beberapa test case
sumber
CJam,
191716 byteCobalah online
Solusi brute force, mencoba nilai secara berurutan sampai satu kali memenuhi kondisi ditemukan.
Versi terbaru menghemat 2 byte karena menggunakan
As
alih-alih"01"
membangun string yang mengandung0
dan1
, seperti yang disarankan oleh @aditsu. Solusi lengkap yang diusulkan dalam komentar menyimpan byte lain, tetapi terlihat cukup berbeda dari milik saya, jadi saya tidak ingin mempostingnya di bawah nama saya.Dan 1 byte lagi disimpan oleh @ Dennis.
Penjelasan:
sumber
li0{1$+_sAs-}g\/
As
untuk membangun string, karena itu adalah perubahan yang sangat lokal, yang di belakang (yang selalu jauh lebih mudah ...) Saya seharusnya memikirkan.li:V!{)_V*sAs-}g
Juga,0{)_easi*sAs-}g
(15 byte) berfungsi dengan interpreter Java dan argumen baris perintah.Python
32,10176 Bytes-25 byte terima kasih kepada @aditsu
hampir seefisien solusi @ aditsu
Alih-alih mencoba untuk mengulang melalui kelipatan dalam urutan meningkat, saya mencoba untuk mengulang melalui produk, yang saya hasilkan dalam bentuk 'biner'.
sumber
n=input()
),while b%n:
(inisialisasib
ke 1), tanpa lekukanbin(m)[2:]
harus lebih pendek dari string format. Tugas ganda padab=m=1
harus menyimpan beberapa juga.Java, 213 byte
Penggunaan
BigInteger
dan karenanya memiliki (untuk semua maksud dan tujuan yang masuk akal) ukuran input tidak terbatas. Namun, tidak yakin tentang kerumitannya, itu tergantung pada tingkat pertumbuhan fungsi kami di sini.Terima kasih kepada geobits dan ypnypn karena telah menyimpan beberapa byte.
sumber
static
pengubah ke metode.b.ONE
dan!(b.multiply(c)+"")
(bukantoString()
).C, 3675 byte
Begitu lama untuk Code Golf ...
Jalankan tanpa parameter baris perintah - didapat
n
daristdin
dan menampilkan hasilnyastdout
. Jalankan dengan nama file - ia menulis hasilnya ken = 1...10000
dalam file itu, dan mengukur waktu.Kinerja untuk 1 ... 10000: 140 ms
Kode ini menggunakan algoritma yang diusulkan oleh aditsu , diimplementasikan dalam C untuk kecepatan. Saya tidak berusaha untuk membuatnya, jadi kode ini akan lebih mudah dibaca.
Saya menerapkannya pertama kali di C ++ menggunakan
std::map
untuk merekam hasil pencarian, dan itu agak lambat. Namun, kunci-kuncimap
bilangan bulat adalah berurutan (saya menyebutnyamod
s, karena mereka mewakili angka modulon
), jadi wajar jika menggunakan array - jadi saya menulis ulang dalam C.Optimalisasi tambahan menyangkut nilai-nilai pemetaan - untuk menghindari menyimpan bilangan bulat besar untuk masing-masing
mod
, saya hanya menyimpan kekuatan terbesar dari 10 di sana - itu hanya cukup informasi untuk pergi ke sebelumnyamod
. Jadi array ini benar-benar pohon pencarian / grafik. Ketika pencarian tibamod = 0
, melacak node pohon kembali ke root memberikan kekuatan 10 dalam urutan menurun.Karena pencarian biasanya berhenti agak cepat, dengan hanya sebagian kecil dari node yang dikunjungi, saya perlu daftar node aktif. Diimplementasikan sebagai array
mod_list
dengan panjangmod_list_length
.Beberapa statistik runtime (pada mesin dengan RAM 16 GB, yang tampaknya penting untuk ukuran besar
n
, karena program mengalokasikan5n
byte memori):99999999
- 2 detik999999999
- 27 detik (hasilnya111111111222222222333333333444444444555555555666666666777777777888888889
- mungkin hasil terbesar untuk bilangan bulat 32-bit)2147483647
- 26 detik (hasilnya4661316525084584315813
)1999999998
- 52 detik (mungkin jangka waktu terpanjang untuk integer 32-bit)sumber
C ++ 11, banyak byte, sangat cepat, wow (1,5 detik pada 1999999998, 0,2 detik pada 1… 10.000)
(Versi Python Golf di bawah.)
Kami mulai dengan konsep yang agak mirip dengan solusi aditsu, di mana kami secara induktif membangun koleksi sisa modular yang dapat dicapai dalam n langkah. Tetapi alih-alih menunggu sampai kita menemukan sisa 0, kita memeriksa dua sisa yang ditemukan a dan b sehingga a · 10 ^ n + b = 0. Pendekatan bertemu-di-tengah ini mengurangi kedalaman pohon pencarian, jadi itu adalah jauh lebih cepat pada input besar dan menggunakan memori jauh lebih sedikit.
Beberapa tolok ukur:
Kode:
Python, 280 byte (8,6 detik pada 1999999998 dengan PyPy)
sumber
Mathematica 115 byte
sumber
Java 156 byte
Terima kasih banyak kepada aditsu :)
sumber
[]
,y
bisalong
juga, Anda lupax*y+""
trik dalam program ke-2, gunakanisEmpty
alih-alih memeriksa panjangnya, gunakan;
alih-alih{}
long
tidak akan membuat kode lebih pendeklong x=…,y;
y
harus dimulai dari 1, Anda dapat menginisialisasi dalam deklarasi, kelas Anda tidak perlu bersifat publik, dan Anda dapat pindahy++
kex*y
bagian (x*y++
)Pyth -
1211 byteGunakan filter dengan arg numerik untuk mendapatkan bilangan asli pertama yang memenuhi predikat, defaultnya adalah 1 yang kita inginkan. Setwise diff untuk memeriksa apakah hanya nol dan satu.
Test Suite .
sumber
"01
. Menghemat satu char.R, 45 byte
Pemakaian:
sumber
Java,
198193181 byteTerima kasih kepada @aditsu karena telah mengurangi 5 byte DAN meningkatkan rentang angka yang dapat diuji!
Perhatikan bahwa beberapa nilai loop negatif karena bagaimana Java mem-parsing bilangan bulat. Ini bisa dielakkan oleh BigInteger, tetapi bonus itu kurang berharga.
Saya tahu bahwa saya tidak akan menang, tetapi saya harap ini menginspirasi jawaban lain yang lebih pendek.
Tidak terbungkus:
sumber
Long
lebih pendek dariInteger
:)C,
107101 byte (10599 byte untuk 32-bit)Ada kekurangan yang jelas dari jawaban dalam kode C pada golf. Memang, C bukan pilihan terbaik untuk menulis program sekecil mungkin, tetapi tidak seburuk itu:
Anda dapat melakukannya tanpa menyertakan #, tetapi semua definisi fungsi akan tersirat. Kelemahan utama adalah bahwa ini menyebabkan asumsi bahwa semua fungsi mengembalikan int. Ini adalah masalah pada mesin 64-bit untuk fungsi yang benar-benar mengembalikan pointer. Jika Anda menggunakan mesin 32-bit, 2 byte dapat dicukur dari solusi di atas:
Versi yang lebih mudah dibaca:
sumber
C # waktu dekat 5 detik (1 hingga 10.000)
Seperti yang diminta, ini adalah program C # golf menjawab tantangan aslinya. Input sebagai argumen baris perintah, output ke konsol.
Kemudian, seperti untuk hadiah: hadiah harus pergi ke aditsu, karena saya pikir algoritme tidak dapat dikalahkan dalam hal kinerja. Tapi anatolyg jawaban sendiri juga luar biasa.
Berikut ini adalah implementasi cepat saya di C #. Saya kira di C ++ bisa lebih cepat (mungkin 2x). Dikompilasi dan diuji dengan Visual Studio 2010, .NET framework 4, 64 bit, mengarahkan output ke nul. Waktu: 00: 00: 05.2604315
sumber
Keys.Reverse
? Apakah urutannya penting? Jika hanya untuk menghindari masalah konkurensi,ToList
lebih pendek.C dengan GMP (621 byte, cepat)
Saya sudah berusaha cepat dan pendek, tetapi disukai cepat. Implementasi ini menggunakan versi yang sedikit ditingkatkan dari percepatan teori angka yang saya sebutkan di komentar pada jawaban aditsu .
Simpan sebagai
pseudobinary.c
dan kompilasi dengangcc pseudobinary.c -lgmp -o pseudobinary
. Perhatikan bahwa ini mengalokasikan begitu banyak memori untuk input besar sehingga Anda harus mengompilasinya untuk platform 64-bit.Versi loop untuk timing (751 bytes)
Versi loop tidak disatukan
sumber
C + GMP, 669
Ini sangat cepat untuk angka yang bertubuh kecil; mulai tersedak ketika hasilnya memiliki lebih dari 64 digit.
Versi yang dapat mencapai 10.000 (671 byte):
Berikut adalah beberapa perintah untuk menguji kode saya dan juga pesaing saya, dan hasilnya di laptop saya:
sumber
T-SQL,
164156155154159 byte(-1 byte. Terima kasih Jonathan!)
(-1 lebih karena mengapa saya memiliki spasi di belakang garis? SMH)
(+5 menyadari golf saya memecahkan banyak hal)
Saya tidak tahu mengapa saya terus kembali ke pertanyaan-pertanyaan ini di mana saya seharusnya mengonversi ke Biner ... T-SQL tidak tahu bagaimana melakukannya dengan benar.
Bagaimanapun, ini adalah SQLFiddle .
Tidak golf:
Sebagian besar hal ini diperlukan untuk menulis fungsi dalam T-SQL, sejauh yang saya ketahui.
Buat string kosong yang akan kita simpan sebagai nomor biner kita.
Simpan nilai input untuk digunakan di akhir. Sepertinya harus ada cara untuk menggunakan input asli bahkan jika kita mengubah nilainya, tetapi saya tidak dapat menemukannya.
Jadi kami mengambil input asli kami, MOD dengan 2 untuk menemukan sisanya, dan itu akan menjadi digit terkecil kami berikutnya. Misalnya, 5% 2 = 1
Lalu kami mengambil nomor kami, dan membaginya menjadi dua. Karena ini adalah
int
tipe, ia membulatkannya ke bilangan bulat terdekat, jadi 5/2 = 2. END Kami kemudian mengulangi ini sampai nilainya 0. Jadi kita berakhir dengan 5% 2 = 1 5/2 = 2 2 % 2 = 0 2/2 = 1 1% 2 = 1 1/2 = 0 yang memberi kita nilai string biner kami dari 101.Kami mengambil string biner kami dan mengubahnya kembali menjadi yang lain
int
.Kami mengembalikan string biner kami
int
dibagi dengan nilai asli kami, sesuai dengan asal pertanyaan.sumber
@>0 SELECT
tidak bisa dihilangkan?Ruby, 46 byte
Saya harus benar-benar menghilangkan loop sementara dengan loop alternatif.
Sunting: Terima kasih @manatwork untuk mencukur 1 byte!
Sunting2: Terima kasih @histocraft untuk 9 byte yang gila!
Sunting: Terima kasih @manatwork lagi untuk mencukur 7 byte!
sumber
z!=z[/[01]+/]
lebih pendek.z[/[^01]/]
bahkan lebih pendek.z="#{n.to_i*k+=1}"while z[/[^01]/]
Scala, 114 Bytes
Versi yang mudah dibaca
sumber
gawk4 brute force, 28 + 2 = 30 byte
Perlu dipanggil dengan
-M
opsi untuk menggunakan nomor besar. Tentu saja ini sangat lambat, menggunakan angka besar memperlambatnya bahkan lebih, tetapi secara teoritis inputnya tidak terbatas, dan penggunaan RAM dapat diabaikan.Contoh penggunaan (jika Anda punya waktu untuk dihabiskan
;)
)gawk4 dioptimalkan, 69 + 2 = 71 byte
Nah, ini akhirnya menjadi klon dari jawaban aditsu. Setelah melihat pertanyaan ini saya masih mencari cara untuk membuat kode bagian subset-sum, ketika saya tidak bisa menolak melihat jawaban lain di sini.
Dalam elemen awk array memiliki perilaku (aneh?) Bahwa jika Anda membandingkan elemen yang tidak ada dengan sesuatu itu entah bagaimana diinisialisasi sebagai kosong sebelum dibandingkan (saya akui bahwa saya tidak begitu yakin tentang apa yang terjadi di sana). Jadi setelah memeriksa
!a[0]
yangfor(i in a)
lingkaran dimulai bahkan tanpa menginisialisasia[$0]
ke0
sebagai aditsu lakukan.Tentu saja
-M
opsi harus digunakan untuk ini juga.Meskipun agak cepat masih lebih lambat dari Python. Untuk
79992
ini membutuhkan sekitar 14 detik pada Core2Duo 2GHz saya. Dan saya tidak akan mengatakan itu bekerja untuk input hingga 2 ^ 31, karena dalam kasus terburuk itu harus membangun array angka besar (gawk4 menggunakan GMP untuk ini), yang memiliki ukuran nomor input. Sebagai 'bonus' array besar sangat lambat di awk ...sumber
Dyalog APL , 25
Ini mendefinisikan program yang tepat "P" (bukan hanya fungsi yang tidak disebutkan namanya):
2∘
mulai dengan 2 sebagai argumen kiri0::
jika ada kesalahan ...⍵∇⍨1+⍺
panggil dirinya dengan argumen⍺×⍵
kiri yang bertambah, gandakan argumen kiri dan kanan⍕
menjadi string⍎¨
buat setiap karakter menjadi~
upaya angka BUKAN logis (jika gagal, pergi ke penanganan kesalahan di atas, lain ...)⍺⊣
kembalikan argumen kiri saat ini.sumber