कुछ कथन (ओं) को लिखें जो एक अहस्ताक्षरित सोलह-बिट पूर्णांक में लोगों की संख्या की गणना करेंगे।
उदाहरण के लिए, यदि इनपुट है 1337
, तो इसका परिणाम यह है 6
क्योंकि 1337
सोलह बिट बाइनरी संख्या है 0000010100111001
, जिसमें छह शामिल हैं।
कुछ कथन (ओं) को लिखें जो एक अहस्ताक्षरित सोलह-बिट पूर्णांक में लोगों की संख्या की गणना करेंगे।
उदाहरण के लिए, यदि इनपुट है 1337
, तो इसका परिणाम यह है 6
क्योंकि 1337
सोलह बिट बाइनरी संख्या है 0000010100111001
, जिसमें छह शामिल हैं।
जवाबों:
F3 0F B8 C1
जो पूर्णांक को अंदर ले जाता है cx
और गिनती को आउटपुट करता है ax
, और इसके बराबर होता है:
popcnt ax, cx ; F3 0F B8 C1
और यहाँ एक 11 10 बाइट समाधान है जो POPCNT का उपयोग नहीं कर रहा है:
31 C0 D1 E9 10 E0 85 C9 75 F8
जो इसके बराबर है:
xor ax, ax ; 31 C0 Set ax to 0
shr cx, 1 ; D1 E9 Shift cx to the right by 1 (cx >> 1)
adc al, ah ; 10 E0 al += (ah = 0) + (cf = rightmost bit before shifting)
test cx, cx ; 85 C9 Check if cx == 0
jnz $-6 ; 75 F8 Jump up to shr cx, 1 if not
ax
और इसके cx
साथ eax
और ecx
32-बिट में बदल जाता है। बाईटेकोड या तो एक ही है।
for(n=0;x;n++)x&=x-1;
आपने कहा "कुछ कथन लिखें" ("एक फ़ंक्शन" नहीं) तो मैंने मान लिया है कि संख्या में आपूर्ति की गई है x
और 1 की संख्या में वापस आ गई है n
। अगर मुझे इनिशियलाइज़ नहीं करना है तो n
मैं 3 बाइट्स बचा सकता हूँ।
यह x&x-1
परीक्षण के लिए प्रसिद्ध अभिव्यक्ति का एक अनुकूलन है अगर कुछ 2 की शक्ति है (गलत है अगर यह सच है, अगर यह नहीं है।)
यहां यह प्रश्न से 1337 नंबर पर कार्रवाई में है। ध्यान दें कि 1 घटाना कम से कम 1 महत्वपूर्ण बिट और सभी शून्य को सही पर प्रवाहित करता है।
0000010100111001 & 0000010100111000 = 0000010100111000
0000010100111000 & 0000010100110111 = 0000010100110000
0000010100110000 & 0000010100101111 = 0000010100100000
0000010100100000 & 0000010100011111 = 0000010100000000
0000010100000000 & 0000010011111111 = 0000010000000000
0000010000000000 & 0000001111111111 = 0000000000000000
संपादित करें: पूर्णता के लिए, यहां भोली एल्गोरिथ्म है, जो एक बाइट लंबा है (और काफी धीमा है)।
for(n=0;x;x/=2)n+=x&1;
{}
। यह इतना आसान काम है कि मुझे आश्चर्य नहीं होना चाहिए कि कोई व्यक्ति पहले से ही इसके साथ आया था।
for(n=0;x;x/=2)n+=x&1;
n->sum(digits(n,2))
यह एक गुमनाम समारोह है कि एक ही तर्क को स्वीकार करता है बनाता है, n
। इसका उपयोग करने के लिए, इसे कुछ इस तरह असाइन f=n->...
करें और इसे कॉल करें f(1337)
।
digits()
समारोह, जब 2 तर्कों के साथ कॉल, यह देखते हुए आधार में इनपुट के अंक की एक सरणी देता है। तो digits(n, 2)
के द्विआधारी अंक लौटाता है n
। सरणी का योग लें और आपके पास बाइनरी प्रतिनिधित्व में लोगों की संख्या है n
।
count_ones
ri2b:+
ri "Read the input and convert it to integer";
2b "Convert the integer into base 2 format";
:+ "Sum the digits of base 2 form";
sum(intToBits(scan())>0)
scan()
स्टड से इनपुट पढ़ता है।
intToBits()
एक पूर्णांक लेता है और raw
इनपुट के द्विआधारी प्रतिनिधित्व वाले शून्य और एक प्रकार के वेक्टर को लौटाता है ।
intToBits(scan())>0
एक तार्किक वेक्टर लौटाता है जहां प्रत्येक तत्व है TRUE
यदि संबंधित बाइनरी वेक्टर तत्व 1 है (चूंकि सभी तत्व 0 या 1 और 1> 0 हैं), अन्यथा FALSE
।
आर में, आप TRUE
तत्वों की संख्या प्राप्त करने के लिए एक तार्किक वेक्टर को जोड़ सकते हैं, इसलिए ऊपर दिए गए तार्किकों के वेक्टर को योग करें जैसा कि हम चाहते हैं।
ध्यान दें कि इनपुट को सीधे sum()
हैंडल नहीं किया जा सकता है raw
, इसलिए तार्किकों का उपयोग करके समाधान।
sum(intToBits(scan()))
एक ही नहीं होगा ?
sum()
प्रकार का इनपुट नहीं ले सकता है raw
, जो कि वापस आ गया है intToBits()
।
: c ?dup if dup 1- and recurse 1+ then ;
0 1337 c
यदि एक वास्तविक कार्य की आवश्यकता है तो दूसरी पंक्ति बन जाती है
: c 0 swap c ;
और आप इसे "1337 सी" से बुलाते हैं। फोर्थ के अपेक्षाकृत क्रिया नियंत्रण शब्द इसे एक कठिन बनाते हैं (वास्तव में, ये बहुत कठिन बनाते हैं)।
संपादित करें: मेरे पिछले संस्करण ने नकारात्मक संख्याओं को सही ढंग से नहीं संभाला।
मुझे याद दिलाने के लिए एलेफाल्फा का शुक्रिया DigitCount
।
DigitCount[#,2,1]&
यह एक सरल पुनरावर्ती कार्य है जिसे थोड़ा और छोटा किया जा सकता है। यह बस थोड़ा सा लेता है और खुद को फिर से चलाता है:
B=n=>n&&(1&n)+B(n>>1)
इसे http://www.es6fiddle.net/imt5ilve/ (आपको इसकी var
वजह से आवश्यकता है 'use strict';
) पर आज़माएं ।
मैं विश्वास नहीं कर सकता कि मैंने मछली पीटी है !!!
पुराना वाला:
n=>n.toString(2).split(1).length-1
दोनों कार्यों को आसानी से ES5 के लिए अनुकूलित किया जा सकता है:
function B(n){return n?(1&n)+B(n>>1):0}
//ungolfed:
function B(number)
{
if( number > 0 )
{
//arguments.callee points to the function itself
return (number & 1) + arguments.callee( number >> 1 );
}
else
{
return 0;
}
}
पुराना वाला:
function(n){return n.toString(2).split(1).length-1}
@ user1455003 ने मुझे एक बहुत अच्छा विचार दिया, जो कि सबसे छोटा 'ट्रिगर' था:
function B(n,x){for(x=0;n;n>>=1)x+=n&1;return x}
मैंने इसे ES6 में ढाल लिया है और इसे बहुत छोटा करने के लिए पुनरावर्ती बना दिया है!
0$11.>~n;
2,:?!^:2%:{+}-
कार्यक्रम केवल मॉड 2 को दोहराता है, घटाना और विभाजित करता है जब तक कि इनपुट नंबर शून्य नहीं हो जाता है, तब मॉड 2 के योग को प्रिंट करता है।
-v
ध्वज के साथ परीक्षण करें , जैसे
py -3 fish.py ones.fish -v 1337
-v
ध्वज संस्करण अभी भी काम करता है।)
यह मेरे ES6 उत्तर के समान aproach का उपयोग करता है
<?=count(split(1,decbin($_GET[n])))-1;
यह एक पूर्ण कोड है, आपको केवल इसे एक फ़ाइल में डालना और इसे पैरामीटर के साथ ब्राउज़र पर एक्सेस करना होगा n=<number>
।
यह थोड़ा छोटा है:
<?=count(split(1,decbin($n)))-1;
यह केवल PHP <4.2 पर मज़बूती से काम करता है क्योंकि निर्देश register_globals
सेट किया गया थाOff
PHP4.2 से PHP5.4 तक डिफ़ॉल्ट रूप से गया था (जो तब तक हटा दिया गया था)।
यदि आप एक php.ini
फ़ाइल बनाते हैं register_globals=On
, तो यह काम करेगा।
कोड का उपयोग करने के लिए, POST या GET के साथ, ब्राउज़र का उपयोग करके फ़ाइल तक पहुँचें।
उन्होंने 2 वास्तव में अच्छे सुझाव दिए जिनका फ़ंक्शन का बहुत दिलचस्प उपयोग है array_sum
:
38 बाइट्स:
<?=array_sum(str_split(decbin(1337)));
45 बाइट्स:
<?=array_sum(preg_split('//', decbin(1337)));
यह वास्तव में बहुत अच्छा विचार है और इसे थोड़ा और छोटा किया जा सकता है, 36 बाइट्स लंबा होने के लिए:
<?=array_sum(split(1,decbin(1337)));
<?=substr_count(decbin(1337),"1");
(34 बाइट)
<?=substr_count(decbin(1337),1);
:। यह कुल 32 बाइट्स है। यह मानते हुए कि यह एक अलग-पर्याप्त कोड है, क्या आप इसे अपने उत्तर के रूप में पोस्ट नहीं करना चाहते हैं? मैं निश्चित रूप से इसे बढ़ा दूंगा!
<?=substr_count(decbin($argv[1]),1);
(या $_GET[n]
; 36 बाइट्स)
¢o1 l
साथ ही काम करेगा। एक और दिलचस्प दृष्टिकोण है -¢¬r-0
; ¢¬
बाइनरी अंकों की सरणी में विभाजन, r-0
घटाव द्वारा कम कर देता है, 0 से शुरू होता है, और -
परिणाम को नकारता है, जिससे यह सकारात्मक हो जाता है।
¢¬x
।
गैर-प्रतिस्पर्धात्मक उत्तर। इस चुनौती की तुलना में बीज़वैक्स नया है।
यह समाधान ब्रायन खेरिगन की "बिट ट्विडलिंग हैक्स" वेबसाइट से सेट बिट्स की गिनती के तरीके का उपयोग करता है।
यह सिर्फ एक लूप के माध्यम से चलता है, बिट काउंट को बढ़ाता है, जब number=number&(number-1)
तक कि इसके माध्यम से पुनरावृत्ति नहीं होती है number = 0
। समाधान केवल लूप से गुजरता है जितनी बार बिट्स सेट होते हैं।
मैं कुछ निर्देशों को फिर से व्यवस्थित करके 4 बाइट्स से बच सकता हूं। स्रोत कोड और स्पष्टीकरण दोनों अपडेट हुए:
pT_
>"p~0+M~p
d~0~@P@&<
{@<
स्पष्टीकरण:
pT_ generate IP, input Integer, redirect
>" if top lstack value > 0 jump next instruction,
otherwise continue at next instruction
p redirect if top lstack value=0 (see below)
~ flip top and 2nd lstack values
0+ set top lstack value to 0, set top=top+2nd
M decrement top lstack value
~ flip top and 2nd lstack values
p redirect to lower left
< redirect to left
& top=top&2nd
@ flip top and 3rd lstack values
@P increment top lstack value, flip top and 3rd values
~0~ flip top and 2nd values, set top=0, flip top and 2nd again
d redirect to upper left
>"p~0+M..... loop back
p if top lstack = 0 at " instruction (see above), redirect
0 set lstack top to zero (irrelevant instruction)
< redirect to the left
@ flip top and 3rd lstack values
{ output top lstack value as integer (bitcount)
बीटवॉक्स दुभाषिया, भाषा कल्पना और उदाहरणों से युक्त मेरे गीथह रिपॉजिटरी को क्लोन करें ।
काम करता है के लिए byte
, short
, char
, और int
। एक मेमने के रूप में उपयोग करें।
Integer::bitCount
बिल्ट-इन का उपयोग किए बिना:
42 बाइट्स
s->{int c=0;for(;s!=0;c++)s&=s-1;return c}
sum(dec2bin(s)-48)
उदाहरण:
octave:1> s=1337
s = 1337
octave:2> sum(dec2bin(s)-48)
ans = 6
"$([char[]][convert]::ToString($s,2)|%{"+$_"})"|iex
स्पष्टीकरण: से
[convert]::ToString($s,2)
एक बाइनरी स्ट्रिंग प्रतिनिधित्व का उत्पादन करता है $s
।
[char[]]
इसे एक वर्ण सरणी के रूप में रखता है और हमें प्रत्येक वर्ण की गणना करने की अनुमति देता है।
|%{"+$_"}
प्रत्येक अक्षर को + साइन के साथ प्रीपेक्ट करता है जिसके परिणामस्वरूप उप अभिव्यक्ति पाईपिंग स्ट्रिंग को
"$()"
सम्मिलित करती है (यानी। "+1 +0 +1 +1 +0 +1 +0 +0" = 4).ToString()
|iex
-join
ऑपरेटर का उपयोग क्यों न करें और .ToString()
45 बाइट्स प्राप्त करने के लिए एक निहितार्थ [char[]][convert]::ToString($s,2)-join'+'|iex
... या, एक अलग दृष्टिकोण के रूप में इनलाइन -replace
ऑपरेटर 43 बाइट्स प्राप्त करने के लिए उपयोग करें([convert]::ToString($s,2)-replace0).length
#(count(filter #{\1}(Long/toString % 2)))
दायें से बायें पढ़ना, बाइनरी स्ट्रिंग में बदलना, वर्णों के अनुक्रम में बदलना, 1
s पर फ़िल्टर करना और गिनना कि आपके पास कितने हैं।
सिडग की मदद से पूरा
#(count(filter #{\1}(Integer/toString% 2)))
#(count(filter #{\1}(Integer/toString % 2)))
CompilerException java.lang.IllegalArgumentException: No matching method: toString_PERCENT_
Integer/toString
। हालांकि यह एक दूसरे से पहले काम किया था।
t 0=[]
t n=t(quot n 2)++[rem n 2]
f=sum.t
f :: Integer -> Integer
इंटरैक्टिव दुभाषिया के रूप में फ़ंक्शन उपयोग की घोषणा करता है f <number>
या main=print$f <number>
फ़ाइल के अंत में लाइन जोड़ता है ।
rem n 2
इसकी सूची बनाने और div
इसके बजाय उपयोग करने के बजाय सीधे s को बहुत अधिक बाइट्स बचा सकते हैं quot
: t 0=0
t n=t(div n 2)+rem n 2
- f
अब और नहीं।
⨭⟦ïⓑ
इनपुट को बाइनरी में कनवर्ट करता है, चार्ट के साथ विभाजन करता है, और परिणामी सरणी का योग प्राप्त करता है।