Bu sayı -2 olarak kesin bir güç mü: (Çok) Sert Mod


26

Bu son mücadelenin bir versiyonu. Bu sayı -2 olan bir tamsayı mı? sorunun ilginç yapısını vurgulamak ve mücadeleyi zorlaştırmak için tasarlanmış farklı bir kriter seti ile. Bu konuda biraz dikkate koymak burada .

Toby'nin bağlantılı soruda harika bir şekilde ifade ettiği zorluk:

Bir tamsayının 2 tam gücü olup olmadığını belirlemenin akıllı yolları var. Bu artık ilginç bir sorun değil, o zaman verilen bir tamsayının -2 tam bir gücü olup olmadığını belirleyelim . Örneğin:

-2 => yes: (-2)¹
-1 => no
0 => no
1 => yes: (-2)⁰
2 => no
3 => no
4 => yes: (-2)²

Kurallar:

  • Bir tamsayı 64 bit, imzalanmış, ikisinin tamamlayıcısıdır. Bu çalışabileceğiniz tek veri türüdür.
  • Sadece aşağıdaki işlemleri kullanabilirsiniz. Bunların her biri bir işlem olarak sayılır.
    • n << k, n >> k: Sol / sağ shift ntarafından kbit. İşaret biti sağa kaydırmada uzatılmıştır.
    • n >>> k: Sağa kaydırma ancak işaret bitini uzatma. 0'lar içeri kaydırıldı.
    • a & b, a | b, a ^ b: Bitwise AND, OR, XOR.
    • a + b, a - b, a * b: Çarpma, çıkarma, ekleyin.
    • ~b: Bit yönünde ters çevir.
    • -b: İkisinin tamamlayıcı olumsuzlaması.
    • a / b, a % b: Böl (tamsayı bölümü, 0'a yuvarlar) ve modulo.
      • Negatif sayılardan oluşan Modulo, C99'da belirtilen kuralları kullanır : (a/b) * b + a%beşit olacaktır a. Yani 5 % -3bir 2ve -5 % 3olduğu -2:
      • 5 / 3olduğu 1, 5 % 3olduğu 2, 1 ila * 3 + 2 = 5.
      • -5 / 3olduğu -1, -5 % 3olduğu -2, -1 * 3 ± 2 = -5.
      • 5 / -3olduğu -1, 5 % -3olduğu 2, -1 * -3 + 2 = 5.
      • -5 / -3olduğu 1, -5 % -3olduğu -2, 1 ila * -3 ± 2 = -5.
      • Python'un //kat bölümü operatörünün, bu bölümdeki "0'a doğru yuvarlama" özelliğini %karşılamadığını ve Python'un operatörünün de gereksinimleri karşılamadığını unutmayın.
    • Atamalar bir işlem olarak sayılmaz. C olduğu gibi, atamalar görevden sonra sol tarafta değerine değerlendirmek: a = (b = a + 5)setleri biçin a + 5, daha sonra setleri aiçin bbir işlem olarak ve sayımları.
    • Bileşik atamaları kullanılabilmektedir a += baracı a = a + bve bir işlem olarak sayılır.
  • Tamsayı sabitlerini kullanabilirsiniz, hiçbir şey olarak sayılmazlar.
  • İşlem sırasını belirtmek için parantezler kabul edilebilir.
  • İşlevleri ilan edebilirsiniz. İşlev bildirimleri sizin için uygun herhangi bir stilde olabilir, ancak 64 bit tam sayıların yalnızca geçerli veri türü olduğunu unutmayın. İşlev bildirimleri işlem olarak sayılmaz, ancak işlev çağrısı biri olarak sayılır. Ayrıca, açık olması gerekirse: İşlevler birden fazla returnifade içerebilir ve returnherhangi bir noktadan izin verilir. returnKendisi bir operasyon olarak sayılmaz.
  • Değişkenleri hiçbir ücret ödemeden beyan edebilirsiniz.
  • whileDöngüler kullanabilirsiniz , ancak ifveya kullanamazsınız for. Bu whiledurumda kullanılan operatörler puanınıza göre sayılır. whiledöngüler durumları sıfır olmayan bir değere sahip olduğu sürece yürütülür (bu kavramın geçerli bir sonucu olmayan dillerde bir "truthy" 0 olması). Erken dönüş izin yana, kullanmak için izin verilir breakve ayrıca
  • Taşma / taşma izin verilir ve değer kenetlemesi yapılmaz. İşlem gerçekten doğru bir şekilde gerçekleşmiş gibi muamele görür ve ardından 64 bite indirilir.

Puanlama / Kazanma Kriterleri:

Girişiniz -2, aksi halde sıfır ise, kodunuz sıfır olmayan bir değer üretmelidir.

Bu . Puanınız, çalışma zamanında yürütülen toplam işlem sayısı değil , kodunuzda bulunan toplam işlem sayısıdır ( yukarıda tanımlandığı gibi) . Aşağıdaki kod:

function example (a, b) {
    return a + ~b;
}

function ispowerofnegtwo (input) {
    y = example(input, 9);
    y = example(y, 42);
    y = example(y, 98);
    return y;
}

5 işlem içerir: iki işlevde ve üç işlev çağrısı.

Sonucunuzu nasıl sunduğunuz önemli değildir, kendi dilinizde uygun olanı kullanın, sonuçta bir değişkeni saklarsanız, bir fonksiyondan döndürürken veya her neyse.

Kazanan, gözle görülür şekilde doğru olan yazıdır (gerekiyorsa geçici veya resmi bir kanıt sunun) ve yukarıda açıklandığı gibi en düşük puana sahip olan yazıdır.

Bonus Çok Zor Mod Mücadelesi!

Partileri insanları etkileme potansiyeli dışında kesinlikle hiçbir şey kazanma şansı için, whiledöngü kullanmadan bir cevap gönderin ! Bunların yeteri kadar sunulması durumunda, kazanan grupları iki gruba ayırmayı düşünebilirim (döngüler olsun ve olmasın).


Not: Yalnızca 32 bit tam sayıyı destekleyen bir dilde bir çözüm sağlamak istiyorsanız, bir açıklamada 64 bit tam sayı için hala doğru olması için yeterince haklı olması koşuluyla bunu yapabilirsiniz.

Ayrıca: Kurallara aykırı değilse, ancak dilinizi yukarıdaki kurallara göre davranmaya zorlamak için gerekliyse, belirli bir dile özgü özelliklere ücretsiz olarak izin verilebilir . Mesela ( haklı), "truthy" 0 'lı olan bir dil için geçici bir çözüm olarak koşula bir bütün halinde uygulandığında , döngülerdeki 0 karşılaştırmaya eşit değil . Bu tür şeylerden yararlanmak için açık girişimlere izin verilmez - örneğin, "kural" 0 veya "tanımsız" değerler kavramı yukarıdaki kuralda mevcut değildir ve bu nedenle güvenilmeyebilir.while


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Dennis,

@hvd Eğer bunu okursanız: Cevabınızı tamamen geri almalısınız! Hala etkileyici olmasa bile doğru m ^= solduğunu kabul etmek ve yerini daha da geliştirmek için ikame etmenin tamamen uygun olacağını düşünüyorum.
Jason C

Nasıl anlamda izin vermek yapar whileve breakancak if? if (x) { ... }eşittir while (x) { ... break; }.
R. ..

@R ..% 100 anlam ifade etmiyor ( breakve erken getirileri pişman olan kısmıdır) ve gelecekteki zorluklar için kurallarda öğrenilen uzun bir hikaye ve bir derstir. Her zaman "bonus" versiyonu var! :)
Jason C

