Sayı ikili ağır mı?


58

Bir tamsayı ikili temsili, önde gelen sıfırları yok sayarak 1s'den fazla 0s içeriyorsa ikili ağırdır . Örneğin 1, ikili gösterimi basit olduğu için ikili-ağırdır, 1ancak ikili gösterimi olduğu gibi 4, ikili ağır değildir 100. Bir bağlanma durumunda (örneğin 2, bir ikili gösterimi ile 10), sayı ikili ağır olarak kabul edilmez.

Girdi olarak pozitif bir tamsayı verildiğinde, eğer ikili-ağır ise bir truthy değeri ve değilse bir falsey değeri verin.

testcases

Biçim: input -> binary -> output

1          ->                                1 -> True
2          ->                               10 -> False
4          ->                              100 -> False
5          ->                              101 -> True
60         ->                           111100 -> True
316        ->                        100111100 -> True
632        ->                       1001111000 -> False
2147483647 ->  1111111111111111111111111111111 -> True
2147483648 -> 10000000000000000000000000000000 -> False

puanlama

Bu yani her dilde en az bayt kazanıyor


Dilim son test olayını kaldıramadığı için olumlu bir tamsayı olarak kabul edilen sınırların dışında olduğu için ne yapmalı?
musicman523

1
@ musicman523 afaik Standart G / Ç kuralları, yalnızca dilinizin sayı biçimiyle temsil edilebilecek numaraları kabul etmeniz gerektiğini belirtir. Boolfuck gibi bir şey kullanarak bu "oyun" Standart Loophole olarak kabul edilir
Skidsdev

Herhangi bir truthy / falsy değeri var mı yoksa iki farklı değere ihtiyacımız var mı?
Outgolfer Erik,

@EriktheOutgolfer herhangi bir değer
Skidsdev

6
Aka A072600 , eğer bu herhangi birine yardım ederse.
dcsohl

Yanıtlar:


28

x86 Makine Kodu, 15 14 bayt

F3 0F B8 C1 0F BD D1 03 C0 42 2B D0 D6 C3

Bu, Microsoft'un __fastcall çağrı kuralını (ecx'te ilk ve tek parametre, eax cinsinden dönüş değeri, callee'nin clobber edx'i serbest bırakmasına izin verilir) kullanan bir işlevdir, ancak kayıtlardaki argümanları ileten diğer çağrı kuralları için önemsiz bir şekilde değiştirilebilir.

255'i truthy, 0'ı falsey olarak döndürür.

Belgelenmemiş (ancak yaygın olarak desteklenen) opcode kullanır salc.

Aşağıdaki sökme:

;F3 0F B8 C1 
  popcnt eax, ecx ; Sets eax to number of bits set in ecx

;0F BD D1
  bsr edx, ecx    ; Sets edx to the index of the leading 1 bit of ecx

;03 C0
  add eax, eax

;42
  inc edx

;2B D0
  sub edx, eax

  ; At this point, 
  ;   edx = (index of highest bit set) + 1 - 2*(number of bits set)
  ; This is negative if and only if ecx was binary-heavy.

;D6
  salc           ; undocumented opcode. Sets al to 255 if carry flag 
                 ; is set, and to 0 otherwise. 

;C3
  ret

Çevrimiçi deneyin!

Peter Cordeslzcnt ile değiştirmeyi önerdiğiniz için teşekkürler bsr.


Güzel. popcntCevaplara bakmak için aşağı inmeden önce açıkça görebildiğim kadarıyla karşılaştım , ancak lzcntsoru tarafından istenen sadece önemli basamaklarla başa çıkmayı düşünmemiştim .
Peter Cordes

(Aka ) bsryerine kullanmaktan net tasarruf elde etmenin bir yolu var mı ? Kullanılacak olurdu yerine size 32 lzcnt verir beri. (. Veya OP dedi neyse ... AMD bile belgeleri bu davranış tüm mevcut Intel ve AMD donanım üzerinde src = 0 için değiştirilmemiş dst, yaprakları, ancak Intel tanımsız diyor olumlu örtülü bir şekilde, .)lzcntrep bsrsublea0
Peter Cordes

