พิมพ์จำนวนของคนในจำนวนไบนารีโดยไม่ใช้ตัวดำเนินการระดับบิต


14

ลักษณะ

กำหนดตัวเลขให้พิมพ์จำนวน1s ที่มีอยู่ในการแสดงเลขฐานสอง

อินพุต

ตัวเลข>= 0ในฐาน 10 ที่จะไม่เกินจำนวนสูงสุดที่ภาษาของคุณสามารถจัดการได้

เอาท์พุต

จำนวนของ1s ในการเป็นตัวแทนไบนารี

สภาพการชนะ

รหัสที่สั้นที่สุดชนะ

ไม่ได้รับอนุญาต

  • ผู้ประกอบการระดับบิต อนุญาตให้ใช้ตัวดำเนินการอื่นเช่นการบวกและการคูณ
  • ฟังก์ชั่นการแปลงฐานในตัว

ตัวอย่าง

Input:     Ouput:

56432      8


Input:     Output:

45781254   11


Input:     Output:

0          0

ฟังก์ชั่นอนุญาตหรือไม่ ฉันต้องการสร้างโซลูชัน Java แต่การเขียนโค้ดแบบเต็มน่าเบื่อเกินไป ... : /
HyperNeutrino

1
ฉันเดาว่าฉันจะไม่ใช้Wiseสำหรับความท้าทายนี้ ... :)
MildlyMilquetoast

คำตอบ:


16

APL, 9 12 ตัวอักษร

+/2|⌊⎕÷2*⍳32

สิ่งนี้อนุมานว่าล่ามใช้จำนวนเต็ม 32 บิตและ⎕IOตั้งค่าเป็น 0 (หมายถึงว่า monadic เริ่มต้นด้วย 0 แทนที่จะเป็น 1) ผมใช้รุ่น 32 บิตของDyalog APL

คำอธิบายจากขวาไปซ้าย:

  • ⍳32สร้างเวกเตอร์ของ32จำนวนเต็มแรก(ดังอธิบายก่อนหน้านี้เนื่องจาก⎕IOเป็น 0 เวกเตอร์นี้เริ่มต้นด้วย 0)
  • *เป็นฟังก์ชั่นพลังงาน ในกรณีนี้มันจะสร้าง2พลังงานของแต่ละองค์ประกอบของเวกเตอร์ที่ระบุเป็นอาร์กิวเมนต์ที่ถูกต้อง
  • ÷เป็นฟังก์ชันหารด้วย มันทำให้เรา(ประเมินผู้ใช้อินพุต) หารด้วยแต่ละองค์ประกอบของเวกเตอร์ไปทางขวา (แต่ละกำลังสอง)
  • ชั้นแต่ละองค์ประกอบของการโต้แย้งไปทางขวา
  • 2|2จะช่วยให้เราที่เหลือขององค์ประกอบของไปทางขวาของตนโดยแบ่งออกเป็นแต่ละ
  • /ลด (เท่า) +การโต้แย้งสิทธิของใช้ฟังก์ชั่นทางด้านซ้ายของ

ไม่มาก 9 ตัวอักษรอีกต่อไป :(

รุ่นเก่าที่ละเมิดกฎ:

+/⎕⊤⍨32/2

คำอธิบายจากขวาไปซ้าย:

  • 32/2: ซ้ำ2, 32ครั้ง
  • commutes ฟังก์ชัน dyadic ทางด้านซ้ายซึ่งในกรณีนี้คือ(กล่าวX⊤⍨Yคือเทียบเท่าY⊤X)
  • เป็นฟังก์ชั่นการเข้ารหัส มันเข้ารหัสจำนวนเต็มไปทางขวาในฐานที่ให้ไว้ทางด้านซ้าย โปรดทราบว่าเนื่องจากตัวดำเนินการเดินทางข้อโต้แย้งด้านขวาและซ้ายจะเปลี่ยน 32/2ฐานเป็นซ้ำสำหรับจำนวนของตัวเลขที่จำเป็นจึง
  • เป็นฟังก์ชัน niladic ที่ยอมรับอินพุตของผู้ใช้และประเมินค่า
  • +/ลด (เท่า) +การโต้แย้งสิทธิของใช้ (เราเพิ่มค่า 0 และ 1)

2
สิ่งนี้จะไม่ทำลายความBuilt-in base conversion functionsขัดแย้งหรือไม่?
Gareth

อ๊ะ! พลาดที่เดียว
Dillon Cower

Gah! คิดว่าฉันจะให้โอกาสตัวเองกับโปรแกรม J ของฉัน! :-) งานที่ดี.
Gareth