1
Neden ifve forizin verilmez? int x=condition; while (x) { ... x=0; }ücretsiz, sadece daha fazla kod. C tarzı ile aynı şey for.
Qwertiy

Yanıtlar:


35

C ++, 15 işlem

Tüm whiledöngüyü yok ederken döngülere neden izin verildiğini bilmiyorum . İşte herhangi bir cevap yok:

int64_t is_negpow2(int64_t n) {
    int64_t neg = uint64_t(n) >> 63; // n >>> 63
    n = (n ^ -neg) + neg; // if (n < 0) n = -n;
    int64_t evenbits = n & int64_t(0xaaaaaaaaaaaaaaaaull >> neg);
    int64_t n1 = n - 1;
    int64_t pot = n & n1;
    int64_t r = pot | (n1 >> 63) | evenbits;
    return ~((r | -r) >> 63); // !r
}

whileDöngüler neden tüm mücadeleyi mahveder ?
Bay Xcoder

10
@ Mr.Xcoder Çünkü zorluk basit bitsel işlemlerle yapmak ve whilebununla her şekilde mücadele etmek.
orlp

Eğer süre döngülerini yapmazsanız, işlem sayısını, döngüde yürütülen sayı sürelerini statik nveya başka bir şey için çarpın .
Magic Octopus Urn