1
Kesinlikle, @Peter ile aynı satırları düşünüyordum, çünkü zorluk açıkça girdileri tam sayılara sınırladı. Aslında, popcntve kullanarak hazırlanmış bir çözüm vardı bsr, ama 17 bayt oldu. Gördüğüm ilk cevapla karşılaştırıldığında bunun oldukça iyi olduğunu düşünüyordum , ama bu zekice leanumara bu pantolonu yendi. Ben de karşılaştırmaya baktım bsfve popcnt. Ancak bu çözümün üstesinden gelebilecek herhangi bir yol göremiyorum, hatta repöneki bırakarak kaydedebileceğiniz 1 baytı dikkate alarak bile .
Cody Gray,

1
salcdeğil eşdeğer için setc al: İkinci set alCF değil 255, ayarlarsanız 1'e
Ruslan

1
Gerçek eşdeğer salcolduğunu sbb al, al, ancak bunu kodlamak için 1 byte bir tasarruf olsun. Bu arada, bir AMD tarafından belgelenmiş ve yaygın anımsatıcı bile Intel'in P6 işlemkodu haritadan geliyor, Intel tarafından desteklenen. Yani bu gerçekten kullanımı oldukça güvenlidir. Ayrıca, bu talimatı kullanmayı düşünmek için güzel bir gelişme! Bu esasen orjinal taslağımın yaptığı şeydi, (1) x86-64 kodunu kullandım, inckodlamanın iki katıydı ve (2) hiç düşünmemiştim salc, bu yüzden aynı işi bir daha uzun yoldan. Çok kötü, sadece bir kez oy kullanabilirim.
Cody Gray,

17

Jöle , 5 bayt

Bo-SR

Boş olmayan çıktı (truthy) veya boş çıktı (falsy) verir.

Çevrimiçi deneyin!

Nasıl çalışır

Bo-SR  Main link. Argument: n

B      Binary; convert n to base 2.
 o-    Compute the logical OR with -1, mapping 1 -> 1 and 0 -> -1.
   S   Take the sum s. We need to check if the sum is strictly positive.
    R  Range; yield [1, ..., s], which is non-empty iff s > 0.

Güzel. Ben Bo-Sama truthy / falsy ... içine pozitif olmayan / pozitif dönüştürmek olacak bir 1 bayt atomu bulamadık
ETHproductions

Mantıklı veya −1 ile, doğru mu?
Lynn,

@Lynn Evet, gerçekten. Teşekkürler.
Dennis


@cairdcoinheringaahing Teşekkürler, ancak Æṃo zamanlar yoktu.
Dennis

14

Python 2,35 bayt

lambda n:max('10',key=bin(n).count)

Çevrimiçi deneyin!

Eski cevap, 38 bayt

Çıkışlar 0falsy gibi -2ya da -1olduğu gibi truthy

lambda n:~cmp(*map(bin(n).count,'10'))

Çevrimiçi deneyin!


2
Önde gelen 0 karşılığında binbu çözüm sorunlarına neden oluyor mu?
Shadow

3
@shadow İşleyiş şekli nedeniyle sorun yok max. Bir bağlanma durumunda, max, maksimum değeri olan yinelemede ilk değeri döndürür. Bu kod, bir bağlanma durumunda 1'in döndürülmesini sağlamak için bu gerçeği kullanır; bu, aslında sıfırdan daha fazla olanın olduğu anlamına gelir bin; Ekstra sıfır için olmasa da, bu şekilde yazıldığında yanlış olur.
FryAmTheEggman

@FryAmTheEggman bu aynı zamanda eski cevaplarda da geçerlidir, her ikisinin de eşit olduğu durumlarda cmpdöner0
Rod

11

Octave , 18 bayt

@(n)mode(de2bi(n))

İletişim araç kutusu dahil olmadığından TIO çalışmıyor. Octave-Online'da test edilebilir .

Bu nasıl çalışır:

de2biOndalık sayıyı, bir dize değil, ikili sayısal bir vektöre dönüştürür dec2bin.

modevektördeki en sık sayıyı döndürür. Kravat durumunda en düşük varsayılandır.

@(n)                % Anonymous function that takes a decimal number as input 'n'
    mode(        )  % Computes the most frequent digit in the vector inside the parentheses
         de2bi(n)   % Converts the number 'n' to a binary vector

İletişim araç kutusu Octave'in standart bir parçası mı, yoksa diğer dillerde bir kütüphane gibi mi görünüyor?
dcsohl