@ กาเร็ ธ : ฉันไม่ได้ตระหนักจนกระทั่งอ่านคำอธิบายของคุณในตอนนี้ แต่คำตอบของฉันก็ค่อนข้างเหมือนกับคุณ! ฉันเดาว่าอาจจะคาดหวังจาก APL เจ :)
ดิลลอน cower

11

Brainbool , 2

,.

การตีความที่เหมาะสมที่สุดในความคิดของฉัน (และสิ่งที่ดีที่สุดของคำตอบที่ใช้) ของ "จำนวนมากที่สุดภาษาของคุณจะสามารถจัดการกับ" คือ "ที่ใหญ่ที่สุดในจำนวนภาษาของคุณnativelyสนับสนุน" Brainbool เป็นอนุพันธ์ brainfuck ที่ใช้บิตมากกว่าไบต์และรับอินพุตและเอาต์พุตในไบนารี ( 0และ1ตัวละคร) มากกว่ารหัสตัวอักษร ดังนั้นจำนวนที่รองรับได้มากที่สุดจึง1มีค่าน้อยที่สุด0ซึ่งมีน้ำหนักของ Hamming 1และ0ตามลำดับ

Brainbool ถูกสร้างขึ้นในปี 2010 ตาม Esolang


9
ฉันรู้ว่ามันต้องมีอยู่จริง แต่ฉันใช้เวลาหนึ่งชั่วโมงในการเรียงลำดับผ่านอนุพันธ์ Brainfuck ใน Esolang เพื่อค้นหา Brainbool
lirtosiast

8

J, 13 ตัวอักษร

(+ จำนวนหลักในจำนวน)

+/2|<.n%2^i.32

การใช้งาน: แทนที่nในโปรแกรมด้วยหมายเลขที่จะทดสอบ

ตัวอย่าง:

+/2|<.56432%2^i.32
8
+/2|<.45781254%2^i.32
11
+/2|<.0%2^i.32
0

อาจมีวิธีการจัดเรียงใหม่เพื่อให้หมายเลขสามารถวางไว้ที่จุดเริ่มต้นหรือจุดสิ้นสุด แต่นี่คือรายการ J แรกของฉันและหัวของฉันเจ็บเล็กน้อยในขณะนี้

คำอธิบาย (ส่วนใหญ่เพื่อให้ฉันเข้าใจในอนาคต)

i.32 - สร้างอาร์เรย์ของตัวเลข 1 ถึง 32

2^ - เปลี่ยนรายการเป็นพลังของสอง 1 ถึง 4294967296

n% - หารจำนวนอินพุตโดยแต่ละองค์ประกอบในรายการ

<. - ปัดเศษผลการหารทั้งหมดให้เป็นจำนวนเต็มถัดไป

2|- เช่นเดียวกับ%2ในภาษาส่วนใหญ่ - ส่งกลับ 0 ถ้าคู่และ 1 ถ้าคี่

+/ - รวมรายการในรายการ (ซึ่งตอนนี้เหลือเพียง 1 วินาทีหรือ 0 วินาที)


ฉันยินดีที่จะอัปโหลดเรื่องนี้เมื่ออ่านจาก stdin (หรืออะไรก็ตามที่เทียบเท่ากับ J)
Steven Rumbalski

ที่ดีที่สุดที่ฉันสามารถทำได้ฉันคิดว่า (อาจจะขึ้นอยู่กับการหาวิธี) คือย้ายอินพุตไปยังจุดสิ้นสุดของโปรแกรม อินพุตมาตรฐานไม่ได้ถูกกล่าวถึงในคำถาม
Gareth

ฉันขอโทษที่ไม่ได้ระบุวิธีการป้อนข้อมูล มันจะไม่ยุติธรรมที่จะเปลี่ยนกฎตอนนี้ดังนั้นฉันจะยอมรับกฎนี้ ฉันจะพูดถึงมันในครั้งต่อไป!
pimvdb

@pvdvdb ไม่มีปัญหามันไม่ใช่เรื่องร้องเรียน ฉันคิดว่ากับโปรแกรม J แม้ว่าสิ่งที่คุณทำได้คือกำหนดคำกริยาที่ทำงานกับอินพุตที่ให้ ไม่แน่ใจว่าฉันจะจัดการเรื่องนี้อย่างไร บางที JB หรือหนึ่งในผู้เชี่ยวชาญ J คนอื่น ๆ ก็สามารถช่วยฉันได้ ...
Gareth