Bu konuda bir yorum yaptı burada .
Jason C

@JasonC Bunun nedeni işaret biti olmadan doğru bir kaydırma kullanmam gerekirdi. Kodu değiştirdim (kullandığı uint64_tiçin doğru işaretini kullanmadan değiştirmenin tek yolu budur.)
orlp

25

Python 2 , 3 işlemleri

def f(n):
 while n>>1:
  while n&1:return 0
  n=n/-2
 return n

Çevrimiçi deneyin!

Operasyonlardır >>, &, /.

Fikir art arda -2'ye bölünür. -2 zincirinin güçleri 1'e düştü -8 -> 4 -> -2 -> 1. Eğer bir isabet ederse 1kabul et. Vurmadan önce tek bir sayıya vursak 1reddet. Aynı zamanda 0, sonsuza dek kendisine giden reddetmemiz gerekiyor .

while n>>1:Kadar döngüler ndöngü sonları, zaman, 0 ya da 1'dir nkendisi döndürülür ve 1bir Truthy çıkar ve0 bir Falsey bir. Döngü içinde, tekrar tekrar uygulayarak n -> n/-2reddeder ve herhangi bir tuhaflığı reddederiz n.

Bu /sadece şimdiye kadar bile değerlerde kullanıldığından, yuvarlama davranışı hiçbir zaman devreye girmez. Bu yüzden, Python'un özelliklerinden farklı bir şekilde yuvarlanması önemli değil.


Güzel. Algoritmadaki akıllı mantık ve koşullamaları bit işlemlerinde birleştiren iyi iş. Ayrıca, uygulama C de çalışabildiğini onaylayabilir
Jason C 19

Neden while n&1yerine if n&1?
Mark Ransom,

2
@MarkRansom Zorluk izin vermiyor if.
xnor

Aha, bunu özledim. Çok zekice oyuncu değişikliği.
Mark Ransom,

1
@EvSunWoodard Puanlama, kodlamadaki operatörlerin sayısıdır, yürütme sırasındaki çağrı sayıları değil, girişe bağlıdır: "Bu, atom-kod-golf. Puanınız, kodunuzda bulunan toplam işlem sayısıdır. ."
xnor

11

Pas, 14 12 işlem (döngü yok)

Optimizasyon gerektirir ( -O) veya -C overflow-checks=nopanik yerine taşan çıkarma işlemini etkinleştirmek için.

fn is_power_of_negative_2(input: i64) -> i64 {
    let sign = input >> 63;
    // 1 op
    let abs_input = (input ^ sign) - sign;
    // 2 ops
    let bad_power_of_two = sign ^ -0x5555_5555_5555_5556; // == 0xaaaa_aaaa_aaaa_aaaa
    // 1 op
    let is_not_power_of_n2 = abs_input & ((abs_input - 1) | bad_power_of_two);
    // 3 ops 
    let is_not_power_of_n2 = (is_not_power_of_n2 | -is_not_power_of_n2) >> 63;
    // 3 ops 
    input & !is_not_power_of_n2
    // 2 ops
}