Kurulumu ile birlikte gelen bir paket. Özellikle bazı kurulumlarda yüklemek zorundasınız ve bazılarında ise standart olarak otomatik olarak yükleniyor. Octave-Online.net adresinde standardın bir parçası, bu yüzden referans olarak kullanıyorum. (Kod, yarışmadan önce var olan en az bir tercümanda çalışmalıdır).
Stewie Griffin,

9

JavaScript (ES6), 36 34 bayt

f=(n,x=0)=>n?f(n>>>1,x+n%2-.5):x>0

f=(n,x=0)=>n?f(n>>>1,x+=n%2-.5):x>035 bayt için
ovs

Girdi asla negatif olmadığından bayt kaydetmek n>>1yerine kullanın n>>>1.
kamoroso94,

@ kamoroso94 Teşekkürler, ancak o zaman 2147483648 tarihinde başarısız olur.
ETHproductions

@ETHproductions Kahretsin ve n/2|0daha iyi değil: /
kamoroso94



7

Brachylog , 6 bayt

ḃọtᵐ>₁

Çevrimiçi deneyin!

açıklama

Example input: 13

ḃ        Base (default: binary): [1,1,0,1]
 ọ       Occurences:             [[1,3],[0,1]]
  tᵐ     Map Tail:               [3,1]
    >₁   Strictly decreasing list

Yana gelen sıfır ile basamaklı bir liste ile kendi çıkışını birleştirmeye asla biz oluşumları biliyoruz 1hep ilk olacak ve oluşumları 0her zaman ikinci sonra olacak .



6

C (gcc) , 51 48 41 40 bayt

i;f(n){for(i=0;n;n/=2)i+=n%2*2-1;n=i>0;}

Çevrimiçi deneyin!


OP'nin açıklamalarına dayanarak kaldırabilirsinizunsigned
musicman523

Nnn pozitif olduğundan, değiştirebilir n>>=1için n/=2. Ben de kullanabilirsiniz düşünmek ~nyerine n^-1aynı zamanda değiştirmek izin vermelidir ki, &&hiç&
musicman523

"Nnn" anlamına gelir - Ben yorum düzenlerken Garip şeyler olur nve değiştirme hakkında aldırma &&için &, ben bu işe sanmıyorum. Ama onu değiştirmek *iş gibi görünüyor
musicman523

@ musicman523 &&Sadece imzasız durumu idare etmek içindi, ancak sadece pozitif tamsayıları kullanmam gerektiğinden, hepsini bir arada kaldırabilirim. Bu /=kadar kısa olmanın iyi bir anlamı >>=, Teşekkürler!
cleblanc

Sen değişen bir bayt kaydedebilirsiniz n&1?++i:--1için i+=n%2*2-1. Ayrıca >0ağır ve sıfır olmayan ağır için sıfır çıkacağını belirterek kurtulmak mümkün olabilir
musicman523

6

R , 54 53 51 bayt

Max Lawnboy sayesinde -1 bayt

n=scan();d=floor(log2(n))+1;sum(n%/%2^(0:d)%%2)*2>d

stdin'den okur; TRUEİkili ağır sayılar için döner . dİkili hanelerin sayısıdır; sum(n%/%2^(0:d)%%2Rakam toplamını hesaplar (yani, sayıları).

Çevrimiçi deneyin!


Cevabınızı yazdıktan sonra cevabınızı gördüm ... Her neyse, 1 byte tasarruf etmek log2(n)yerine kullanabilirsinizlog(n,2)
Maxim Mikhaylov

Tabii ki @ MaxLawnboy ah. Teşekkürler!
Giuseppe,

Başka bir 12 bayt golf attı
JAD

6

x86_64 makine kodu, 23 22 21 bayt

31 c0 89 fa 83 e2 01 8d 44 50 ff d1 ef 75 f3 f7 d8 c1 e8 1f c3

Demonte:

  # zero out eax
  xor  %eax, %eax
