Bitsel işleçleri kullanmadan ikili sayıdaki miktarı yazdırın


14

Açıklama

Bir sayı verildiğinde 1, ikili gösterimdeki miktarını yazdırın .

Giriş

Bir dizi >= 0yüksek numaralı Dil geçmez 10 tabanına işlemek için yapabiliyor.

Çıktı

1İkili gösterimdeki s miktarı .

Kazanma koşulu

En kısa kod kazanır.

İzin verilmeyen

  • Bitsel operatörler. Toplama ve çarpma gibi diğer operatörlere izin verilir.
  • Yerleşik temel dönüştürme işlevleri.

Örnekler

Input:     Ouput:

56432      8


Input:     Output:

45781254   11


Input:     Output:

0          0

İşlevlere izin veriliyor mu? Bir Java çözümü yapmak istiyorum, ancak tam kod yazmak çok sıkıcı ...: /
HyperNeutrino

1
Sanırım bu meydan okuma için Bilge kullanmayacağım ... :)
MildlyMilquetoast

Yanıtlar:


16

APL, 9 12 karakter

+/2|⌊⎕÷2*⍳32

Bu, yorumlayıcının 32 bit tamsayılar kullandığını ve ⎕IO0'a ayarlandığını varsayar (yani, monadinin 1 yerine 0 ile başlar). Dyalog APL'nin 32 bit sürümünü kullandım .

Sağdan sola açıklama:

  • ⍳32ilk 32tamsayıların bir vektörünü üretir (daha önce açıklandığı gibi ⎕IO, 0 olduğu için bu vektör 0 ile başlar).
  • *güç işlevidir. Bu durumda, 2vektörün doğru argümanı olarak verilen her bir elemanının gücünü üretir .
  • ÷bölünmüş işlevdir. Bize (değerlendirilen kullanıcı girişi) vektörün her bir elementinin sağına (ikisinin her bir gücü) bölünmesini sağlar.
  • argümanın her bir öğesini sağına döşer.
  • 2|bize sağındaki her öğenin kalanını bölerek verir 2.
  • /soldaki fonksiyonu kullanarak sağ argümanını azaltır (katlar) +.

Artık tam 9 karakter değil. :(

Eski, kurallara aykırı versiyon:

+/⎕⊤⍨32/2

Sağdan sola açıklama:

  • 32/2: Çoğalt 2, 32kere.
  • ikili işlevi soluna gider, bu durumda (yani, X⊤⍨Yeşdeğerdir Y⊤X).
  • kodlama fonksiyonudur. Solda verilen tabanda tamsayıyı sağa kodlar. İşe gidip gelme operatörü nedeniyle sağ ve sol argümanların değiştirildiğini unutmayın. Baz, gerekli basamak sayısı için tekrarlanır 32/2.
  • kullanıcı girişini kabul eden ve değerlendiren niladik bir işlevdir.
  • +/kullanarak doğru argümanını azaltır (katlar) +. (0'ları ve 1'leri toplarız.)

2
Bu zıtlığı Built-in base conversion functionsbozmuyor mu?
Gareth

Tüh! Bunu özledim.
Dillon Cower

Gah! J programımla kendime savaşma şansı vereceğimi düşündüm! :-) İyi iş.
Gareth

@Gareth: Açıklamanızı şu ana kadar okuyamadım, ama cevabım sizinkiyle hemen hemen aynı! Sanırım bu APL ve J'den beklenebilir. :)
Dillon Cower

11

Brainbool , 2

,.

Benim düşünceme göre en makul yorum (ve cevapların çoğunun ne kullandığı) "dilinizin işleyebileceği en yüksek sayı", "dilinizin doğal olarak desteklediği en büyük sayıdır ". Brainbool, bayt yerine bit kullanan 0ve 1karakter kodları yerine ikili ( ve karakterler) girdi ve çıktı alan beyin fırtınası türevidir . Bu nedenle yerel olarak desteklenen en büyük sayı 1ve en küçük olanı sırasıyla 0Hamming ağırlıklarına 1ve 0sırasıyla.

Esolang'a göre Brainbool 2010 yılında kuruldu.