(Netleştirmek için: !xburada bitsel-DEĞİL , mantıklı değil-DEĞİL)

Test durumları:

#[test]
fn test_is_power_of_negative_2() {
    let mut value = 1;
    for _ in 0 .. 64 {
        assert_ne!(0, is_power_of_negative_2(value), "wrong: {} should return nonzero", value);
        value *= -2;
    }
}

#[test]
fn test_not_power_of_negative_2() {
    for i in &[0, -1, 2, 3, -3, -4, 5, -5, 6, -6, 7, -7, 8, 1<<61, -1<<62, 2554790084739629493, -4676986601000636537] {
        assert_eq!(0, is_power_of_negative_2(*i), "wrong: {} should return zero", i);
    }
}

Çevrimiçi deneyin!


Fikir olup olmadığını kontrol etmektir | x | 2'nin gücüdür ( (y & (y - 1)) == 0her zamanki gibi). X 2 nin kuvveti, o zaman diğer kontrol (1) ise x >= 0, o da olmalı 2'nin daha da güç, ya da (2) x < 02'nin, olması gerektiği tuhaf güç Biz bunu kontrol &"-ing bad_power_of_two"maske 0x… aaaa ne zaman x >= 0(yalnızca eşit güç olduğunda 0 üretir) veya ne zaman 0x… 5555 x < 0.


~((r | -r) >> 63)Cevabımı düzeltmeyi bitirmek için numaranı çaldım .
orlp

6

Haskell, 2 3 işlem

import Data.Bits (.&.)

f 0 = False
f 1 = True
f n | n .&. 1 == 0 = f (n `div` -2)
f n | otherwise    = False

Özyinelemeli bir işlev tanımlar f(n). Kullanılan işlemler; işlev çağrısı ( f), division ( div) ve bit yönünde ve ( .&.) işlevidir .

Haskell'in döngü ifadeleri içermemesi nedeniyle döngü içermez :-)


4
Neden Haskell çözümünün döngüler kullanmadığını "Fırsatçı" adlı biri tarafından sağladığını şaşırtmadım =)
Cort Ammon - Monica

1
Ben çok ilgili tereddütlü f 0, f 1, f n ...bunlar aslında olduklarından burada ifsonra tekrar, ben izin vermedi rağmen ', kılık değiştirdi while+ breakve erken returno fuara görünüyor böylece, s. Kural setimden yanlışlıkla yorumlamaya açık kalmamdan yararlanıyor gibi görünse de, güzel bir çözüm.
Jason C

3
Özellikle, |s özellikle havadadır. Bu, belirli bir kuralı daha az tartışmalı bir şekilde ihlal ettiğini söyledi: Karşılaştırma ==yapılamaz. Bu kodun benim yorumlanması doğru olup olmadığını Bununla birlikte, bu, boole kullanım burada yapar sonuçlarını değiştirmeye görünmüyor onların yerine keyfi tamsayı değerleri ikame olarak kabul edilebilir görünür ve daha nihai sunum formunun bulunmaktadır.
Jason C

@JasonC Sadece kullanıyorum ==gelen döküm için başka yol yoktur çünkü Inthiç Boolveya Haskell "Truthy". Örüntü eşleştirme ve korumaların "hayır if" kuralına aykırı olup olmadığı sizin çağrınızdır ;-)
Opportunist

18
Desen eşleştirmesiyle, 0 işlemi kullanarak tüm 64 bit tam sayıların sonuçlarını yalnızca kodlayabilirsiniz.
xnor

5

Python 3, 10 veya 11 9 işlemleri

def g(x):
 while x:
  while 1 - (1 + ~int(x - -2 * int(float(x) / -2))) & 1: x /= -2
  break
 while int(1-x):
     return 0
 return 5  # or any other value