Loop:
  # copy input to edx
  mov  %edi, %edx
  # extract LSB(edx)
  and  $0x1, %edx
  # increment(1)/decrement(0) eax depending on that bit
  lea -1(%rax,%rdx,2), %eax
  # input >>= 1
  shr  %edi
  # if input != 0: repeat from Loop
  jnz  Loop

  # now `eax < 0` iff the input was not binary heavy,
  neg %eax
  # now `eax < 0` iff the input was binary heavy (which means the MSB is `1`)
  # set return value to MSB(eax)
  shr  $31, %eax
  ret

ThanksRuslan, @PeterCordes -1byte için teşekkürler !

Çevrimiçi deneyin!


8d 1fBunun yerine kullanmanızın belirli bir nedeni var mı 89 fb?
Ruslan,

2
Asıl soru, bu iğrenç AT&T sözdizimini kullanmanızın belirli bir nedeni var mı? Ayrıca, demontaj ve sökme hem sahip olduğunu kabul add eax, 2+ dec eaxancak yorumlarınız artırmak istediğiniz düşündürmektedir ebxdeğil eax.
Cody Gray,

1
Sen yerini alabilir jnz Next/ add/ decile (7 bayt) lea -1(%rax, %rbx, 2), %eax(4 bayt) yapmak eax += 2*ebx - 1(gibi diğer x86 makine-kodu cevap ). Daha sonra ilmik dışına, neg %eax(2 bayt) işaret biti aşağıya kaydırmadan önce. 1 bayt net tasarruf. Veya test %eax,%eax/ setge %aldönüş değeri ise de çalışır, boolya da int8_t.
Peter Cordes

1
@PeterCordes Sanırım ne olduğunu biliyorum, ama emin değilim: Denememiş olabilirim lea -1(%rax,rbx,2)ama sadece lea -1(%eax,%eax,2)bu şekilde bayt harcadım .. Her neyse, ikiniz de haklıydınız, böyle bir bayt kurtarabilirim. Çok teşekkürler (karşılığında ben bunu leabir movsüre değiştireceğim )!
18'de

1
@ moonheart08: O zamanlar bunu bilmiyordum ama biri 7 baytlık bir cevap verdi.
ბიმო

5

Perl 6 ,  32  30 bayt

{[>] .base(2).comb.Bag{qw<1 0>}}

Dene

{[>] .polymod(2 xx*).Bag{1,0}}

Dene

Expanded:

{      # bare block lambda with implicit parameter 「$_」

  [>]  # reduce the following with &infix:« > »

    .polymod(2 xx *) # turn into base 2 (reversed) (implicit method call on 「$_」)
    .Bag\            # put into a weighted Set
    { 1, 0 }         # key into that with 1 and 0
                     # (returns 2 element list that [>] will reduce)
}

5

Bilge , 40 39 bayt

::^?[:::^~-&[-~!-~-~?]!~-?|>]|:[>-?>?]|

Çevrimiçi deneyin!

açıklama

::^?                                      Put a zero on the bottom
    [                                     While
     :::^~-&                              Get the last bit
            [-~!-~-~?]!~-?|               Increment counter if 0 decrement if 1
                           >              Remove the last bit
                            ]|            End while
                              :[>-?>?]|   Get the sign

5

Haskell, 41 34

g 0=0
g n=g(div n 2)+(-1)^n
(<0).g

Eğer ngarip bir almak -1bile eğer bir alacak 1. Bir özyinelemeli arama ekleyin n/2ve eğer durdurun n = 0. Sonuç, 0sayının altındaysa ikili ağırdır.

Çevrimiçi deneyin!

Düzenleme: @ Ørjan Johansen bazı kısayollar buldu ve 7 bayt kaydetti. Teşekkürler!


mod n 2sadece olabilir nve bu bir akümülatör olmadan daha kısa bir bayt. Çevrimiçi deneyin!
Ørjan Johansen

5

Retina , 37 34 bayt

.+
$*
+`(1+)\1
$1@
@1
1
+`.\b.

1+

Çevrimiçi deneyin! Link, daha küçük test senaryoları içeriyor (daha büyük olanları muhtemelen hafızada kalacaktı). Düzenleme: @ Martininder sayesinde 3 bayt kaydedildi. Açıklama: İlk aşamada tekli için ondalık dönüştürür ve bir sonraki iki aşamada (kullanıyorum dışında bu, neredeyse düz Retina wiki tekli aritmetik sayfanın dışına ikili tekli dönüştürmek @yerine 0). Üçüncü aşama, ya olabilecek ya @1da olabilecek farklı karakter çiftlerini arar 1@ve hiçbiri kalmayana kadar siler. Son aşama kalan 1s için kontrol eder.


