बाइनरी उलटी गिनती लंबाई


18

अनंत से गणना से प्रेरित

एक गैर-नकारात्मक पूर्णांक को देखते हुए N, निम्न चरणों की पुनरावृत्ति की संख्या को 0 तक पहुंचने के लिए आउटपुट देता है:

  1. Nबाइनरी में बदलें ( 4812390 -> 10010010110111001100110)
  2. हर एक को पलटें ( 10010010110111001100110 -> 01101101001000110011001)
  3. ट्रिम प्रमुख शून्य ( 01101101001000110011001 -> 1101101001000110011001)
  4. दशमलव में परिवर्तित करें ( 1101101001000110011001 -> 3576217)

नियम

  • इनपुट और आउटपुट किसी भी अस्पष्ट, सुसंगत प्रारूप में हो सकते हैं
  • इनपुट आपकी भाषा के लिए मूल प्रतिनिधित्व योग्य पूर्णांक सीमा के भीतर होगा (यदि आपकी भाषा मनमाने ढंग से बड़े पूर्णांक का समर्थन करती है, तो कोई उत्तर नहीं है)

परीक्षण के मामलों

0 -> 0
1 -> 1
42 -> 6
97 -> 3
170 -> 8
255 -> 1
682 -> 10
8675309 -> 11
4812390 -> 14
178956970 -> 28
2863311530 -> 32

यह अनुक्रम OEIS में A005811 है।


6
चरण 3 का कोई फायदा नहीं है
edc65

@ edc65 ऐसा लगता है कि आप चरण 3 या चरण 4 कर सकते हैं, यह इस बात पर निर्भर करता है कि आपका एल्गोरिथ्म कैसा है
ब्रायन जे

@ edc65 आपके लिए शायद यह किसी काम का नहीं है। एक साधारण उलटा ऑपरेटर आपके लिए अग्रणी शून्य को ट्रिम नहीं करता है। ~(~a) == a
प्रहार

@Poke Bitwise बाइनरी प्रतिनिधित्व के सभी बिट्स को सम्मिलित नहीं करता है, जिसमें प्रमुख शून्य (और मनमाने सटीक पूर्णांक के साथ भाषाओं में अनंत राशि) शामिल हैं। यह चरण 2 के बराबर नहीं है
डेनिस

@Poke एक सरल उलटा ऑपरेशन चरण १.४ को लागू करने से अलग है। यदि आप इन चरणों को लागू करना चाहते हैं, तो चरण 3 का कोई फायदा नहीं है, क्योंकि चरण 2 में फ्लिप (जैसा कि दिखाया गया है) अग्रणी 0 को नहीं बदलता है। चरण 2 तो करता प्रमुख 1s के लिए अग्रणी 0s बदलने के लिए, तो Obviuosly आप अग्रणी निकालना पड़ 1s , नहीं प्रमुख चरण 3 में 0
edc65

जवाबों:


14

जेली , 6 4 बाइट्स

^HBS

इसे ऑनलाइन आज़माएं!या सभी परीक्षण मामलों को सत्यापित करें

पृष्ठभूमि

चलो एन एक गैर-ऋणात्मक पूर्णांक होना।

युक्ति में वर्णित प्रक्रिया के चरण 2 और 3 को वैकल्पिक रूप से सभी अग्रणी 1 को हटाने के रूप में कहा जा सकता है और शेष बिट्स को टॉगल करने के ।

इसका मतलब है कि हम एक चरण में आसन्न और बराबर बाइनरी अंकों की ठीक एक समूह से हटा देंगे तो की बाइनरी उलटी गिनती लंबाई n बस की बाइनरी प्रतिनिधित्व में इन समूहों की संख्या है n । इस चुनौती के प्रयोजनों के लिए, 0 पर विचार करें क्योंकि कोई अंक नहीं है।

के लिए एन = 8675309 , द्विआधारी में इस प्रकार की प्रक्रिया दिखता है।

100001000101111111101101
 11110111010000000010010
     1000101111111101101
      111010000000010010
         101111111101101
          10000000010010
           1111111101101
                   10010
                    1101
                      10
                       1
                       0