9
Var olması gerektiğini biliyordum, ama Brainbool'u bulmak Esolang'daki Brainfuck türevleri arasında bir saat ayırmamı aldı.
lirtosiast

8

J, 13 karakter

(+ sayıdaki basamak sayısı)

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

Kullanımı: nprogramdaki test edilecek sayı ile değiştirin .

Örnekler:

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

Muhtemelen bunu yeniden düzenlemenin bir yolu var, böylece sayı başlangıçta veya sonunda yerleştirilebilir, ancak bu benim ilk J girişim ve başım biraz acıyor.

Açıklama (esas olarak gelecekte anlayabilmem için)

i.32 - 1'den 32'ye kadar sayılardan oluşan bir dizi oluşturur

2^ - listeyi iki 1 ila 4294967296 arasındaki güçlere dönüştürür

n% - giriş numarasını listedeki her bir öğeye böler

<. - tüm bölme sonuçlarını bir sonraki tamsayıya yuvarlar

2|- %2çoğu dilde olduğu gibi - çiftse 0, tekse 1 döndürür

+/ - listedeki öğeleri toplar (şimdi yalnızca 1 veya 0'dır)


Stdin'den (ya da eşdeğeri J'nin sahip olduğu her şeyden) okuduktan sonra bunu yükseltmekten mutluluk duyacağım.
Steven Rumbalski

Yapabileceğim en iyi şey (belki, nasıl olduğunu anlamaya bağlı olarak) girdiyi programın sonuna taşımaktır. Yine de standart girdi soruda belirtilmemiş mi?
Gareth

Giriş yolunu belirtmediğim için üzgünüm. Şimdi kuralları değiştirmek haksızlık olur, bu yüzden kabul ediyorum. Bir dahaki sefere bundan bahsedeceğim!
pimvdb

@pimvdb Sorun değil, şikayet değildi. J programları ile düşünüyorum ama yapabileceğiniz tek şey verilen girdi üzerinde çalışan bir fiil tanımlamak olduğunu. Bunu yapmak için bunu nasıl yeniden düzenlediğimden emin değilim. Belki JB ya da diğer J uzmanlarından biri bana bu konuda yardımcı olabilir ...
Gareth

... ve biraz daha okuduktan sonra standart girdi konusunda tamamen yanıldığımı görüyorum.
Gareth

8

Brainfuck, 53 karakter

Bu zorunlu bir Brainfuck çözümü eksikti, bu yüzden bunu yaptım:

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

Hücre 1'den sayı alır ve sonucu hücre 6'ya koyar.

Kayıtlı olmayan ve yorum yapılan sürüm:

[  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 karakter

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

not: Diğer cevabım lambda ve özyineleme kullanıyor ve bu bir while döngüsü kullanıyor. İki cevabı garanti edecek kadar farklı olduklarını düşünüyorum.


6

Ruby, 38 karakter

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

Yakut ve Steven ile aynı özyineli yaklaşımı kullanan başka bir çözüm.


5

GolfScript, 17 16 karakter

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

Düzenleme: yeni sürüm, katlama yerine liste işlemini kullanarak 1 karakteri kaydeder (orijinal sürüm ~{.2%\2/.}do]{+}*, doğrudan sayım sürümü:) ~0\{.2%@+\2/.}do;.


5

C, 45

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

Burada C golf için gerçekten özel bir şey yok: örtük dönüş türü, parametreler için örtük tamsayı türü.



4

Perl, 45 43 36 Karakter

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

45-> 43 için Howard'a ve 43-> 36 için User606723'e teşekkürler.


$n=int($n/2)Hangi 2 karakteri daha kısa kullanabilirsiniz .
Howard

İnt () işlevine ihtiyacımız olduğundan emin miyiz? $n=<>;while($n){$_+=$n%2;$n/=2}print$ N / 2 sonunda 0'a yeterince yaklaşıncaya kadar döngü devam edecek, ama umursuyor muyuz? ;)
user606723

@ user606723 Sadece denedim ve en azından 1000'e kadar her durum için mükemmel çalışıyor gibi görünüyor.
PhiNotPi

3

Perl, 30 karakter

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

Dayanarak PhiNotPi çözümüyle bazı ekstra golf ile. perl -M5.010Perl 5.10 sayözelliğini etkinleştirmek için ile çalıştırın .


