Apakah jumlahnya biner-berat?


58

Integer adalah biner-berat jika representasi binernya mengandung lebih 1dari 0s sementara mengabaikan nol terkemuka. Sebagai contoh 1 adalah biner-berat, karena representasi binernya sederhana 1, namun 4 tidak berat biner, seperti representasi binernya 100. Dalam hal terjadi pengikatan (misalnya 2, dengan representasi biner 10), jumlahnya tidak dianggap sebagai biner-berat.

Diberikan bilangan bulat positif sebagai input, menghasilkan nilai kebenaran jika biner-berat, dan nilai falsey jika tidak.

Testcases

Format: 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

Mencetak gol

Ini adalah sehingga byte paling sedikit di setiap bahasa menang


Bagaimana jika bahasa saya tidak dapat menangani test case terakhir karena itu di luar batas dari apa yang dianggap sebagai bilangan bulat positif?
musicman523

1
@ musicman523 afaik Aturan I / O Standar menyatakan bahwa Anda hanya perlu menerima angka yang dapat diwakili oleh format angka bahasa Anda. Perhatikan bahwa "bermain game" ini dengan menggunakan sesuatu seperti boolfuck dianggap sebagai Standard Loophole
Skidsdev

Apakah ada nilai kebenaran / kepalsuan yang dihitung atau kita perlu dua nilai yang berbeda?
Erik the Outgolfer

@EriktheOutgolfer nilai apa pun
Skidsdev

6
Aka A072600 , jika ini membantu siapa pun.
dcsohl

Jawaban:


28

Kode Mesin x86, 15 14 byte

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

Ini adalah fungsi menggunakan konvensi panggilan panggil Microsoft___ (parameter pertama dan satu-satunya di ecx, nilai balik dalam eax, callee diizinkan untuk clobber edx), meskipun secara sepele dapat dimodifikasi untuk konvensi panggilan lain yang menyampaikan argumen dalam register.

Ini mengembalikan 255 sebagai benar, dan 0 sebagai falsey.

Ini menggunakan opcode tidak berdokumen (tapi banyak didukung) salc.

Pembongkaran di bawah ini:

;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

Cobalah online!

Terima kasih kepada Peter Cordes untuk menyarankan mengganti lzcntdengan bsr.


Bagus. Saya sudah sampai sejauh yang jelas popcntsebelum menggulir ke bawah untuk melihat jawaban, tetapi tidak terpikir lzcntuntuk berurusan dengan hanya angka signifikan seperti yang dipersyaratkan oleh pertanyaan.
Peter Cordes

Apakah ada cara untuk mendapatkan penghematan bersih dari menggunakan bsralih-alih lzcnt(alias rep bsr)? Anda harus menggunakan subsebagai ganti leakarena memberi Anda 32-lzcnt. (Atau membiarkan pertama tidak dimodifikasi untuk src = 0, pada semua perangkat keras Intel dan AMD yang ada. AMD bahkan mendokumentasikan perilaku ini, tetapi Intel mengatakan tidak terdefinisi ... Pokoknya, OP mengatakan positif , yang mengesampingkan 0.)
Peter Cordes

1
Saya benar-benar berpikir sepanjang jalur yang sama dengan @Peter, karena tantangannya secara eksplisit membatasi input ke bilangan bulat positif. Bahkan, saya punya solusi yang dirancang menggunakan popcntdan bsr, tapi itu 17 byte. Aku berpikir itu cukup bagus dibandingkan dengan jawaban pertama yang kulihat , tapi leatrik pintar ini mengalahkan itu. Saya juga melihat membandingkan bsfdan popcnt. Tetapi saya tidak melihat cara apa pun yang dapat mengalahkan solusi ini, bahkan dengan memperhitungkan 1 byte yang dapat Anda hemat dengan menjatuhkan repawalan.
Cody Grey

1
salctidak setara dengan setc al: yang terakhir ditetapkan alke 1 jika CF ditetapkan, bukan ke 255.
Ruslan