İade 5yetkileri için -2, 0aksi


Yorumlar uzun tartışmalar için değildir; bu konuşma sohbete taşındı .
Dennis,

5

C, 5 işlem

long long f(long long x){
    x=x ^ ((x & 0xaaaaaaaaaaaaaaaa) * 6);
    while(x){
        while(x&(x-1))
            return 0;
        return 1;
    }
    return 0;
}

C, 10 işlem, döngüsüz

long long f(long long x){
    x = x ^ ((x & 0xaaaaaaaaaaaaaaaa) * 6);
    long long t = x & (x-1);
    return (((t-1) & ~t) >> 63) * x;
}

C, 1 işlem

long long f(long long x){
    long long a0=1, a1=-2, a2=4, a3=-8, a4=16, a5=-32, a6=64, a7=-128, a8=256, a9=-512, a10=1024, a11=-2048, a12=4096, a13=-8192, a14=16384, a15=-32768, a16=65536, a17=-131072, a18=262144, a19=-524288, a20=1048576, a21=-2097152, a22=4194304, a23=-8388608, a24=16777216, a25=-33554432, a26=67108864, a27=-134217728, a28=268435456, a29=-536870912, a30=1073741824, a31=-2147483648, a32=4294967296, a33=-8589934592, a34=17179869184, a35=-34359738368, a36=68719476736, a37=-137438953472, a38=274877906944, a39=-549755813888, a40=1099511627776, a41=-2199023255552, a42=4398046511104, a43=-8796093022208, a44=17592186044416, a45=-35184372088832, a46=70368744177664, a47=-140737488355328, a48=281474976710656, a49=-562949953421312, a50=1125899906842624, a51=-2251799813685248, a52=4503599627370496, a53=-9007199254740992, a54=18014398509481984, a55=-36028797018963968, a56=72057594037927936, a57=-144115188075855872, a58=288230376151711744, a59=-576460752303423488, a60=1152921504606846976, a61=-2305843009213693952, a62=4611686018427387904, a63=-9223372036854775807-1, a64=0;
    while(a0){
        long long t = x ^ a0;
        long long f = 1;
        while(t){
            f = 0;
            t = 0;
        }
        while(f)
            return 1;
        a0=a1; a1=a2; a2=a3; a3=a4; a4=a5; a5=a6; a6=a7; a7=a8; a8=a9; a9=a10; a10=a11; a11=a12; a12=a13; a13=a14; a14=a15; a15=a16; a16=a17; a17=a18; a18=a19; a19=a20; a20=a21; a21=a22; a22=a23; a23=a24; a24=a25; a25=a26; a26=a27; a27=a28; a28=a29; a29=a30; a30=a31; a31=a32; a32=a33; a33=a34; a34=a35; a35=a36; a36=a37; a37=a38; a38=a39; a39=a40; a40=a41; a41=a42; a42=a43; a43=a44; a44=a45; a45=a46; a46=a47; a47=a48; a48=a49; a49=a50; a50=a51; a51=a52; a52=a53; a53=a54; a54=a55; a55=a56; a56=a57; a57=a58; a58=a59; a59=a60; a60=a61; a61=a62; a62=a63; a63=a64;
    }
    return 0;
}

2
Ah, bu sonuncusu sadece bir şeytan. Güzel.
Jason C,

4

Montaj, 1 işlem