... และเมื่ออ่านรายละเอียดเพิ่มเติมตอนนี้ฉันเห็นว่าฉันผิดอย่างสมบูรณ์เกี่ยวกับอินพุตมาตรฐาน
Gareth

8

Brainfuck, 53 ตัวอักษร

สิ่งนี้ขาดวิธีแก้ปัญหาของ Brainfuck ดังนั้นฉันจึงทำสิ่งนี้:

[[->+<[->->>>+<<]>[->>>>+<<]<<<]>>>>[-<<<<+>>>>]<<<<]

รับหมายเลขจากเซลล์ 1 และใส่ผลลัพธ์ลงในเซลล์ 6

รุ่นที่ไม่ได้ลงทะเบียนและแสดงความคิดเห็น:

[  while n != 0
  [  div 2 loop
    -
    >+<  marker for if/else
    [->->>>+<<]  if n != 0 inc n/2
    >
    [->>>>+<<]  else inc m
    <<<
  ]
  >>>>  move n/2 back to n
  [-<<<<+>>>>]
  <<<<
]

6

Python 2.6, 41 ตัวอักษร

t,n=0,input()
while n:t+=n%2;n/=2
print t

หมายเหตุ:คำตอบอื่น ๆ ของฉันใช้แลมบ์ดาและการเรียกซ้ำและหนึ่งคำนี้ใช้ลูป while ฉันคิดว่าพวกเขาแตกต่างกันพอที่จะรับประกันสองคำตอบ



5

GolfScript, 17 16 ตัวอักษร

~{.2%\2/.}do]0-,

แก้ไข:รุ่นใหม่ช่วยประหยัด 1 ตัวอักษรโดยใช้การดำเนินรายการแทนเท่า (รุ่นเดิมคือ~{.2%\2/.}do]{+}*รุ่นนับโดยตรง~0\{.2%@+\2/.}do;)


5

C, 45

f(n,c){for(c=0;n;n/=2)c+=n%2;printf("%d",c);}

ไม่มีอะไรพิเศษจริงๆที่นี่สำหรับการเล่นกอล์ฟใน C: ประเภทผลตอบแทนโดยนัย, ประเภทจำนวนเต็มโดยปริยายสำหรับพารามิเตอร์


4

Python 2.6, 45 ตัวอักษร

b=lambda n:n and n%2+b(n/2) 
print b(input())

1
สามารถทำให้สั้นลงได้โดยใช้อักขระสองตัวโดยใช้defแทนแลมบ์ดา
Konrad Rudolph

1
@KonradRudolph: ที่จริงแล้วคุณเสียความได้เปรียบเมื่อรวมคำสั่ง return
Steven Rumbalski

โอ๊ะฉันลืมไปแล้ว โง่.
Konrad Rudolph

print b(input())คุณไม่จำเป็นต้อง เป็นที่ยอมรับได้ในการส่งคืนค่าและรับ "อินพุต" เป็นอาร์กิวเมนต์สำหรับฟังก์ชัน
caird coinheringaahing

4

Perl, 45 43 36 ตัวละคร

$n=<>;while($n){$_+=$n%2;$n/=2}print

ขอบคุณ Howard สำหรับ 45-> 43 และเพื่อ User606723 สำหรับ 43-> 36


คุณอาจใช้$n=int($n/2)ตัวอักษรสั้นกว่า 2 ตัว
โฮเวิร์ด

เราแน่ใจว่าเราต้องการ int ()? $n=<>;while($n){$_+=$n%2;$n/=2}printสิ่งนี้จะวนซ้ำจนกระทั่ง $ n / 2 จนเข้าใกล้ 0 มากที่สุด แต่เราสนใจไหม ;)
606723

@ user606723 ฉันเพิ่งลองและดูเหมือนว่าจะทำงานได้อย่างสมบูรณ์แบบอย่างน้อยสำหรับทุกกรณีถึง 1,000
PhiNotPi

3

Perl, 30 ตัวอักษร

$==<>;1while$_+=$=%2,$=/=2;say

ขึ้นอยู่กับวิธีการแก้ปัญหาของ PhiNotPiพร้อมการเล่นกอล์ฟเพิ่มเติม ทำงานด้วยperl -M5.010เพื่อเปิดใช้งานsayคุณสมบัติPerl 5.10


ที่ไม่$=ตัวแปรพิเศษทำอะไรเป็นพิเศษในโปรแกรมของคุณหรือมันเป็นเพียงอีกหนึ่งตัวแปรธรรมดา?
PhiNotPi