${1}olabilir $+. Yoksa kullanabilirsiniz !yerine 0ve sonra kısaltmak 01|10için .\b..
Martin Ender,

@MartinEnder Huh, $+desen bir içerdiğinde doğru olanı yapar |mı? Bunu daha önce de kullanıp kullanamayacağımı merak ediyorum ...
Neil

2
hayır, $+süper aptalcadır ve kullannsın ya da olmasın, en büyük sayıdaki grubu kullanır. Dokuzdan fazla gruba sahip olduğunuzda veya buradakine benzer bir durumda olduğunuzda, golf oynamak için kullanışlıdır ve neden bir üretim düzeninde kullandığımı bilmiyorum.
Martin Ender,

5

R , 43 bayt

max(which(B<-intToBits(scan())>0))/2<sum(B)

Çevrimiçi deneyin!

             intToBits(scan())              # converts to bits
          B<-                 >0            # make logical and assign to B
max(which(                      ))/2        # get the length of the trimmed binary and halve
                                    <sum(B) # test against the sum of bits

+1 temiz çözüm! Bilmiyordum bileintToBits
Giuseppe

Başka bir 4 bayt golf attı
JAD

5

Kotlin , 50 bayt

{i:Int->i.toString(2).run{count{it>'0'}>length/2}}

Kapalı tipte lambda (Int) -> Boolean. Sürüm 1.1 ve üstü yalnızca kullanım nedeniyle Int.toString(radix: Int).

Ne yazık ki TIO'nun Kotlin çalışma zamanı 1.0.x gibi görünüyor, bu yüzden TIO bağlantısı yerine üzücü bir köpek:



4

R, 39 37 bayt

sum(intToBits(x<-scan())>0)>2+log2(x)

Bu, @MickyT ve @Giuseppe tarafından kullanılan ve birkaç bayttan tasarruf edilen yöntemlerin bir birleşimidir.

sum(intToBits(x) > 0)1bit miktarını sayar ve 2+log2(x)/2yuvarlandığında toplam bit miktarının yarısıdır. İki değerin eşit olduğu davranışlardan dolayı yuvarlamak zorunda değiliz.



4

Regex (ECMAScript), 85 73 71 bayt

^((?=(x*?)\2(\2{4})+$|(x*?)(\4\4xx)*$)(\2\4|(x*)\5\7\7(?=\4\7$\2)\B))*$

Çevrimiçi deneyin!

Deadcode ile açıklama

Önceki 73 bayt sürümü aşağıda açıklanmıştır.

^((?=(x*?)\2(\2{4})+$)\2|(?=(x*?)(\4\4xx)*$)(\4|\5(x*)\7\7(?=\4\7$)\B))+$

ECMAScript regex'in kısıtlamaları nedeniyle, etkili bir taktik genellikle gerekli adımı her adımda değişmez tutarken, bir seferde bir adım atmaktır. Örneğin, mükemmel bir kareyi veya 2 gücünü test etmek için, her adımda 2'yi kare veya gücünü (sırasıyla) korurken boyuttaki sayıyı azaltın.

İşte bu çözüm her adımda neler yapıyor:

111100101ones>zeroes1

ones>zeroesones1>zeroes1

Bu tekrarlanan adımlar daha fazla ileri gidemediğinde, sonuç, ya 1ağır olan bitişik bir bit dizisi olacaktır ve orijinal sayının da ağır olduğunu ya da orjinal sayının ağır olmadığını belirten 2 gücünün olduğunu gösterir.

Ve elbette, bu adımlar yukarıda sayının ikili gösterimi üzerine yapılan tipografik manipülasyonlar açısından açıklanmış olmasına rağmen, gerçekte unary aritmetik olarak uygulanmaktadır.

