Orang-orang Yunani kuno memiliki hal-hal ini disebut angka genap tunggal dan ganda. Contoh angka genap tunggal adalah 14. Angka ini dapat dibagi 2 sekali, dan pada saat itu menjadi angka ganjil (7), setelah itu tidak dapat dibagi 2 lagi. Angka genap dua kali lipat adalah 20. Ini dapat dibagi 2 dua kali, dan kemudian menjadi 5.
Tugas Anda adalah menulis fungsi atau program yang menggunakan bilangan bulat sebagai input, dan menampilkan berapa kali bilangan itu dapat dibagi 2 sebagai bilangan bulat, sesedikit mungkin dalam byte. Masukan akan berupa bilangan nol bukan (nilai positif atau negatif, dalam batas bahasa Anda).
Kasus uji:
14 -> 1
20 -> 2
94208 -> 12
7 -> 0
-4 -> 2
Jawaban dengan byte terkecil menang.
Kiat: Cobalah mengonversi nomor menjadi basis 2. Lihat apa yang memberitahu Anda.
The input will be a nonzero integer
Apakah ini perlu diedit mengikuti komentar Anda tentang nol menjadi input potensial?Jawaban:
Jelly , 4 byte
Dalam versi terbaru Jelly,
ÆEḢ
(3 byte) berfungsi.Coba di sini .
sumber
kode mesin x86_64, 4 byte
Instruksi BSF (bit scan forward) melakukan hal ini !
Dalam perakitan gcc-style, ini adalah:
Input diberikan dalam register EDI dan dikembalikan dalam register EAX sesuai dengan konvensi panggilan c 64-bit standar .
Karena pengkodean biner komplemen dua, ini berfungsi untuk -ve serta + ve nomor.
Juga, terlepas dari dokumentasi yang mengatakan "Jika konten dari operan sumber adalah 0, konten dari operan tujuan tidak ditentukan." , Saya temukan di VM Ubuntu saya bahwa output
f(0)
adalah 0.Instruksi:
evenness.s
dan kumpulkangcc -c evenness.s -o evenness.o
evenness-main.c
dan kompilasi dengangcc -c evenness-main.c -o evenness-main.o
:Kemudian:
gcc evenness-main.o evenness.o -o evenness
./evenness
@FarazMasroor meminta detail lebih lanjut tentang bagaimana jawaban ini diturunkan.
Saya lebih terbiasa dengan c daripada seluk-beluk perakitan x86, jadi biasanya saya menggunakan kompiler untuk menghasilkan kode perakitan untuk saya. Saya tahu dari pengalaman bahwa ekstensi gcc seperti
__builtin_ffs()
,__builtin_ctz()
dan__builtin_popcount()
biasanya mengkompilasi dan merakit ke 1 atau 2 instruksi pada x86. Jadi saya mulai dengan fungsi c seperti:Alih-alih menggunakan kompilasi gcc biasa semua jalan ke kode objek, Anda dapat menggunakan
-S
opsi untuk mengkompilasi hanya untuk perakitan -gcc -S -c evenness.c
. Ini memberikan file perakitanevenness.s
seperti ini:Banyak dari ini bisa dimainkan. Secara khusus kita tahu bahwa konvensi pemanggilan c untuk fungsi dengan tanda tangan bagus dan sederhana - param input dilewatkan dalam register dan nilai balik dikembalikan dalam register. Jadi kita dapat mengambil sebagian besar instruksi - banyak dari mereka yang peduli dengan menyimpan register dan mengatur bingkai stack baru. Kami tidak menggunakan tumpukan di sini dan hanya menggunakan register, jadi tidak perlu khawatir tentang register lain. Ini meninggalkan kode perakitan "golf":
int f(int n);
EDI
EAX
EAX
Catatan seperti yang ditunjukkan oleh zwol, Anda juga dapat menggunakan kompilasi yang dioptimalkan untuk mencapai hasil yang serupa. Khususnya
-Os
menghasilkan instruksi di atas persis (dengan beberapa arahan assembler tambahan yang tidak menghasilkan kode objek tambahan.)Ini sekarang dirakit dengan
gcc -c evenness.s -o evenness.o
, yang kemudian dapat dihubungkan ke program driver tes seperti dijelaskan di atas.Ada beberapa cara untuk menentukan kode mesin yang sesuai dengan rakitan ini. Favorit saya adalah menggunakan
disass
perintah pembongkaran gdb :Jadi kita bisa melihat bahwa kode mesin untuk
bsf
instruksi0f bc c7
dan untukret
yaituc3
.sumber
evenness-main.c
dengan pengaturan optimasi yang berbeda; bagi saya rusak dengan-O
,-O2
atau-O3
.Python, 25 byte
n & -n
nol apa pun kecuali bit paling tidak signifikan, misalnya ini:Kami tertarik pada jumlah trailing nol, jadi kami mengonversinya menjadi string biner
bin
, yang untuk nomor di atas akan menjadi"0b10000"
. Karena kita tidak peduli dengan0b
, atau1
, kita mengurangi 3 dari panjang string itu.sumber
Pyth, 6 byte
Coba di sini .
sumber
JavaScript (ES6), 18 byte
4 byte lebih pendek dari
31-Math.clz32
. Hah.sumber
Math.clz32
juga ...JavaScript ES6,
2219 byteSepertinya rekursi adalah rute terpendek.
sumber
Pyth, 8 byte
Sebagai contoh, representasi biner
94208
adalah:Setelah memisahkan pada
1
s dan mengambil elemen terakhir dari array yang dihasilkan, ini menjadi:Itu 12 nol, jadi "12-ly even."
Ini bekerja karena
x / 2
pada dasarnyax >> 1
—yaitu, hak bithift dari1
. Oleh karena itu, angka dapat dibagi 2 hanya ketika LSB0
(seperti halnya angka desimal dapat dibagi 10 ketika digit terakhirnya0
).sumber
05AB1E ,
45 byteSekarang mendukung angka negatif. Kode:
Cobalah online!
Penjelasan:
Menggunakan pengodean CP-1252.
sumber
Pyth, 6 byte
Pada dasarnya adil
sumber
MATL , 5 byte
Ini berfungsi untuk semua bilangan bulat.
Cobalah online!
sumber
C, 36 (28) byte
(Tidak menguji untuk argumen nol karena argumen bukan nol ditentukan.)
Pembaruan (sebagai tanggapan terhadap komentar) : Jika kami mengizinkan deklarasi fungsi gaya K&R, maka kami dapat memiliki versi 28-byte:
Dalam hal ini, kami bergantung pada fakta bahwa kompiler default keduanya
n
dan tipe kembalif
keint
. Formulir ini menghasilkan peringatan dengan C99 dan tidak mengkompilasi sebagai kode C ++ yang valid.sumber
int n
->n
kode C masih valid dan memotong 4 karakter.Java 7, 39 atau mungkin 44 byte
Rekursi Yay! Saya harus menggunakan
!=
bukannya perbandingan yang lebih pendek sehingga tidak akan meluap pada input negatif, tetapi selain itu cukup mudah. Jika aneh, kirim nol. Jika genap, tambahkan satu dan lakukan lagi.Ada dua versi karena sekarang output untuk nol tidak diketahui. Yang pertama akan berulang sampai stack meluap, dan tidak menghasilkan apa-apa, karena 0 bahkan genap. Yang kedua mengeluarkan 0 yang bagus, aman, tapi mungkin-tidak-matematis-ketat untuk output.
sumber
JavaScript (ES6),
20 byte19 byte.Ini adalah port solusi Haskell oleh @nimi ke JavaScript. Ia menggunakan properti "korsleting"
&&
yang mengembalikan sisi kirinya jika itu falsey (yang dalam hal ini-0
) atau mengembalikan sisi kanannya.odd x = 0
Oleh karena itu untuk menerapkan kami membuat sisi kiri1 - (x % 2)
yang gelembung0
melalui&&
, kalau tidak kita kambuh1 + f(x / 2)
.Cukur
1 - (x % 2)
as(~x) % 2
adalah karena @Neil di bawah, dan memiliki properti aneh yang menyebabkan fungsi di atas untuk memancarkan-0
angka ganjil kecil. Nilai ini adalah kekhasan keputusan JS bahwa integer adalah ganda IEEE754; sistem ini memiliki fungsi yang terpisah+0
dan-0
khusus dalam JavaScript untuk digunakan===
satu sama lain. The~
Operator menghitung 32-bit-menandatangani-bulat bitwise inversi untuk nomor, yang untuk angka ganjil kecil akan menjadi nomor bahkan negatif. (Angka positifMath.pow(2, 31) + 1
misalnya menghasilkan0
daripada-0
.) Pembatasan aneh untuk bilangan bulat 32-bit tidak memiliki efek lain; khususnya itu tidak memengaruhi kebenaran.sumber
~x&1
byte lebih pendek dari1-x%2
.Perl 6,
2318 bytepemakaian
sumber
Ruby 24 byte
Pengiriman golf kode pertama saya (ya!)
Bagaimana saya sampai di sini :
Pertama saya ingin mendapatkan kode yang benar-benar memenuhi spesifikasi untuk mengatasi masalah saya, jadi saya membangun metode ini tanpa memperhatikan jumlah byte:
dengan pengetahuan ini saya de-recursed fungsi menjadi loop sementara dan ditambahkan
$*
(ARGV) sebagai input dan saya sebagai hitungan berapa kali jumlah telah dibelah dua sebelum menjadi aneh.Saya cukup bangga dengan ini dan hampir menyerahkannya sebelum saya tersadar bahwa semua pembagian oleh dua ini terdengar agak biner bagi saya, sebagai seorang insinyur perangkat lunak, tetapi bukan seorang ilmuwan komputer, ini bukan hal pertama yang muncul dalam pikiran.
Jadi saya mengumpulkan beberapa hasil tentang seperti apa nilai input dalam biner:
Saya perhatikan bahwa hasilnya adalah jumlah posisi di sebelah kiri yang harus kami lalui sebelum jumlahnya menjadi ganjil.
Melakukan beberapa manipulasi string sederhana saya membagi string pada kemunculan terakhir 1 dan menghitung panjang 0s yang tersisa:
menggunakan
("%b" % x)
pemformatan untuk mengubah angka menjadi biner, dan String # slice untuk mengiris string saya.Saya telah belajar beberapa hal tentang ruby dalam pencarian ini dan berharap untuk lebih banyak golf segera!
sumber
@wizzwizz4
di awal komentar untuk membalas saya. (Ini berfungsi dengan semua nama pengguna!)J, 6 byte
Penjelasan:
sumber
C, 37 byte
f(int x){return x?x&1?0:1+f(x/2):0;}
Periksa bit terakhir secara rekursif hingga bukan 0.sumber
f(int n){return __builtin_ctz(n);}
jika Anda bersedia menggunakan ekstensi gcc. Atau bahkan#define f __builtin_ctz
int
. Itu implisit, sama seperti tipe pengembalian.f(n){...}
? GCC tidak akan mengompilasinya. Saya bukan pakar C, tetapi pencarian cepat mengungkapkan bahwa mungkin fitur ini telah dihapus di versi C. yang lebih baru. Jadi mungkin itu akan dikompilasi dengan bendera yang sesuai?-ansi
atau-gnu99
? Saya tahu saya berhasil. Saya menulis sebuah tip jawaban tentang itu!Haskell, 28 byte
Contoh penggunaan:
f 94208
->12
.Jika nomornya ganjil, hasilnya adalah
0
, selain itu1
ditambah panggilan rekursif dengan setengah nomor.sumber
div x 2
? Mengapa tidakx/2
?div
adalah divisi integer, divisi/
floating point.Befunge, 20
Eksekusi kode terus bergerak ke kanan dan membungkus ke karakter kedua dari baris pertama (terima kasih untuk trailing
#
) sampai2%
output1
, yang menyebabkan_
untuk beralih ke kiri, lalu|
ke atas, yang membungkus ke pada<
pada baris kedua, yang keluar dan keluar. Kami menambah elemen tumpukan kedua ke atas setiap kali melalui loop, kemudian membaginya dengan 2.sumber
Retina ,
2917Cobalah online!
2 byte disimpan berkat Martin!
Mengambil input yang tidak disadari. Ini berulang kali cocok dengan jumlah terbesar yang
1
bisa dimiliki sehingga jumlah yang1
cocok persis dengan jumlah sisanya1
. Setiap kali ia melakukan ini, ia menambahkan;
ke string. Pada akhirnya, kami menghitung jumlah;
s dalam string.Jika Anda ingin input desimal, tambahkan:
ke awal program.
sumber
Jolf, 6 byte
Coba di sini!
Agak sederhana ... Kudos to ETHProduk untuk mengusir Jolf dengan versi yang benar-benar berfungsi!
sumber
PARI / GP, 17 byte
sumber
6502 bahasa mesin, 7 byte
Untuk menemukan nilai tempat 1 bit paling signifikan dari nilai bukan nol di akumulator, biarkan hasilnya di register X:
Untuk menjalankan ini pada 6502 simulator di e-tradition.net , awali dengan
A9
diikuti oleh integer 8-bit.Ini membongkar sebagai berikut:
Ini setara dengan C berikut, kecuali bahwa C
int
harus setidaknya 16-bit:Hal yang sama bekerja pada 65816, dengan asumsi MX = 01 (akumulator 16-bit, indeks 8-bit), dan setara dengan potongan C di atas.
sumber
Brachylog ,
2715 bytePenjelasan
sumber
CJam, 8 byte
Baca integer, nilai absolut, faktorisasi prima, hitung berpasangan.
sumber
JavaScript ES6, 36
38byteGolf dua byte berkat produk @ETH
Jawabannya cukup membosankan, tetapi berhasil. Mungkin sebenarnya terlalu mirip dengan jawaban lain, jika dia menambahkan perubahan yang disarankan maka saya akan menghapus milik saya.
Untuk menjalankan, tetapkan ke variabel (
a=>{for...
) karena ini merupakan fungsi anonim, lalu panggil dengana(100)
.sumber
b%2==0
dapat diubah menjadib%2-1
, danc++
dapat dipindahkan ke dalam bagian terakhir darifor
pernyataan. Saya pikir ini juga akan berhasil:b=>eval("for(c=0;b%2-1;b/=2)++c")
b%2-1
=>~b&1
Juga, saya pikir ini gagal pada input0
, yang dapat diperbaiki denganb&&~b&1
b%2-1
periksa gagal untuk nomor ganjil negatif.ES6, 22 byte
Mengembalikan -1 jika Anda lulus 0.
sumber
DUP , 20 byte
Try it here!
Dikonversi menjadi rekursi, output sekarang menjadi nomor teratas di stack. Pemakaian:
Penjelasan
sumber
Japt,
95 byteUji secara online!
Versi sebelumnya seharusnya lima byte, tetapi yang ini benar-benar berfungsi.
Bagaimana itu bekerja
sumber
C,
444038 36 byte2 byte off terima kasih @JohnWHSmith . 2 byte off terima kasih @luserdroog .
Tes langsung pada ideone .
sumber
!(n%2)
dengan yang kecil~n&1
.=0
. Global secara implisit diinisialisasi ke 0.a
, bukankah hanya dijamin berfungsi saat pertama kali dipanggil? Saya tidak tahu itu diizinkan.