2
@PhiNotPi: $=ใช้ค่าจำนวนเต็มเท่านั้นดังนั้นการใช้จะช่วยฉันintได้
Ilmari Karonen

อาร์กิวเมนต์บรรทัดคำสั่งไม่ควรเป็นส่วนหนึ่งของการนับถ่านหรือไม่
Soham Chowdhury

@SohamChowdhury: ไม่ต่อเมตาดาต้าเธรดนี้
Ilmari Karonen

3

Lisp ทั่วไป 12 ตัวอักษร

(สมมติว่าชื่อตัวแปร 1 ถ่าน - เช่น: ความยาว 11 + หมายเลข)

มันไม่ใช่ฟังก์ชันการแปลงพื้นฐานดังนั้นจึงควรทำงาน:

(logcount x)

ตัวอย่าง:

[1]> (logcount 0)
0
[2]> (logcount 1)
1
[3]> (logcount 1024)
1
[4]> (logcount 1023)
10
[5]> (logcount 1234567890123456789012345678901234567890)
68

(ใช้ GNU CLISP)


หืมมม, ไม่ใช่อย่างที่ฉันคิดไว้เพื่อดูว่าเป็นคำตอบ :) ฉันไม่คิดว่าฉันจะยอมรับสิ่งนี้ได้ มันเป็นพื้นเพียงกรณีของผู้อื่นนี้
pimvdb

3

C, 61 60 57 53 ตัวอักษร

void f(x){int i=0;for(;x;x/=2)i+=x%2;printf("%u",i);}

ฟังก์ชั่นร่างกายเท่านั้นคือ 38 ตัวอักษร แก้ไข : ลบตัวดำเนินการบิตเรตแก้ไข : นำprintfออกจากลูปตามที่แนะนำในข้อคิดเห็นแก้ไข : สลับไปยังการประกาศ K&R; นอกจากนี้ไม่เฉพาะ C99 อีกต่อไป


ฉันเห็นค่าที่เหมาะสม
Joanis

ฉันขอโทษ แต่ตัวดำเนินการ AND ยังนับเป็นตัวดำเนินการระดับบิต
pimvdb

@ M.Jananis: เอ่อขอบคุณที่สังเกต แก้ไขแล้ว.
sam hocevar

1
ฉันคิดว่าคุณสามารถสำรองตัวละครได้สองสามตัวถ้าคุณเปลี่ยนมาเป็น K&R C. ถ้าคุณตกลง
JB

คุณสามารถย่อให้สั้นลงได้สี่ตัวอักษรโดยเลื่อน printf ออกจากลูป
marinus

3

dc – 26 chars

This is rather long, mostly due to the lack of loop constructs in dc.

0?[d2%rsi+li2/d0<x]dsxx+p

Keeps adding up the modulo 2 of the number and dividing the number by to until it reaches zero. Can handle arbitrarily long integers.

Example:

$ dc -e '0?[d2%rsi+li2/d0<x]dsxx+p' <<< 127
7
$ dc countones.dc <<< 1273434547453452352342346734573465732856238472384263456458235374653784538469120235
138

3

C, 66 characters

main(int n,char **a){printf("%u",__builtin_popcount(atoi(a[1])))};

Note: requires gcc or gcc-compatible compiler (e.g. ICC, clang).

For some CPUs __builtin_popcount compiles to a single instruction (e.g. POPCNT on x86).


Is it correct that __builtin_popcount actually just implements the counting of 1s itself? If so, although it's not strictly wrong according to the rules I honestly don't think this is a fair entry.
pimvdb

You should probably stipulate this in the question if you want to disallow entries that take advantage of built-in capabilities of a given language or compiler.
Paul R

This is not legal C++ because in C++ you cannot omit the return type on main, nor use printf without prior include.
celtschk

@celtschk: fair point - edited out the C++
Paul R

2

JavaScript, 78 72 71 characters

I'll post my initial solution which I came up with before posting the question as well. There is already a much better JavaScript answer though :)

for(n=prompt(a=0),j=1;j<=n;j*=2)for(i=j;i<=n;i+=2*j)n<i+j&&a++;alert(a)

http://jsfiddle.net/Mk8zd/1/

The idea comes from certain "mind reading cards" which enable you to obtain the number someone else has in mind, by showing them cards and let them say on which cards their number is apparent.

It works because each number is a unique combination of 1s / 0s in binary. My solution checks on which "cards" the number is apparent so as to determine how many 1s it has. It's just not very efficient, though...

I found this document which outlines the mind reading technique.



2

PHP, 57