$=Özel değişken, programınızda özel bir şey yapıyor mu yoksa sadece sıradan bir değişken mi?
PhiNotPi

2
@PhiNotPi: $=sadece tamsayı değerleri alır, bu yüzden onu kullanmak beni kurtarır int.
Ilmari Karonen

Komut satırı arg. Karakter sayısının bir parçası olmamalı mı?
Soham Chowdhury

@SohamChowdhury: Bu meta konu başına değil .
Ilmari Karonen

3

Ortak Lisp, 12 karakter

(1 karakter değişkeni adı varsayıldığında - ör: 11 + sayı uzunluğu)

Bu bir temel dönüştürme işlevi değildir, bu yüzden çalışması gerekir:

(logcount x)

Örnekler:

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

(GNU CLISP kullanarak.)


Hımm, tam olarak aklıma cevap veremediğim gibi değil :) Bunu kabul edebileceğimi sanmıyorum. Temelde sadece başka bir dava bu .
pimvdb

3

C, 61 60 57 53 karakter

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

İşlev gövdesi yalnızca 38 karakterdir. Düzenleme : bitsel operatör kaldırıldı Düzenleme : printfyorumlarda önerildiği gibi döngüden çıkarın Düzenleme : K&R bildirimine geçin; ayrıca, bu artık C99'a özgü değil


Bitsel görüyorum !!!
Joanis

Üzgünüm ama AND operatörü de bitsel operatör olarak sayılır.
pimvdb

@ M.Joanis: duh, fark ettiğin için teşekkürler. Sabit.
sam hocevar

1
Sana K & R C geçtiyseniz Birkaç karakter yedek düşünüyorum Eğer bununla ediyoruz Tamam sen.
JB

Printf'i döngüden çıkararak bunu dört karakter kısaltabilirsiniz.
marinus

3

dc - 26 karakter

Bu, çoğunlukla ilmek yapılarının eksikliğinden dolayı oldukça uzundur dc.

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

Sayının modulo 2'sini toplar ve sayıyı sıfıra ulaşıncaya kadar böler. Rasgele uzun tamsayılarla başa çıkabilir.

Misal:

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

3

C, 66 karakter

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

Not: gcc veya gcc uyumlu derleyici gerektirir (örn. ICC, clang).

Bazı CPU'lar __builtin_popcountiçin tek bir komutu derler (örneğin POPCNTx86'da).


__builtin_popcountAslında sadece 1kendi sayımını uygulayan doğru mudur ? Eğer öyleyse, kurallara göre kesinlikle yanlış olmasa da, dürüstçe bunun adil bir giriş olduğunu düşünmüyorum.
pimvdb

Belirli bir dilin veya derleyicinin yerleşik özelliklerinden yararlanan girişlere izin vermek istemiyorsanız, muhtemelen bunu soruda belirtmelisiniz.
Paul R

Bu yasal C ++ değildir, çünkü C ++ 'da ana dönüş türünü atlayamazsınız veya printfönceden dahil etmeden kullanamazsınız .
celtschk

@celtschk: fair point - düzenlendiC++
Paul R

2

JavaScript, 78 72 71 karakter

Soruyu göndermeden önce bulduğum ilk çözümümü de göndereceğim. Yine de çok daha iyi bir JavaScript cevabı var :)

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/

Fikir, kartlarını göstererek ve numaralarının hangi kartlarda göründüğünü söylemelerine izin vererek, başka birinin aklındaki numarayı elde etmenizi sağlayan belirli "zihin okuma kartlarından" gelir.

Çalışır, çünkü her sayı ikili olarak 1s / 0s'nin benzersiz bir kombinasyonudur . Benim çözümüm, kaç tane kart olduğunu belirlemek için sayının hangi "kartlar" üzerinde göründüğünü kontrol eder 1. Yine de çok verimli değil ...

Zihin okuma tekniğini özetleyen bu belgeyi buldum .


2

Haskell (60 karakter)

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;

Bu $n, test edilecek değeri tutan varsayımdır .

PHP, 55 (alternatif çözüm)

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

Yine, bu $ntest edilecek değeri tutan varsayımdır . Bu bir alternatiftir çünkü floorgirdiye or-operatörünü kullanır .