.data

    .space 1         , 1 # (-2)^31
    .space 1610612735, 0
    .space 1         , 1 # (-2)^29
    .space 402653183 , 0
    .space 1         , 1 # (-2)^27
    .space 100663295 , 0
    .space 1         , 1 # (-2)^25
    .space 25165823  , 0
    .space 1         , 1 # (-2)^23
    .space 6291455   , 0
    .space 1         , 1 # (-2)^21
    .space 1572863   , 0
    .space 1         , 1 # (-2)^19
    .space 393215    , 0
    .space 1         , 1 # (-2)^17
    .space 98303     , 0
    .space 1         , 1 # (-2)^15
    .space 24575     , 0
    .space 1         , 1 # (-2)^13
    .space 6143      , 0
    .space 1         , 1 # (-2)^11
    .space 1535      , 0
    .space 1         , 1 # (-2)^9
    .space 383       , 0
    .space 1         , 1 # (-2)^7
    .space 95        , 0
    .space 1         , 1 # (-2)^5 = -32
    .space 23        , 0
    .space 1         , 1 # (-2)^3 = -8
    .space 5         , 0
    .space 1         , 1 # (-2)^1 = -2
    .space 1         , 0
dataZero:
    .space 1         , 0
    .space 1         , 1 # (-2)^0 = 1
    .space 2         , 0
    .space 1         , 1 # (-2)^2 = 4
    .space 11        , 0
    .space 1         , 1 # (-2)^4 = 16
    .space 47        , 0
    .space 1         , 1 # (-2)^6 = 64
    .space 191       , 0
    .space 1         , 1 # (-2)^8
    .space 767       , 0
    .space 1         , 1 # (-2)^10
    .space 3071      , 0
    .space 1         , 1 # (-2)^12
    .space 12287     , 0
    .space 1         , 1 # (-2)^14
    .space 49151     , 0
    .space 1         , 1 # (-2)^16
    .space 196607    , 0
    .space 1         , 1 # (-2)^18
    .space 786431    , 0
    .space 1         , 1 # (-2)^20
    .space 3145727   , 0
    .space 1         , 1 # (-2)^22
    .space 12582911  , 0
    .space 1         , 1 # (-2)^24
    .space 50331647  , 0
    .space 1         , 1 # (-2)^26
    .space 201326591 , 0
    .space 1         , 1 # (-2)^28
    .space 805306367 , 0
    .space 1         , 1 # (-2)^30
    .space 3221225471, 0
    .space 1         , 1 # (-2)^32

.globl isPowNeg2
isPowNeg2:
    movl dataZero(%edi), %eax
    ret

Sayının 2 olup olmadığını bulmak için çok büyük bir arama tablosu kullanır. Bunu 64 bite kadar genişletebilirsiniz, ancak bu kadar veriyi okuyucunun alıştırması olarak bırakacak bir bilgisayar bularak bulabilirsiniz :-P


1
Bir tabloyu indekslemek izin verilen işlemlerden biri değil.
R. ..

1
Ayrıca, bu açıkça 64 bit'e genişletilemez. :-)
R ..