1
Setara sebenarnya salcadalah sbb al, al, tetapi Anda mendapatkan penghematan 1 byte untuk menyandikannya. Omong-omong, ini didokumentasikan oleh AMD, dan secara luas didukung oleh Intel, dengan mnemonic bahkan berasal dari peta opcode P6 Intel. Jadi yang ini sebenarnya cukup aman untuk digunakan. Juga, perbaikan yang bagus di sini untuk berpikir untuk menggunakan instruksi itu! Ini pada dasarnya adalah apa konsep awal saya lakukan, kecuali (1) saya menggunakan kode x86-64, jadi incdua kali lebih lama untuk menyandikan, dan (2) saya tidak memikirkannya salc, jadi saya melakukan pekerjaan yang sama di sebuah jalan yang lebih panjang. Sayang sekali, saya hanya bisa memilih satu kali.
Cody Grey

17

Jelly , 5 byte

Bo-SR

Menghasilkan output yang tidak kosong (benar) atau output kosong (salah).

Cobalah online!

Bagaimana itu bekerja

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.

Bagus. Saya pernah Bo-S, tetapi saya tidak dapat menemukan atom 1-byte yang akan mengubah positif / non-positif menjadi kebenaran / kepalsuan ...
ETHproduksi

Logis atau dengan −1, kan?
Lynn

@ Lynn Ya, tentu saja. Terima kasih.
Dennis


@cairdcoinheringaahing Terima kasih, tetapi saat Æṃitu tidak ada.
Dennis

14

Python 2 , 35 byte

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

Cobalah online!

Jawaban lama, 38 byte

Keluaran 0sebagai palsu dan -2atau -1sebagai kebenaran

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

Cobalah online!


2
Apakah 0 terdepan dalam pengembalian binpenyebab masalah ini?
Bayangan

3
@shadow Tidak ada masalah, karena cara maxkerjanya. Dalam hal seri, max akan mengembalikan nilai pertama di iterable yang memiliki nilai maksimal. Kode ini menggunakan fakta itu untuk memastikan bahwa 1 dikembalikan pada saat seri, yang sebenarnya berarti ada lebih banyak daripada nol, karena nol tambahan ditambahkan oleh bin. Ini sebenarnya akan salah ketika ditulis dengan cara ini jika bukan karena nol tambahan.
FryAmTheEggman

@FryAmTheEggman ini juga berlaku pada jawaban lama, di mana cmppengembalian 0ketika keduanya sama
Rod

11

Oktaf , 18 byte

@(n)mode(de2bi(n))

TIO tidak berfungsi karena kotak alat komunikasi tidak disertakan. Itu dapat diuji di Octave-Online .

Bagaimana ini bekerja:

de2bimengkonversi angka desimal ke vektor angka biner, bukan string seperti dec2binhalnya.

modemengembalikan digit paling sering dalam vektor. Ini default ke terendah dalam kasus seri.