Her iki çözüm de işe yarar ve bildirimlere neden olmaz.


2

Ocaml, 45 karakter

@Leah Xue'nin çözümüne dayanıyor. Üç boşluk kaldırılabilir ve if-then-else yerine işlevi kullanmak biraz daha kısadır (~ 3 karakter).

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


1

Scala, 86 karakter

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

Kullanımı: scala O 56432


1

D (70 karakter)

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

1

R, 53 karakter

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

Örnekler:

> 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

Numarayı girmek karakter sayısının bir parçası değilse, 43 karakterdir:

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

test senaryoları ile

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

1

OCaml, 52 karakter

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

1

düzen

Meydan okumaya eklemek için kuralları biraz cilaladım. İşlev, sayının tabanını umursamaz çünkü kendi ikili ölçeğini kullanır. Analogdan sayısal dönüşüme kadar ilham aldım. Ben sadece bunun için düz özyineleme kullanın:

(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

Bir sayıyı ikiliye okumak ya da ikiliden bir "yerleşik temel dönüştürme işlevi" yazdırmak, böylece yukarıdaki printbir tamsayıyı geçersiz kılmak değil mi? Yukarıdaki yanıtların hemen hemen hepsi gibi bir tamsayıyı okumaya ve yazdırmaya izin verirseniz, yerleşik bir popcountişlev kullanarak talepte bulunacağım :

Haskell, 50

Bir yoktu popCounteklenen rutin Data.BitsGHC v7.2.1 / v7.4.1 bu yaz için modülün (biletler konusunda bkz primop ve bağlayıcı ).

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

GMP de bir popcount işlevi sunmasına rağmen, GMP için kendi GMPYveya GMP::Mpzmodüllerini kullanarak yukarıdaki Python ve Perl puanlarını ne yazık ki yenemiyorum .


1

JavaScript, 49 47 45 42 bayt

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

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

Düzenleme 1: Çıkarın qve ~~yuvarlamak için kullanın , 2 karakter kaydedin.

Düzenleme 2: kullanım |0operatörü yuvarlama yerine ~~parantezler (2 karakter) kaydedin.

Düzenleme 3: basitleştirmek n>0için nve birleşerek n=n/2|0tüm koşulu yapmak; şimdi ifade alanı boşa harcadı :(


3
Is not |0arasında ikilik santral?
Vilx-

Teknik olarak evet. Ama bunu sadece en yakın int'e yuvarlamak için kullanıyorum, bu yüzden biraz akıllıca bir fayda elde etmiyorum :)
mellamokb

Kuralları bana bükmek gibi kokuyor ... ama ben hakim değilim.
Vilx-

Giriş 1 çıkış 0 verir.
Atreys

1
|bitsel işleç ... izin verilmiyor. Math.round
Jamie

1

Java 7, 36 bayt

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

Elbette bu, her şeyden ötürü, Java'nın yerleşik olduğu bir şeydir ...


Bu, yasaklanan "yerleşik temel dönüştürme işlevleri" kapsamına girmiyor mu?
FlipTack

@ Flp.Tkc Aslında temel dönüşüm yapmıyorum. bitCountKaputun altında nasıl çalıştığı hakkında hiçbir fikrim yok .
Poke

Bu sadece işi yapmak için bir bulitin kullanıyor gibi görünüyor, ama tamam ...
FlipTack

@ Flp.Tkc Bu ... tam olarak nedir? Gerekli tüm kütüphaneleri bile dahil ediyorum (hiç yok). Bu dilin gücünü gösteriyor! ilgili meta
Poke

1

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

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

TI-Basic dizgecikli dil olarak, tüm belirteçleri ama remainder(olan bir baytlık , geri kalan iki


Siteye Hoşgeldiniz!
James

1

PHP, 36 bayt

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

Varsayım $n, test edilecek sayıdır, bir PHP Bildirimi gösterir $ove $n0 olduğunda tam olarak çalışmaz (hiçbir şey çıktılamaz).

PHP, 53 bayt

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

Komut satırı girişini kabul eder, bir PHP Bildirimi göstermez ve 0 için doğru çıktı verir.


Siteye Hoşgeldiniz! :)
James
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.