इन समूहों की गिनती के बजाय (जो कि बढ़त के मामले में विफल हो जाएंगे 0 के ), हम निम्नलिखित करते हैं।

n और n: 2 में निम्नलिखित द्विआधारी निरूपण हैं।

n   = 8675309 = 100001000101111111101101_2
n:2 = 4337654 =  10000100010111111110110_2

ध्यान दें कि n: 2 का बाइनरी प्रतिनिधित्व बस n है है, बाईं ओर एक बिट स्थानांतरित कर दिया।

यदि हम XOR n और n: 2 करते हैं , तो हम एक 1 (MSB) प्राप्त करेंगे , और विभिन्न आसन्न अंकों के प्रत्येक जोड़े के लिए एक अतिरिक्त 1 । समूहों की संख्या इस प्रकार n 2 n: 2 में सेट बिट्स की संख्या के बराबर है

यह काम किस प्रकार करता है

^HBS  Main link. Argument: n

 H    Halve; yield n:2.
^     XOR n with n:2.
  B   Convert the result to binary.
   S  Compute the sum of the resulting binary digits.

1
गजब का! एक पूरी तरह से अलग तर्क
edc65

9

पायथन 2, 30 बाइट्स

lambda n:bin(n^n/2).count('1')

Ideone पर इसका परीक्षण करें ।

पृष्ठभूमि

चलो n एक गैर-ऋणात्मक पूर्णांक होना।

युक्ति में वर्णित प्रक्रिया के चरण 2 और 3 को वैकल्पिक रूप से सभी अग्रणी 1 को हटाने और शेष बिट्स को टॉगल करने के रूप में कहा जा सकता है ।

इसका मतलब है कि हम एक चरण में आसन्न और बराबर बाइनरी अंकों की ठीक एक समूह से हटा देंगे तो की बाइनरी उलटी गिनती लंबाई n बस की बाइनरी प्रतिनिधित्व में इन समूहों की संख्या है n । इस चुनौती के प्रयोजनों के लिए, 0 पर विचार करें क्योंकि कोई अंक नहीं है।

के लिए एन = 8675309 , द्विआधारी में इस प्रकार की प्रक्रिया दिखता है।

100001000101111111101101
 11110111010000000010010
     1000101111111101101
      111010000000010010
         101111111101101
          10000000010010
           1111111101101
                   10010
                    1101
                      10
                       1
                       0

इन समूहों को गिनने के बजाय (जो कि बढ़त के मामले में 0 के लिए विफल हो जाएगा ), हम निम्नलिखित करते हैं।

n और n: 2 में निम्नलिखित द्विआधारी निरूपण हैं।

n   = 8675309 = 100001000101111111101101_2
n:2 = 4337654 =  10000100010111111110110_2

ध्यान दें कि n: 2 का बाइनरी प्रतिनिधित्व बस n है, बाईं ओर एक बिट स्थानांतरित कर दिया।

यदि हम XOR n और n: 2 करते हैं , तो हम एक 1 (MSB) प्राप्त करेंगे , और विभिन्न आसन्न अंकों के प्रत्येक जोड़े के लिए एक अतिरिक्त 1 । समूहों की संख्या इस प्रकार n 2 n: 2 में सेट बिट्स की संख्या के बराबर है ।


9

पायथन 2, 29 बाइट्स

f=lambda n:n and-n%4/2+f(n/2)

बाइनरी विस्तार में 0 और 1 के बीच के विकल्पों की संख्या को गिना जाता है, एक विकल्प के रूप में अग्रणी 1 को गिना जाता है। अंतिम दो बाइनरी अंकों के अलग-अलग होने की जाँच करके ऐसा होता है, फिर हटाए गए अंतिम अंक के साथ संख्या पर आघात करना। अंतिम दो अंक बिल्कुल अलग हैं यदि n%41 या 2 है, जिसे निम्न के रूप में जांचा जा सकता है -n%4/2


6

जावास्क्रिप्ट (ईएस 6), 26 बाइट्स

f=n=>n&&(n^(n>>=1))%2+f(n)

0 और 1. के बीच के बदलावों को गिनकर काम करता है और केवल 31 बिट्स तक काम करता है। 53 बिट्स का समर्थन करने के लिए 29 बाइट्स:

f=n=>1<=n&&(n%2^n/2%2)+f(n/2)


4

05AB1E , 7 5 बाइट्स

डेनिस की बदौलत 2 बाइट्स बचाए

b0ÛÔg

0 के किनारे के मामले के बिना यह 3 बाइट्स हो सकता हैbÔg

इसे ऑनलाइन आज़माएं! या एक के रूप में टेस्ट सूट के रूप में

व्याख्या

b      # convert to binary
 0Û    # trim off leading zeroes
   Ô   # remove adjacent duplicates
    g  # length

3

CJam , 14 बाइट्स

ri0{2b:!2bj)}j

इसे ऑनलाइन आज़माएं!

ri      e# read integer
0       e# value for terminal case
{       e# recursive function
  2b    e#   create binary representation with no leading zeros
  :!    e#   flip bits
  2b    e#   convert binary back to integer
  j     e#   recursive call
  )     e#   increment from 0 on the way up
}j      e# end

मूल रूप से अन्य प्रश्न के मेरे उत्तर की एक दस्तक ।


3

जावा 7,112 108 100 90 73 बाइट्स

int c(int i){int l=1,j=i;for(;(j=j/2)>0;l*=2);return i<1?0:1+c(2*l-1-i);}

मूल विचार

 Lets take an no 10110(21)
 then you do set all bits in no 21 and you will get 11111
 and after that you would subtract the original number from 11111.
 You will get 01001 and loop it until you will get 0

j=j/2को छोटा किया जा सकता है j/=2। इसके अलावा एक महान जवाब!
केविन क्रूज़सेन

हम्म .. @ नील के जावास्क्रिप्ट उत्तर से एक पोर्ट हालांकि छोटा है: int c(int i){return i>0?((i^(i>>=1))%2+c(i):0;}( 47 बाइट्स )। मैं अभी भी आपके वर्तमान उत्तर को छोड़ दूंगा, हालांकि, यह अधिक मूल है, और अन्य उपयोगकर्ताओं के पोर्ट मूल के पूर्ण विपरीत हैं। :)
केविन क्रूज़सेन

3

जे, 14 बाइट्स

**1+/@,2~:/\#:

0 के n = 0 के विशेष रिटर्न के साथ n के बाइनरी अंकों में रन की संख्या को गिनता है ।

