在不使用按位运算符的情况下,以二进制数打印1的数量


14

描述

给定一个数字,1以二进制表示形式打印它具有的s 数量。

输入值

>= 0以10为底的数字不会超过您的语言能够处理的最高数字。

输出量

1s 的数量(以二进制表示)。

获奖条件

最短的代码获胜。

不允许的

  • 按位运算符。允许其他运算符,例如加法和乘法。
  • 内置基本转换功能。

例子

Input:     Ouput:

56432      8


Input:     Output:

45781254   11


Input:     Output:

0          0

是否允许功能?我想制作一个Java解决方案,但是编写完整的代码太繁琐了……:/
HyperNeutrino

1
我想我不会用Wise来挑战... :)
MildlyMilquetoast

Answers:


16

APL,9个12个字符

+/2|⌊⎕÷2*⍳32

假定解释器使用32位整数,并且将⎕IO其设置为0(表示monadic 以0而不是1开头)。我使用了32位版本的Dyalog APL

从右到左的解释:

  • ⍳32生成一个前32整数的向量(如前所述,因为⎕IO为0,所以该向量从0开始)。
  • *是幂函数。在这种情况下,它生成2作为其右引数提供的向量的每个元素的幂。
  • ÷是除法功能。它使我们(评估的用户输入)除以矢量右边的每个元素(每个为2的幂)。
  • 将参数的每个元素置于其右边。
  • 2| 给我们右边的每个元素的其余部分除以 2
  • / 使用其左侧的函数减少(折叠)其右侧参数, +

不再是9个字符了。:(

违反规则的旧版本:

+/⎕⊤⍨32/2

从右到左的解释:

  • 32/2:复制232次数。
  • 将二进位函数换向其左侧,在这种情况下为(即,X⊤⍨Y等于Y⊤X)。
  • 是编码功能。它在给定其左边的底数中对右边的整数进行编码。注意,由于使用了通勤运算符,左右参数将被切换。对所需的位数重复基数,因此32/2
  • 是一个尼拉度函数,它接受用户输入并对其进行评估。
  • +/使用减少(折叠)其正确的参数+。(我们将0和1相加。)

2
这不会打破Built-in base conversion functions约束吗?
Gareth

哎呀!错过了那一个。
Dillon Cower

加!以为我通过J程序给了自己一次战斗的机会!:-) 不错的工作。
Gareth

@Gareth:直到现在阅读您的解释,我才意识到,但是我的答案与您的答案几乎相同!我猜这可能是APL和J.所期望的:)
Dillon Cower

11

脑袋 2

,.

在我看来(“您的语言能够处理的最高数字”)(以及大多数答案使用的是最合理的解释)是“您的语言本机支持的最大数字”。Brainbool是一个头脑混乱的派生类,它使用位而不是字节,并以二进制(01字符)而不是字符代码的形式进行输入和输出。因此1,最大的本机支持数字是,而最小的是0,分别具有1和的汉明权重0

根据Esolang的说法,Brainbool成立于2010年。


9
我知道它一定存在,但是我花了一个小时的时间在Esolang上对Brainfuck衍生物进行分类,才能找到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读)中读取,我将很乐意对此表示赞同。
史蒂芬·鲁姆巴尔斯基

我认为最好的办法(也许是根据弄清楚的方式)是将输入移到程序的末尾。问题中没有提到标准输入吗?
Gareth

很抱歉没有指定输入方式。现在更改规则将是不公平的,因此我会接受这一规则。我下次再提!
pimvdb

@pimvdb没问题,这不是投诉。我认为尽管使用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

注意:我的其他答案使用lambda和递归,而这个答案使用while循环。我认为它们足够不同,因此有两个答案。


6

Ruby,38个字符

f=->u{u<1?0:u%2+f[u/2]}
p f[gets.to_i]

使用ruby的另一种解决方案以及与Steven相同的递归方法。


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

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,但是我们在乎吗?;)
user606723 2011年

@ user606723我只是去尝试了,似乎完全适用于所有情况下的工作,至少到1000
PhiNotPi

3

Perl,30个字符

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

基于PhiNotPi的解决方案,并进行了一些额外的打高尔夫球。运行perl -M5.010以启用Perl 5.10 say功能。


请问$=特变做你的程序有什么特别,或者是它只是一个普通的变量?
PhiNotPi 2011年

2
@PhiNotPi:$=仅采用整数值,因此使用它可以为我节省一个int
Ilmari Karonen 2011年

命令行arg是否不应该作为字符计数的一部分?
苏厄姆·乔杜里

@SohamChowdhury:不是每个meta线程
Ilmari Karonen

3

普通Lisp,12个字符

(假设1个char变量名称-即: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)2011年

抱歉,AND运算符也算作按位运算符。
pimvdb 2011年

@ M.Joanis:嗯,感谢您的关注。固定。
sam hocevar,2011年

1
我认为,如果您改用K&R C,可以保留几个字符。 如果您同意的话。
JB

通过将printf移出循环,可以将其缩短四个字符。
marinus 2012年

3

dc – 26个字符

这相当长,主要是由于中缺少循环构造dc

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

继续将数字的模2相加,然后将数字除以直至其达到零。可以处理任意长整数。

例:

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

3

C,66个字符

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

注意:需要gcc或gcc兼容的编译器(例如ICC,clang)。

对于某些CPU,它们会__builtin_popcount编译为一条指令(例如,POPCNT在x86上)。


__builtin_popcount实际上只实现1s本身的计数是否正确?如果是这样,尽管按照规则并没有严格错误,但老实说,我认为这不是一个公平的条目。
pimvdb 2012年

如果您要禁止使用给定语言或编译器的内置功能的条目,则可能在问题中作了规定。
Paul R

这不是合法的C ++,因为在C ++中,您不能在main上省略返回类型,也printf不能在没有事先包含的情况下使用。
celtschk 2012年

@celtschk:公平点-编辑了C++
Paul R

2

JavaScript,78 72 71个字符

我还将发布最初的解决方案,然后再提出问题。虽然已经有了一个更好的JavaScript答案:)

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/

这个想法来自某些“心灵阅读卡”,通过向他们显示卡片并让他们说出他们的号码在哪些卡片上是显而易见的,从而使您能够获得他人记住的数字。

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

Haskell (60 chars)

f n=sum[1|x<-[0..n],odd$n`div`2^x]
main=interact$show.f.read

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

Scala, 86 characters

object O extends App{def f(i:Int):Int=if(i>0)i%2+f(i/2)else 0
print(f(args(0).toInt))}

Usage: scala O 56432


1

D (70 chars)

int f(string i){int k=to!int(i),r;while(k){if(k%2)r++;k/=2;}return r;}

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

OCaml, 52 characters

let rec o x=if x=0 then 0 else (x mod 2) + (o (x/2))

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

TI-Basic (TI-84 Plus CE), 30 bytes

Prompt X
0→S
While X
S+remainder(2,X→S
int(X/2→X
End
S

TI-Basic is a tokenized language, all tokens but remainder( are one-byte, remainder is two


Welcome to the site!
James

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.