# For these comments, N = the number to the right of the "cursor", a.k.a. "tail",
# and "rightmost" refers to the big-endian binary representation of N.
^
(                          # if N is even and not a power of 2:
    (?=(x*?)\2(\2{4})+$)   # \2 = smallest divisor of N/2 such that the quotient is
                           # odd and greater than 1; as such, it is guaranteed to be
                           # the largest power of 2 that divides N/2, iff N is not
                           # itself a power of 2 (using "+" instead of "*" is what
                           # prevents a match if N is a power of 2).
    \2                     # N = N - \2. This changes the rightmost "10" to a "01".
|                          # else (N is odd or a power of 2)
    (?=(x*?)(\4\4xx)*$)    # \4+1 = smallest divisor of N+1 such that the quotient is
                           # odd; as such, \4+1 is guaranteed to be the largest power
                           # of 2 that divides N+1. So, iff N is even, \4 will be 0.
                           # Another way of saying this: \4 = the string of
                           # contiguous 1 bits from the rightmost part of N.
                           # \5 = (\4+1) * 2 iff N+1 is not a power of 2, else
                           # \5 = unset (NPCG) (iff N+1 is a power of 2), but since
                           #   N==\4 iff this is the case, the loop will exit
                           #   immediately anyway, so an unset \5 will never be used.
    (
        \4                 # N = N - \4. If N==\4 before this, it was all 1 bits and
                           # therefore heavy, so the loop will exit and match. This
                           # would work as "\4$", and leaving out the "$" is a golf
                           # optimization. It still works without the "$" because if
                           # N is no longer heavy after having \4 subtracted from it,
                           # this will eventually result in a non-match which will
                           # then backtrack to a point where N was still heavy, at
                           # which point the following alternative will be tried.
    |
        # N = (N + \4 - 2) / 4. This removes the rightmost "01". As such, it removes
        # an equal number of 0 bits and 1 bits (one of each) and the heaviness of N
        # is invariant before and after. This fails to match if N is a power of 2,
        # and in fact causes the loop to reach a dead end in that case.
        \5                 # N = N - (\4+1)*2
        (x*)\7\7(?=\4\7$)  # N = (N - \4) / 4 + \4
        \B                 # Assert N > 0 (this would be the same as asserting N > 2
                           # before the above N = (N + \4 - 2) / 4 operation).
    )
)+
$       # This can only be a match if the loop was exited due to N==\4.

2
Bu, Deadcode'un cevabından ilham alırken , algoritma bir yorum yerine ayrı bir cevabı hakettiğini hissettiğimden yeterince farklı.
Grimmy

