Ini adalah versi dari tantangan terakhir. Apakah angka ini bilangan bulat dari -2? dengan serangkaian kriteria yang berbeda yang dirancang untuk menyoroti sifat menarik dari masalah dan membuat tantangan lebih sulit. Saya menaruh beberapa pertimbangan di sini .
Tantangan seperti yang dinyatakan oleh Toby dalam pertanyaan terkait, adalah:
Ada cara pintar untuk menentukan apakah integer adalah kekuatan tepat dari 2. Itu bukan lagi masalah yang menarik, jadi mari kita tentukan apakah integer yang diberikan adalah kekuatan yang tepat dari -2 . Sebagai contoh:
-2 => yes: (-2)¹ -1 => no 0 => no 1 => yes: (-2)⁰ 2 => no 3 => no 4 => yes: (-2)²
Aturan:
- Integer adalah 64 bit, ditandatangani, komplemen dua. Ini adalah satu - satunya tipe data yang dapat Anda gunakan.
- Anda hanya dapat menggunakan operasi berikut. Masing-masing dihitung sebagai satu operasi.
n << k
,n >> k
: Pergeseran kiri / kanann
menurutk
bit. Bit tanda diperpanjang di shift kanan.n >>> k
: Bergeser ke kanan tetapi tidak memperpanjang bit tanda. 0 bergeser masuk.a & b
,a | b
,a ^ b
: Bitwise AND, OR, XOR.a + b
,a - b
,a * b
: Menambah, mengurangi, mengalikan.~b
: Bitwise terbalik-b
: Negasi komplemen dua.a / b
,a % b
: Membagi (hasil bagi bilangan bulat, putaran ke 0), dan modulo.- Modulo angka negatif menggunakan aturan yang ditentukan dalam C99 :
(a/b) * b + a%b
harus samaa
. Begitu5 % -3
juga2
, dan-5 % 3
adalah-2
: 5 / 3
is1
,5 % 3
is2
, karena 1 * 3 + 2 = 5.-5 / 3
is-1
,-5 % 3
is-2
, -1 -1 3 + -2 = -5.5 / -3
is-1
,5 % -3
is2
, -1 -1 -3 + 2 = 5.-5 / -3
is1
,-5 % -3
is-2
, sebagai 1 * -3 + -2 = -5.- Perhatikan bahwa
//
operator pembagian lantai Python tidak memenuhi properti pembagian "putaran menuju 0" di sini, dan%
operator Python juga tidak memenuhi persyaratan.
- Modulo angka negatif menggunakan aturan yang ditentukan dalam C99 :
- Tugas tidak dihitung sebagai operasi. Seperti dalam C, tugas mengevaluasi ke nilai sisi kiri setelah penugasan:
a = (b = a + 5)
setb
kea + 5
, lalu seta
keb
, dan dihitung sebagai satu operasi. - Penugasan majemuk dapat digunakan
a += b
saranaa = a + b
dan dihitung sebagai satu operasi.
- Anda dapat menggunakan konstanta integer, mereka tidak dihitung sebagai apa pun.
- Tanda kurung untuk menentukan urutan operasi dapat diterima.
- Anda dapat mendeklarasikan fungsi. Deklarasi fungsi bisa dalam gaya apa pun yang nyaman untuk Anda tetapi perhatikan bahwa integer 64 bit adalah satu - satunya tipe data yang valid. Deklarasi fungsi tidak dihitung sebagai operasi, tetapi sebuah fungsi panggilan dianggap sebagai satu. Juga, harus jelas: Fungsi dapat berisi beberapa
return
pernyataan danreturn
s dari titik mana pun diizinkan. Itureturn
sendiri tidak dihitung sebagai operasi. - Anda dapat mendeklarasikan variabel tanpa biaya.
- Anda dapat menggunakan
while
loop, tetapi Anda tidak dapat menggunakanif
ataufor
. Operator yang digunakan dalamwhile
kondisi tersebut menghitung skor Anda.while
loop dijalankan selama kondisinya mengevaluasi ke a tidak nol ("benar" 0 dalam bahasa yang memiliki konsep ini bukan hasil yang valid). Sejak awal-return diperbolehkan, Anda diijinkan untuk menggunakanbreak
juga - Overflow / underflow diizinkan dan tidak ada penjepitan nilai yang akan dilakukan. Itu diperlakukan seolah-olah operasi benar-benar terjadi dengan benar dan kemudian dipotong menjadi 64 bit.
Kriteria Penilaian / Kemenangan:
Kode Anda harus menghasilkan nilai yang bukan nol jika inputnya adalah kekuatan -2, dan nol sebaliknya.
Ini adalah atom-kode-golf . Skor Anda adalah jumlah total operasi yang ada dalam kode Anda (sebagaimana didefinisikan di atas), bukan jumlah total operasi yang dijalankan pada saat run-time. Kode berikut:
function example (a, b) {
return a + ~b;
}
function ispowerofnegtwo (input) {
y = example(input, 9);
y = example(y, 42);
y = example(y, 98);
return y;
}
Berisi 5 operasi: dua di fungsi, dan tiga panggilan fungsi.
Tidak masalah bagaimana Anda mempresentasikan hasil Anda, gunakan apa pun yang nyaman dalam bahasa Anda, baik itu akhirnya menyimpan hasil dalam variabel, mengembalikannya dari suatu fungsi, atau apa pun.
Pemenangnya adalah pos yang terbukti benar (berikan bukti kasual atau formal jika perlu) dan memiliki skor terendah seperti dijelaskan di atas.
Bonus Tantangan Mode Sangat Keras!
Untuk kesempatan memenangkan apa pun kecuali kemampuan potensial untuk mengesankan orang di pesta, kirimkan jawaban tanpa menggunakan while
loop! Jika cukup dari ini diajukan saya bahkan dapat mempertimbangkan membagi kelompok yang menang menjadi dua kategori (dengan dan tanpa loop).
Catatan: Jika Anda ingin memberikan solusi dalam bahasa yang hanya mendukung bilangan bulat 32-bit, Anda dapat melakukannya, asalkan Anda cukup membenarkan bahwa bilangan bulat 64-bit akan tetap benar untuk penjelasan.
Juga: Beberapa fitur bahasa tertentu dapat diizinkan tanpa biaya jika mereka tidak menghindari aturan tetapi diperlukan untuk memaksa bahasa Anda ke dalam berperilaku sesuai dengan aturan di atas . Sebagai contoh (dibuat-buat), saya akan mengizinkan gratis tidak sama dengan 0 perbandingan dalam while
loop, ketika diterapkan pada kondisi secara keseluruhan, sebagai solusi untuk bahasa yang memiliki "benar" 0's. Upaya yang jelas untuk mengambil keuntungan dari hal-hal semacam ini tidak diperbolehkan - mis. Konsep nilai "benar" 0 atau "tidak terdefinisi" tidak ada dalam aturan di atas, dan karenanya tidak dapat diandalkan.
m ^= s
itu masih mengesankan, dan saya pikir itu akan benar-benar baik untuk membuat substitusi untuk memperbaikinya lebih.while
danbreak
tetapi tidakif
?if (x) { ... }
setara denganwhile (x) { ... break; }
.break
dan pengembalian awal adalah bagian yang disesalkan) dan merupakan cerita panjang dan pelajaran yang dipetik dalam aturan untuk tantangan di masa depan. Selalu ada versi "bonus"! :)if
danfor
tidak diizinkan?int x=condition; while (x) { ... x=0; }
gratis, hanya lebih banyak kode. Sama halnya dengan c-stylefor
.Jawaban:
C ++, 15 operasi
Saya tidak tahu mengapa
while
loop diizinkan karena mereka menghancurkan seluruh tantangan. Inilah jawaban tanpa:sumber
while
loop menghancurkan seluruh tantangan ?while
bertentangan dengan itu dalam segala hal.n
atau sesuatu.uint64_t
karena itulah satu-satunya cara untuk mendapatkan giliran yang tepat tanpa ekstensi tanda.)Operasi Python 2 , 3
Cobalah online!
Operasi yang
>>
,&
,/
.Idenya adalah untuk berulang kali membaginya dengan -2. Powers -2 rantai turun ke 1:
-8 -> 4 -> -2 -> 1
. Jika kita menekan a1
, terima. Jika kami menekan nomor ganjil sebelum memukul1
, tolak. Kita juga perlu menolak0
, yang selamanya berlaku untuk dirinya sendiri.The
while n>>1:
loop sampain
adalah 0 atau 1. Ketika loop istirahat,n
itu sendiri dikembalikan, dan1
merupakan output truthy dan0
satu Falsey. Di dalam loop, kami menolak berulang kali menerapkann -> n/-2
dan menolak yang anehn
.Karena
/
hanya digunakan pada nilai yang sama, perilaku pembulatannya tidak pernah berlaku. Jadi, tidak masalah bahwa putaran Python berbeda dari spec.sumber
while n&1
bukannyaif n&1
?if
.Karat,
1412 operasi (tanpa loop)Memerlukan pengoptimalan (
-O
) atau-C overflow-checks=no
untuk mengaktifkan pengurangan yang berlebihan alih-alih panik.(Untuk memperjelas:
!x
adalah bitwise-tidak di sini, tidak logis-TIDAK)Kasus uji:
Cobalah online!
Idenya adalah untuk memeriksa apakah | x | adalah kekuatan 2 (menggunakan
(y & (y - 1)) == 0
seperti biasa). Jika x adalah kekuatan 2, maka kami selanjutnya memeriksa (1) kapanx >= 0
, itu juga harus menjadi kekuatan genap 2, atau (2) kapanx < 0
, itu harus menjadi kekuatan aneh dari 2. Kami memeriksa ini dengan&
-ing the "bad_power_of_two
"mask 0x… aaaa whenx >= 0
(menghasilkan 0 hanya ketika itu adalah kekuatan genap), atau 0x ... 5555 kapanx < 0
.sumber
~((r | -r) >> 63)
trik Anda untuk menyelesaikan memperbaiki jawaban saya.Haskell,
23 operasiMenentukan fungsi rekursif
f(n)
. Operasi yang digunakan adalah pemanggilan fungsi (f
), pembagian (div
), dan bitwise dan (.&.
).Tidak mengandung loop karena fakta bahwa Haskell tidak memiliki pernyataan loop :-)
sumber
f 0
,f 1
,f n ...
di sini karena mereka pada dasarnyaif
's menyamar, meskipun sekali lagi, saya membiarkanwhile
+break
dan awalreturn
s, sehingga tampaknya adil. Meskipun tampaknya memanfaatkan aturan saya yang secara tidak sengaja dibiarkan terbuka untuk interpretasi, itu adalah solusi yang bagus.|
s terutama di udara. Yang mengatakan, ini memang melanggar satu aturan tertentu dengan cara yang tidak terlalu diperdebatkan: Perbandingan==
tidak diperbolehkan. Catatan, bagaimanapun, bahwa jika interpretasi saya kode ini benar, penggunaan boolean sini tidak muncul diterima sebagai substitusi nilai integer sewenang-wenang di tempat mereka tidak muncul untuk mengubah hasil, dan mereka lebih dari bentuk presentasi akhir.==
karena tidak ada cara lain untuk melemparkan dariInt
keBool
atau "Kebenaran" di Haskell. Apakah pencocokan pola dan penjaga melanggar aturan "tidak adaif
" adalah panggilan Anda ;-)Python 3,
Operasi10 atau 119Pengembalian
5
untuk kekuatan-2
,0
jika tidaksumber
C, 5 operasi
C, 10 operasi, tanpa loop
C, 1 operasi
sumber
Majelis, 1 operasi
Menggunakan tabel pencarian besar untuk menemukan apakah angka itu kekuatan 2. Anda dapat memperluas ini menjadi 64 bit, tetapi menemukan komputer untuk menyimpan banyak data yang tersisa sebagai latihan untuk pembaca :-P
sumber
C, 31 operasi
Demo Langsung
Ide saya sederhana, jika itu kekuatan dua, maka jika log-nya genap maka harus positif, kalau tidak log-nya harus aneh.
sumber
C, 7 operasi
atau:
C, 13 operasi tanpa kondisi loop-as-conditional
Penjelasan:
n&-n
menghasilkan bit set terendahn
.a
adalah nilai absolut dinegasikann/2
, tentu negatif karena/2
menghalangi limpahan negasi.a/x
adalah nol hanya jikaa
kekuatan tepat dua; jika tidak, setidaknya satu bit lainnya diatur, dan itu lebih tinggi darix
, bit terendah, menghasilkan hasil negatif.~(a/x >> 63)
kemudian menghasilkan bitmask itu semua-yang jikan
atau-n
adalah kekuatan dua, jika tidak semua-nol.^s
diterapkan ke topeng untuk memeriksa tandan
untuk melihat apakah itu kekuatan-2
.sumber
PHP, 3 operasi
ternary dan
if
dilarang; jadi mari kita menyalahgunakanwhile
:$n>>1
: jika angka 0 atau 1, kembalikan angka$n&1
: jika angka ganjil, kembalikan 0$n/-2
(+ cor ke int)sumber
JavaScript ES6, 7 operasi
Cobalah online!
Penjelasan
Sementara x! = 0 dan x% 2 == 0 4 ops
x / x sama dengan 1 selama x tidak 0 (0/0 memberikan NaN yang dievaluasi salah)
& bitwise dan
x & 1 ^ 1 sama dengan 1 jika x genap (x dan 1) xor 1
Ini adalah bentuk pembagian yang didefinisikan oleh pertanyaan 1 op
Sedangkan x! = 1 dan x! = 0 1 op
Kondisi yang diperlukan untuk keluar ketika x == 0 atau x == 1 karena keduanya adalah nilai balik dan memasukkan infinite loop tidak akan produktif. Secara teoritis ini dapat diperpanjang untuk nilai yang lebih besar dengan meningkatkan angka heksadesimal. Saat ini berfungsi hingga ± 2 ^ 32-1
Set x ke 0 1 op
Sementara saya bisa menggunakan kembali 0 untuk 0 ops, saya merasa bahwa loop sementara yang rusak oleh pernyataan lain terasa terlalu banyak seperti curang.
mengembalikan x (1 jika kekuatan -2, 0 sebaliknya)
sumber