$i=$s=0;for(;$i<log($n,2);){$s+=$n/pow(2,$i++)%2;}echo$s;

This assumes that $n holds the value to be tested.

PHP, 55 (alternative solution)

function b($i){return$i|0?($i%2)+b($i/2):0;}echo b($n);

Again, this assumes that $n holds the value to be tested. This is an alternative because it uses the or-operator to floor the input.

Both solutions work and do not cause notices.


2

Ocaml, 45 characters

Based on @Leah Xue's solution. Three spaces could be removed and it's sligthly shorter (~3 characters) to use function instead of if-then-else.

let rec o=function 0->0|x->(x mod 2)+(o(x/2))  




1

R, 53 characters

o=function(n){h=n%/%2;n%%2+if(h)o(h)else 0};o(scan())

Examples:

> o=function(n){h=n%/%2;n%%2+if(h)o(h)else 0};o(scan())
1: 56432
2: 
Read 1 item
[1] 8
> o=function(n){h=n%/%2;n%%2+if(h)o(h)else 0};o(scan())
1: 45781254
2: 
Read 1 item
[1] 11
> o=function(n){h=n%/%2;n%%2+if(h)o(h)else 0};o(scan())
1: 0
2: 
Read 1 item
[1] 0

If inputting the number is not part of the character count, then it is 43 characters:

o=function(n){h=n%/%2;n%%2+if(h)o(h)else 0}

with test cases

> o(56432)
[1] 8
> o(45781254)
[1] 11
> o(0)
[1] 0


1

Scheme

I polished the rules a bit to add to the challenge. The function doesn't care about the base of the number because it uses its own binary scale. I was inspired by the way analog to numeric conversion works. I just use plain recursion for this:

(define (find-ones n)
  (define (nbits n)
    (let nbits ([i 2])
      (if (< i n) (nbits (* i 2)) i)))
  (let f ([half (/ (nbits n) 2)] [i 0] [n n])
    (cond [(< half 2) i]
      [(< n i) (f (/ half 2) i (/ n 2))]
      [else (f (/ half 2) (+ i 1) (/ n 2))])))

1

Isn't reading a number into binary or printing the number from binary a "builtin base conversion function", thus invalidating every answer above that prints an integer? If you permit reading and printing an integer, like almost all the above answers do, then I'll make claims using a builtin popcount function :

Haskell, 50

There was a popCount routine added to the Data.Bits module for GHC v7.2.1/v7.4.1 this summer (see tickets concerning the primop and binding).

import Data.Bits
main=interact$show.popCount.read

I cannot beat the above Python and Perl scores using their GMPY or GMP::Mpz modules for GMP sadly, although GMP does offer a popcount function too.


1

JavaScript, 49 47 45 42 bytes

for(n=prompt(o=0);n=n/2|0;o+=n%2);alert(o)

Demo: http://jsfiddle.net/hcYdx/4/

Edit 1: remove q and use ~~ for rounding, save 2 chars.

Edit 2: use |0 rounding operator instead of ~~ to save parentheses (2 chars).

Edit 3: simplify n>0 to n and combine with n=n/2|0 to make entire condition; now have wasted statement space :(


3
Isn't the |0 a bitwise operator?
Vilx-

Technically yes. But i'm using it purely to round to the nearest int, so I'm not getting any bit-wise benefit :)
mellamokb

Smells like bending the rules to me... but I'm not the judge.
Vilx-

Input 1 gives output 0.
Atreys

1
| is bitwise operator... it is disallowed. Time to do Math.round :-)
Jamie

1

Java 7, 36 bytes

int b(Long a){return a.bitCount(a);}

Because of course this, of all things, is something that Java has a builtin for...


Doesn't this fit under "built-in base-conversion functions", which are banned?
FlipTack

@Flp.Tkc I'm not actually doing base-conversion. I have no idea how bitCount operates under the hood.
Poke

this seems like just using a bulitin to do the job, but ok...
FlipTack

@Flp.Tkc That's... exactly what it is? I'm even including all required libraries (there aren't any). This is demonstrating the strength of the language! related meta
Poke


1

PHP, 36 bytes

while($n){$o+=$n%2;$n/=2*1;}echo $o;

Assumes $n is the number to be tested, shows a PHP Notice for $o, and doesn't exactly work when $n is 0 (outputs nothing).

PHP, 53 bytes

$n=$argv[1];$o=0;while($n){$o+=$n%2;$n/=2*1;}echo $o;

Accepts command-line input, doesn't show a PHP Notice, and outputs correctly for 0.


Welcome to the site! :)
James
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.