2
Bu olağanüstü ve tam olarak görmek istediğim şeydi (birisi regex'imi sudan çok daha özlü bir algoritma ile dışarı atıyor). Ancak yorumlarınız bunu gerçekten açıklamıyor ve regex'in yorumlanan 73 baytlık sürümü bile çalışmıyor (geriye dönük kayıtlar \5birer birer kapalı). Bunu çalıştım ve açıklamıştım ve cevabımda yorum yaptım (çünkü StackExchange çok satırlı cevaplara izin vermiyor).
Deadcode

4

Regex (ECMAScript), 183 bayt

Bu ECMA regex ile çözmek için başka ilginç bir problemdi. Bununla başa çıkmanın "açık" yolu, 1bit sayısını saymak ve bunu toplam bit sayısıyla karşılaştırmaktır. Ancak, ECMAScript regex'teki şeyleri doğrudan sayamazsınız - kalıcı geri dönüşlerin olmaması, bir döngüde yalnızca bir sayının değiştirilebileceği anlamına gelir ve her adımda yalnızca azaltılabilir.

Bu unary algoritması aşağıdaki gibi çalışır:

  1. N'ye uyan en büyük 2 gücün karekökünü alın ve karekökün mükemmel mi yoksa yuvarlatılmış mı olduğuna dikkat edin. Bu daha sonra kullanılacak.
  2. Bir döngüde, her bir en anlamlı 1biti, bir 0bitin olduğu en önemli yere hareket ettirin . Bu adımların her biri çıkarmadır. Döngünün sonunda, kalan sayı (ikili olarak gösterileceği gibi) 1s olmayan bir 0s dizesidir . Bu işlemler aslında tekdüze olarak yapılır; bu sadece kavramsal olarak ikili olarak yapılmaktadır.
  3. Bu " 1s ikili dizisini " daha önce elde edilen karekök ile karşılaştırın. Karekökün yuvarlanması gerekiyorsa, iki katına çıkmış bir sürümünü kullanın. Bu, " 1s nin ikili dizisinin " son bir eşleşme olması için N'nin yarısından daha fazla ikili basamağının olması gerektiğini garanti eder .

Karekök elde etmek için, Rocco numaralarım regex post'unda kısaca açıklanan çarpım algoritmasının bir çeşidi kullanılır. En az anlamlı 0biti tanımlamak için, benim faktöriyel numaralarım regex post'unda kısaca açıklanan bölme algoritması kullanılır. Bunlar spoiler . Bu yüzden , sizin için şımarık bazı gelişmiş regex sihrini istemiyorsanız, daha fazla okumayın . Bu sihri kendiniz bulmaya bir göz atmak istiyorsanız, bu önceki yazıdaki ardışık spoiler etiketli önerilen problemler listesinde bazı problemleri çözerek başlamanızı ve bağımsız olarak matematiksel bilgiler edinmeye çalışmanızı şiddetle tavsiye ederim .

Daha fazla uzatmadan, regex:

^(?=.*?(?!(x(xx)+)\1*$)(x)*?(x(x*))(?=(\4*)\5+$)\4*$\6)(?=(((?=(x(x+)(?=\10$))*(x*))(?!.*$\11)(?=(x*)(?=(x\12)*$)(?=\11+$)\11\12+$)(?=.*?(?!(x(xx)+)\14*$)\13(x*))\16)*))\7\4(.*$\3|\4)

Çevrimiçi deneyin!

# For the purposes of these comments, the input number = N.
^
# Take the floor square root of N
(?=
    .*?
    (?!(x(xx)+)\1*$)    # tail = the largest power of 2 less than tail
    (x)*?               # \3 = nonzero if we will need to round this square root
                        #      up to the next power of two
    (x(x*))             # \4 = potential square root; \5 = \4 - 1
    (?=
        (\4*)\5+$       # Iff \4*\4 == our number, then the first match here must result in \6==0
    )
    \4*$\6              # Test for divisibility by \4 and for \6==0 simultaneously
)
# Move all binary bits to be as least-significant as possible, e.g. 11001001 -> 1111
(?=
    (                                 # \7 = tool for making tail = the result of this move
        (
            (?=
                (x(x+)(?=\10$))*(x*)  # \11 = {divisor for getting the least-significant 0 bit}-1
            )
            (?!.*$\11)                # Exit the loop when \11==0
            (?=
                (x*)                  # \12 = floor((tail+1) / (\11+1)) - 1
                (?=(x\12)*$)          # \13 = \12+1
                (?=\11+$)
                \11\12+$
            )
            (?=
                .*?
                (?!(x(xx)+)\14*$)     # tail = the largest power of 2 less than tail
                \13                   # tail -= \13
                (x*)                  # \16 = tool to move the most-significant 1 bit to the
                                      # least-significant 0 bit available spot for it
            )
            \16
        )*
    )
)
\7                  # tail = the result of the move
\4                  # Assert that \4 is less than or equal to the result of the move
(
    .*$\3
|
    \4              # Double the value of \4 to compare against if \3 is non-empty,
                    # i.e. if we had an even number of total digits.
)



3

J , 12 bayt

(+/>-:@#)@#:

J fiilleri sağdan sola yürütür, bu yüzden en baştan başlayalım ve başlangıç ​​yolunda ilerleyelim.

açıklama

         #:       NB. Convert input to list of bits
       -:@#       NB. Half (-:) the (@) length (#)
          >       NB. Greater than 
         +/       NB. Sum (really plus (+) reduce (/)

1
(#<2*+/)@#:Ben bir şey eksik olmadıkça 1 tasarruf gerekir.
FrownyFrog





2

C #, 82 bayt

n=>{var s=System.Convert.ToString(n,2);return s.Replace("0","").Length>s.Length/2}

Dize bir IEnumerable <char> olarak davranarak biraz daha kesebilirsiniz. n=>{var s=Convert.ToString(n,2);return s.Count(c=>c=='1')>s.Length/2;}
GalacticCowboy

@GalacticCowboy Tamamen nitelendirmeniz Convertve dahil etmeniz gerektiğinden using System.Linq;(olarak kısa yazılmış namespace System.Linq{}) 11 bayt ekler . Güzel fikir sadece bu durumda tasarruf güvence altına almak için yeterli traş değil.
TheLethalCoder
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.