Gerçekten de, bir tablo indeksleme değildi amaçlanan cari kurallara göre izin verilecek. "Değişkenleri bildirebilirsin" ve "tamsayı değişmezlerini belirtebilirsiniz" ifadelerini skalerlerin amacı ile belirledim ve anlamsal olarak bu bir dizi (ve bilişimsel olarak, dizi türlerine izin vermedim ya da herhangi bir türden dizine izin vermedim. operasyonları "assembler bağlamında" ekleme "olarak adlandırabilseniz de)), ancak Fırsatçı siz olun ... :)
Jason C

3

C, 31 işlem

Canlı Demo

Benim fikrim basit, eğer iki kişilik bir güçse, o zaman günlüğü bile o zaman pozitif olmalı, yoksa günlüğü tuhaf olmalıdır.

int isPositive(int x) // 6
{
    return ((~x & (~x + 1)) >> 31) & 1;
}

int isPowerOfTwo(int x) // 5
{
    return isPositive(x) & ~(x & (x-1));
}

int log2(int x) // 3
{
    int i = (-1);

    while(isPositive(x))
    {
        i  += 1;
        x >>= 1;
    }

    return i;
}

int isPowerOfNegativeTwo(int x) // 17
{
    return (  isPositive(x) &  isPowerOfTwo(x) & ~(log2(x) % 2) )
         | ( ~isPositive(x) & isPowerOfTwo(-x) & (log2(-x) % 2) );
}

1
Aslında düşündüğünden daha iyisini yaptın. Bir işlev çağrısı, işlevdeki operatörlerin sayısı olarak değil, sadece 1 olarak sayılır. Yani, doğru saydıysam (iki kez kontrol edersem) isPositive + 5 için isPowerOfTwo + 3 için log2 + 17 için isPowerOfNegativeTwo = 31 için bir şeye sahipsin.
Jason C

1

C, 7 işlem

int64_t is_power_of_neg2(int64_t n)
{
    int64_t x = n&-n;
    while (x^n) {
        while (x^-n)
            return 0;
        return x & 0xaaaaaaaaaaaaaaaa;
    }
    return x & 0x5555555555555555;
}

veya:

C, 13 koşulsuz döngüler olmadan işlemler

int64_t is_power_of_neg2(int64_t n)
{
    int64_t s = ~(n>>63);
    int64_t a = ((n/2)^s)-s;
    int64_t x = n&-(uint64_t)n; // Cast to define - on INT64_MIN.
    return ~(a/x >> 63) & x & (0xaaaaaaaaaaaaaaaa^s);
}

Açıklama:

  • n&-nayarlanan en düşük bit değerini verir n.
  • aOlumsuzluğun ihmali mutlak değerdir, mutlak olarak n/2olumsuzdur; çünkü /2olumsuzlama taşması önlenir.
  • a/xsıfır ancak aikisinin tam gücü ise; aksi halde en az bir başka bit ayarlanmıştır ve en xdüşük bitten daha yüksektir , bu da negatif sonuç verir.
  • ~(a/x >> 63)o zaman , her ikisine birden sahip olan nya da -nher ikisinin gücü olan bir bit maskesi verir .
  • ^snBir güç olup olmadığını görmek için işaretini kontrol etmek için maskeye uygulanır -2.

1

PHP, 3 işlem

üçlü ve ifizin verilmeyen; öyleyse kötüye kullanalım while:

function f($n)
{
    while ($n>>1)               # 1. ">>1"
    {
        while ($n&1)            # 2. "&1"
            return 0;
        return f($n/-2|0);      # 3. "/-2" ("|0" to turn it into integer division)
    }
    return $n;
}
  1. $n>>1: eğer sayı 0 veya 1 ise, dönüş numarası
  2. $n&1: sayı tek ise 0 döndür
  3. baska test $n/-2(+ int a bas)

0

JavaScript ES6, 7 işlem

x=>{
  while(x&1^1&x/x){
    x/=-2;x=x|0
  }
  while(x&0xfffffffe)x-=x
  return x
}

Çevrimiçi deneyin!

açıklama

while(x&1^1&x/x)

X! = 0 ve x% 2 == 0 4 ops
x / x, 0 olmadığı sürece 1'e eşittir (0/0, yanlış olarak değerlendirilen NaN verir)
ve bit
yönünde ve x & 1 ^ 1, 1'e eşittir. eğer x, (x ve 1) x veya 1 ise

x/=-2;x=x|0

Bu 1 op sorusu tarafından tanımlanan bölünme şeklidir

while(x&0xfffffffe)  

Öte yandan, x! = 1 ve x! = 0 1 op
x == 0 veya x == 1 olduğunda bu iki değerin geri dönüş değerleri olduğu ve sonsuz bir döngüye girmenin çıkması verimli olmaz. Bu, onaltılık sayıyı artırarak teorik olarak daha büyük değerler için genişletilebilir. Şu anda ± 2 ^ 32-1'e kadar çalışıyor

x-=x

0'a 0 1 op olarak ayarlayın
0 ops için return 0 kullanmış olsam da, başka bir ifadeyle kırılmış olan herhangi bir döngünün hile gibi hissettiğini hissettim.

return x

x değerini döndürür (1, aksi takdirde -2, 0 ise)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.