@(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

Apakah kotak alat komunikasi merupakan bagian standar dari Oktaf, atau lebih mirip dengan perpustakaan dalam bahasa lain?
dcsohl

Ini adalah paket yang dilengkapi dengan instalasi. Anda harus memuatnya secara khusus di beberapa instalasi, dan secara otomatis dimuat sebagai standar di instalasi lain. Itu bagian dari standar pada Octave-Online.net, jadi saya menggunakannya sebagai referensi. (Kode harus bekerja di setidaknya satu juru bahasa yang ada sebelum tantangan).
Stewie Griffin

9

JavaScript (ES6), 36 34 byte

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>0selama 35 byte.
ovs

Gunakan n>>1alih-alih n>>>1untuk menyimpan byte karena input tidak pernah negatif.
kamoroso94

@ kamoroso94 Terima kasih, tapi kemudian gagal pada 2147483648.
ETHproduksi

@ ETProduk Sial, dan n/2|0tidak lebih baik: /
kamoroso94



7

Brachylog , 6 byte

ḃọtᵐ>₁

Cobalah online!

Penjelasan

Example input: 13

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

Karena tidak akan pernah menyatukan outputnya dengan daftar angka dengan nol terkemuka, kita tahu bahwa kejadian 1akan selalu menjadi yang pertama dan kejadian 0akan selalu menjadi yang kedua setelah .



6

C (gcc) , 51 48 41 40 byte

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

Cobalah online!


Berdasarkan klarifikasi OP, Anda dapat menghapusunsigned
musicman523

Karena nnn positif, Anda dapat berubah n>>=1menjadi n/=2. Saya juga berpikir Anda dapat menggunakan ~nsebagai gantinya n^-1, yang seharusnya juga memungkinkan Anda untuk berubah &&ke&
musicman523

Hal-hal aneh terjadi ketika saya mengedit komentar - "nnn" berarti n, dan tidak pernah keberatan tentang mengubah &&untuk &, saya tidak berpikir bahwa akan bekerja. Tetapi mengubahnya *tampaknya bekerja
musicman523

@ musicman523 Itu &&hanya untuk menangani kasus yang tidak ditandatangani tetapi karena saya hanya perlu menangani bilangan bulat positif saya dapat menghapus semuanya bersama-sama. Pouint bagus tentang /=menjadi lebih pendek >>=, terima kasih!
cleblanc

Anda dapat menyimpan perubahan satu byte n&1?++i:--1menjadi i+=n%2*2-1. Anda juga dapat menyingkirkannya >0dengan menyatakan bahwa Anda akan menghasilkan nol untuk yang berat dan yang bukan nol untuk yang tidak berat
musicman523

6

R , 54 53 51 byte

-1 byte terima kasih kepada Max Lawnboy

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

membaca dari stdin; kembali TRUEuntuk angka-angka berat biner. dadalah jumlah digit biner; sum(n%/%2^(0:d)%%2menghitung jumlah digit (yaitu jumlah yang).

Cobalah online!


Hanya melihat jawaban Anda setelah memposting milik saya ... Lagi pula, Anda dapat menggunakan log2(n)alih-alih log(n,2)menyimpan 1 byte
Maxim Mikhaylov

@MaxLawnboy ah, tentu saja. Terima kasih!
Giuseppe

Bermain golf dengan 12 byte lagi: codegolf.stackexchange.com/a/132396/59530
JAD

6

kode mesin x86_64, 23 22 21 byte

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

Dibongkar:

  # 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

Terima kasih @Ruslan, @PeterCordes untuk -1byte!

Cobalah online!


Apakah ada alasan khusus mengapa Anda menggunakan 8d 1fbukan 89 fb?
Ruslan

2
Pertanyaan sebenarnya adalah, apakah ada alasan khusus mengapa Anda menggunakan sintaks AT&T yang keji itu?!? Juga, pembongkaran dan pembongkaran Anda berdua setuju bahwa Anda memiliki add eax, 2+ dec eax, tetapi komentar Anda menyarankan Anda ingin menambah ebx, bukan eax.
Cody Grey

1
Anda dapat mengganti jnz Next/ add/ dec(7 byte) dengan lea -1(%rax, %rbx, 2), %eax(4 byte) yang harus dilakukan eax += 2*ebx - 1(seperti pada jawaban kode mesin x86 lainnya ). Lalu di luar loop, neg %eax(2 byte) sebelum menggeser bit tanda ke bawah. Penghematan bersih 1 byte. Atau test %eax,%eax/ setge %aljuga akan berfungsi, jika nilai pengembalian Anda adalah a boolatau int8_t.
Peter Cordes

1
@PeterCordes Saya pikir saya tahu apa yang terjadi, tapi saya tidak yakin: Saya mungkin belum mencoba lea -1(%rax,rbx,2)tetapi hanya lea -1(%eax,%eax,2)membuang-buang byte dengan cara ini .. Bagaimanapun, Anda berdua benar, saya dapat menyimpan byte seperti ini. Terima kasih banyak (sebagai imbalannya saya akan mengubahnya leauntuk movsementara waktu saya melakukannya)!
ბიმო

1
@ moonheart08: Saya tidak tahu soal itu dulu, tapi seseorang mengirim jawaban yang menghemat 7 byte.
ბიმო

5

Perl 6 ,  32  30 byte

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

Menguji

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

Menguji

Diperluas:

{      # 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

Bijaksana , 40 39 byte

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

Cobalah online!

Penjelasan

::^?                                      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

Jika naneh, ambil a -1jika itu genap, ambil a 1. Tambahkan panggilan rekursif dengan n/2dan hentikan jika n = 0. Jika hasilnya kurang dari 0angka itu biner-berat.

Cobalah online!

Sunting: @ Ørjan Johansen menemukan beberapa pintasan dan menyimpan 7 byte. Terima kasih!


mod n 2bisa saja n, dan itu satu byte lebih pendek tanpa akumulator. Cobalah online!
Ørjan Johansen

5

Retina , 37 34 byte

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

1+

Cobalah online! Tautan mencakup test case yang lebih kecil (yang lebih besar mungkin akan kehabisan memori). Sunting: Disimpan 3 byte berkat @MartinEnder. Penjelasan: Tahap pertama mengkonversi dari desimal ke unary, dan dua tahap berikutnya mengkonversi dari unary ke binary (ini hampir langsung keluar dari halaman aritmatika unary di wiki Retina, kecuali bahwa saya menggunakan @alih-alih 0). Tahap ketiga mencari pasangan karakter yang berbeda, yang bisa berupa @1atau 1@, dan menghapusnya sampai tidak ada yang tersisa. Tahap terakhir kemudian memeriksa sisa 1s.


${1}bisa $+. Atau Anda bisa menggunakan dan !bukannya 0menyingkat 01|10menjadi .\b..
Martin Ender

@ Martin Ennder Huh, apakah $+melakukan hal yang benar ketika polanya berisi a |? Saya bertanya-tanya apakah saya bisa menggunakan itu sebelumnya ...
Neil

2
tidak, $+itu super bodoh dan hanya menggunakan grup dengan jumlah terbesar, apakah itu digunakan atau tidak. Ini hanya berguna untuk bermain golf ketika Anda memiliki lebih dari sembilan grup atau dalam situasi seperti yang ada di sini, dan saya tidak tahu mengapa saya pernah menggunakannya dalam regex produksi.
Martin Ender


5

Kotlin , 50 byte

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

Lambda dari tipe implisit (Int) -> Boolean. Versi 1.1 dan lebih tinggi hanya karena penggunaan Int.toString(radix: Int).

Sayangnya runtime Kotio TIO tampaknya 1,0.x, jadi inilah anjing yang sedih alih-alih tautan TIO:



4

R, 39 37 byte

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

Ini adalah kombinasi dari metode yang digunakan oleh @MickyT dan @Giuseppe, menghemat beberapa byte lagi.

sum(intToBits(x) > 0)menghitung jumlah 1bit, dan 2+log2(x)/2setengah dari jumlah total bit, ketika dibulatkan ke bawah. Kami tidak harus membulatkan karena perilaku ketika kedua nilai tersebut sama.


4

C # (.NET Core) , 62 , 49 byte

Tanpa LINQ.

EDIT: dana dengan -13 byte golf mengubah sementara ke rekursif dan mengembalikan bool, bukan bilangan bulat.

x=>{int j=0;for(;x>0;x/=2)j+=x%2*2-1;return j>0;}

Cobalah online!


4

Regex (ECMAScript), 85 73 71 byte

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

Cobalah online!

penjelasan oleh Deadcode

Versi 73 byte sebelumnya dijelaskan di bawah ini.

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

Karena keterbatasan regex ECMAScript, taktik yang efektif sering kali untuk mengubah langkah nomor satu sekaligus menjaga properti yang dibutuhkan tidak berubah-ubah pada setiap langkah. Misalnya, untuk menguji kuadrat sempurna atau kekuatan 2, kurangi jumlahnya dalam ukuran sekaligus pertahankan kuadrat atau kekuatan 2 (masing-masing) di setiap langkah.

Inilah yang dilakukan solusi ini di setiap langkah:

111100101Haines>zerHaies1

Haines>zerHaiesHaines-1>zerHaies-1

Ketika langkah-langkah yang diulang ini tidak dapat melangkah lebih jauh, hasil akhirnya akan berupa string 1bit yang berdekatan , yang berat, dan menunjukkan bahwa angka asli juga berat, atau kekuatan 2, yang menunjukkan bahwa angka asli tidak berat.

Dan tentu saja, meskipun langkah-langkah ini dijelaskan di atas dalam hal manipulasi tipografi pada representasi angka biner, mereka sebenarnya diimplementasikan sebagai aritmatika unary.

# 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
Walaupun ini terinspirasi oleh jawaban Deadcode , algoritmenya cukup berbeda sehingga saya merasa pantas mendapatkan jawaban terpisah daripada komentar.
Grimmy

2
Ini fenomenal, dan persis apa yang ingin saya lihat (seseorang meniup regex saya keluar dari air dengan algoritma yang jauh lebih ringkas). Tetapi komentar Anda benar-benar tidak menjelaskannya sama sekali, dan versi 73-byte dari regex yang dikomentari bahkan tidak berfungsi (backref \5selanjutnya dimatikan satu per satu). Saya telah mempelajari ini dan menjelaskan serta berkomentar dalam jawaban saya (karena StackExchange tidak mengizinkan balasan multiline).
Deadcode

4

Regex (ECMAScript), 183 byte

Ini adalah masalah lain yang menarik untuk dipecahkan dengan regex ECMA. Cara "jelas" untuk menangani ini adalah dengan menghitung jumlah 1bit dan membandingkannya dengan jumlah total bit. Tetapi Anda tidak dapat secara langsung menghitung hal-hal dalam ECMAScript regex - kurangnya referensi-balik yang persisten berarti bahwa hanya satu angka yang dapat dimodifikasi dalam satu lingkaran, dan pada setiap langkah hanya dapat dikurangi.

Algoritma unary ini berfungsi sebagai berikut:

  1. Ambil akar kuadrat dari kekuatan 2 terbesar yang cocok dengan N, dan perhatikan apakah akar kuadrat itu sempurna atau harus dibulatkan ke bawah. Ini akan digunakan nanti.
  2. Dalam satu lingkaran, pindahkan masing-masing yang paling signifikan 1 bit ke posisi paling tidak signifikan di mana ada 0bit. Masing-masing langkah ini adalah pengurangan. Pada akhir loop, angka yang tersisa (karena akan diwakili dalam biner) adalah string 1s tanpa 0s. Operasi-operasi ini sebenarnya dilakukan secara unary; itu hanya secara konseptual bahwa mereka dilakukan dalam biner.
  3. Bandingkan ini "string biner dari 1 s" ini dengan akar kuadrat yang diperoleh sebelumnya. Jika akar kuadrat harus dibulatkan, gunakan versi yang berlipat ganda. Ini memastikan bahwa "string biner 1s" harus memiliki lebih dari setengah digit biner sebanyak N agar ada pertandingan final.

Untuk mendapatkan akar kuadrat, varian dari algoritma multiplikasi dijelaskan secara singkat dalam posting regex nomor Rocco saya digunakan. Untuk mengidentifikasi 0bit paling tidak signifikan , algoritma pembagian yang dijelaskan secara singkat dalam pos faktor nomor regex saya digunakan. Ini adalah spoiler . Jadi jangan membaca lebih jauh jika Anda tidak ingin beberapa sihir regex unary canggih dimanjakan untuk Anda . Jika Anda memang ingin mencoba sendiri keajaiban ini, saya sangat menyarankan memulai dengan memecahkan beberapa masalah dalam daftar masalah yang direkomendasikan secara spoiler-tag pada posting sebelumnya , dan mencoba untuk menemukan wawasan matematika secara mandiri.

Tanpa basa-basi lagi, 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)

Cobalah online!

# 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 byte

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

J mengeksekusi kata kerja kanan-ke-kiri, jadi mari kita mulai dari akhir dan bekerja menuju awal.

Penjelasan

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

1
(#<2*+/)@#:harus menyimpan 1 kecuali saya kehilangan sesuatu.
FrownyFrog




2

Python 2 , 44 byte

f=lambda n,c=0:f(n/2,c+n%2*2-1)if n else c>0

Cobalah online!

Jawaban Lama, 47 byte

c,n=0,input()
while n:c+=n%2*2-1;n/=2
print c>0

Ini hanyalah port dari jawaban C @ cleblanc . Ini lebih panjang daripada jawaban Python lainnya, tetapi saya pikir itu layak dikirim karena merupakan metode yang sama sekali berbeda untuk menemukan jawabannya.

Cobalah online!


2

C #, 82 byte

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

Anda dapat memangkas lebih banyak dengan memperlakukan string sebagai <nama> IEnumerable. n=>{var s=Convert.ToString(n,2);return s.Count(c=>c=='1')>s.Length/2;}
GalacticCowboy

@ GalacticCowboy Itu menambahkan 11 byte karena Anda harus sepenuhnya memenuhi syarat Convertdan termasuk using System.Linq;(ditulis lebih pendek dari namespace System.Linq{}). Ide bagus hanya tidak cukup untuk menjamin penghematan dalam kasus ini.
TheLethalCoder
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.