प्रयोग

   f =: **1+/@,2~:/\#:
   (,.f"0) 0 1 42 97 170 255 682 8675309 4812390 178956970 2863311530
         0  0
         1  1
        42  6
        97  3
       170  8
       255  1
       682 10
   8675309 11
   4812390 14
 178956970 28
2863311530 32

व्याख्या

**1+/@,2~:/\#:  Input: integer n
            #:  Get the binary digits of n
       2   \    For each overlapping sublist of size 2
        ~:/       Reduce by not-equals
  1   ,         Prepend a 1
   +/@          Reduce by addition
*               Sign(n), returns 0 for n = 0 else 1
 *              Multiply with the previous sum and return

3

सीजेएम , 11 10 बाइट्स

एक बाइट को बचाने के लिए @ डेनिस का धन्यवाद!

ri_2be`,e&

इसे ऑनलाइन आज़माएं!

व्याख्या

ri            #e Read as integer
              #e STACK: 97
  _           #e Duplicate
              #e STACK: 97, 97
   2b         #e Convert to binary
              #e STACK: 97, [1 1 0 0 0 0 1]
     e`       #e Run-length encoding
              #e STACK: 97, [[2 1] [4 0] [1 1]]
       ,      #e Length
              #e STACK: 97, 3
        e&    #e Return first value if 0, or else the second value
              #e STACK: 3

1
e&(तार्किक और) एक बाइट पर बचाता है \g*
डेनिस

@ डेनिस धन्यवाद! यह आसान है कि सीजेएम के तार्किक और कैसे काम करता है, मुझे पता नहीं था
लुइस मेंडो

2

रैकेट 349 बाइट्स

(define(h s)(apply string(map(λ(x)(if(eq? x #\0)#\1 #\0))(string->list s))))(define(g s)(let*
((l(string-length s))(k(for/list((i s)(n l)#:final(not(equal? i #\0)))n)))(substring s(last k))))
(define(f n)(if(= 0 n)0(begin(let loop((n n)(c 1))(define m(string->number(string-append "#b"
(g(h(number->string n 2))))))(if(> m 0)(loop m(add1 c))c))))

Ungolfed:

(define (invertBinary s)
  (apply string
         (map
          (λ(x)(if(eq? x #\0)#\1 #\0))
          (string->list s))))

(define (trimLeading0s s)
  (let* ((l (string-length s))
         (k (for/list ((i s)
                       (n l)
                       #:final (not(equal? i #\0)))
              n)))
    (substring s (last k))))

(define (f n)
  (if (= 0 n) 0
      (begin
        (let loop ((n n)
                   (c 1))
          (define m 
            (string->number
             (string-append
              "#b"
              (trimLeading0s
               (invertBinary
                (number->string n 2))))))

          (if (> m 0)
              (loop m (add1 c))
              c)))))

परिक्षण:

(f 0)
(f 1)
(f 42)
(f 97)
(f 170)
(f 255)
(f 682)
(f 8675309)
(f 4812390)
(f 178956970)
(f 2863311530)

आउटपुट:

0
1
6
3
8
1
10
11
14
28
32

आप 2 बाइट्स को बदलकर tlऔर ib1-बाइट नामों से बचा सकते हैं ।
Mego

किया हुआ। सलाह के लिये धन्यवाद।
nn


2

विम, 62 59 बाइट्स

-3 बाइट्स DJMcMayhem के लिए धन्यवाद

C0
<C-r>=pri<Tab>'%b',<C-r>")
<Esc>0qqC<C-r>=tr(@",'01','10')
<Esc>:s/^0\+
k<C-a>j@qq@q

यहाँ अक्षत वर्णों के साथ xxd आउटपुट है:

0000000: 4330 0d12 3d70 7269 0927 2562 272c 1222  C0..=pri.'%b',."
0000010: 290d 1b30 7171 4312 3d74 7228 4022 2c27  )..0qqC.=tr(@",'
0000020: 3031 272c 2731 3027 290d 1b3a 732f 5e30  01','10')..:s/^0
0000030: 5c2b 0d6b 016a 4071 7140 71              \+.k.j@qq@q

इसे ऑनलाइन आज़माएं!

व्याख्या

C                                   " Delete the number (it goes in @")
0<CR>                               " Print 0 (our counter) and a carriage return
<C-r>=pri<Tab>'%b',<C-r>")<CR><Esc> " Use `printf()` to insert the number as base 2
0qq                                 " Return to column 0, start recording a macro
  C<C-r>=tr(@",'01','10')<CR><Esc>  "   Replace 0s with 1s and vice versa
  :s/^0\+<CR>                       "   Delete leading 0s
  k<C-a>                            "   Increment the number on the line above
  j                                 "   Return to the previous line
  @q                                "   Invoke macro recursively
q@q                                 " Stop recording and invoke macro

1
अच्छा! कुछ सुझाव: :s/^0*एक बाइट की तुलना में कम है :s/^0\+, और जब आप "ईवैल" रजिस्टर में होते हैं, तो आप बस pr<S-tab>'%b',<C-r>")स्वत: पूर्ण के लिए कर सकते हैं । (4 बाइट्स बचाता है)
DJMcMayhem

ओह, स्वतः पूर्ण टिप के लिए धन्यवाद! मैं उपयोग नहीं कर सकता :s/^0*क्योंकि यह एक खाली लाइन से मेल खाता है, और मुझे पुनरावर्ती मैक्रो से बचने के लिए खाली लाइन के लिए विफल होने की आवश्यकता है।
जॉर्डन


0

PHP, 64 बाइट्स

मेरे उलटी गिनती समाधान के आधार पर

for($n=$argv[1];$n;print 1)$n=bindec(strtr(decbin($n),"01",10));

प्रिंट 1चरित्र kबार है, जहां kपुनरावृत्तियों की संख्या है।


पूर्णांक आउटपुट के लिए +4 बाइट्स: (के लिए खाली आउटपुट 0)

for($n=$argv[1];$n;$i++)$n=bindec(strtr(decbin($n),"01",10));echo$i;

0

जावास्क्रिप्ट (ईएस 6), 44

पुनरावर्ती कार्य

जावास्क्रिप्ट सकारात्मक पूर्णांक तक सीमित, 31 बिट्स:

f=(a,s=0)=>a?f((-1>>>Math.clz32(a))-a,s+1):s

53 महत्वपूर्ण बिट्स के लिए डबल सटीक संख्या का प्रबंधन - 59 बाइट्स:

F=(a,s=0)=>a?F('0b'+a.toString(2).replace(/./g,1)-a,s+1):s

दूसरे तरीके से: @ डेनिस द्वारा अद्भुत एल्गोरिथ्म का उपयोग करते हुए, 53 बिट्स, 43 बाइट्स का प्रबंधन करने वाला गैर पुनरावर्ती कार्य :

a=>a&&a.toString(2).match(/(.)\1*/g).length

0

PHP, 51 बाइट्स

<?=preg_match_all('/(1+|0+)/',decbin($argv[1])?:o);

1 या 0. के रनों की संख्या की गणना करने के लिए एक regex का उपयोग करता है। दुर्भाग्य से इसके लिए एक विशेष मामले की 0आवश्यकता होती है जिसके लिए 3 अतिरिक्त बाइट्स की आवश्यकता होती है (और एक नोटिस देता है)।


a) oनोटिस से बचने के लिए एक अंक> 1 का उपयोग करें । बी) आप -Fझंडे के साथ और $argnइसके बजाय 3 बाइट्स बचा सकते हैं $argv[1]। ग) /1+|0+/रेगेक्स के लिए पर्याप्त होना चाहिए।
टाइटस

0

जावा 7, 71 बाइट्स

int b(Long a){return a==0?0:1+b(~a&-1L>>>64-a.toString(a,2).length());}

मुझे पता है कि यह जियोबिट्स के splitसमाधान द्वारा पीटा गया है (जो अंततः पोस्ट किया जाएगा) लेकिन यह अभी भी लिखने में मजेदार था


0

ऑक्टेव, 47 बाइट्स

@(x)(sum(dec2bin(bitxor(x,idivide(x,2)))=='1'))

OEIS प्रविष्टि के अनुसार, हम इस चुनौती के समाधान के लिए जिस मूल्य की तलाश कर रहे हैं , वह दिए गए पूर्णांक के लिए ग्रे कोड में s की संख्या के बराबर भी है1

विकिपीडिया बताता है कि ग्रे कोड की गणना x ^ (x >> 1) के रूप में की जा सकती है, इसलिए उपरोक्त फ़ंक्शन में मैं ग्रे कोड की गणना इस तरह करता हूं, इसे बाइनरी स्ट्रिंग में परिवर्तित करता हूं, और गिनता हूं कि उस स्ट्रिंग के कितने अंक हैं 1


0

जावा 7, 64 बाइट्स

long g(Long n){return n.toString(n,2).split("0+").length*2-n%2;}

मुझे पता है कि यह एक बेहतर जवाब के एक बंदरगाह से पीटा जा सकता है, लेकिन मैं इसके साथ चैट में आया था, और पोक के बारे में कुछ कहने के बाद मैं इसे पोस्ट नहीं कर सकता :)


0

सी, 76 बाइट्स

unsigned n,m,i;f(x){for(i=0;x;x^=m-1,i++)for(n=x,m=2;n>>=1;m<<=1);return i;}

सभी परीक्षण मामलों के लिए काम करता है (जितना मैं अहस्ताक्षरित या अंतिम परीक्षण मामले को शामिल नहीं करना चाहता) ...


0

बैश, 57 बाइट्स

संकुल: कोर उपयोगिताएँ, grep, sed, vim (for) xxd )

मान लें कि संख्या बाइनरी प्रारूप में दी गई है। किसी भी लंबाई स्वीकार्य है :)

xxd -b -c1|cut -d" " -f2|sed s/^0*//|grep -o .|uniq|wc -l


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.