Düşük çekiçleme ağırlığı ile çekiçleme ağırlığını hesaplama


19

Bir ipin çekiç ağırlığını hesaplayan bir program oluşturun . Kazanan, en düşük çekiçleme ağırlığına sahip programdır.

Kurallar:

  • Bir ASCII karakteri için çekiçleme ağırlığı 1, ikili gösteriminde ayarlanan toplam bit sayısı olarak tanımlanır .
  • Giriş kodlamasının, diliniz için normal olan herhangi bir giriş mekanizmasından (ör. Stdin, args, vb.) Geçirilen 7 bitlik ASCII olduğunu varsayın.
  • Sonucu sayı olarak stdout'a veya dilinizin kullandığı varsayılan / normal çıktı mekanizmasına gönderin.
  • Söylemeden geçmeli, ancak programı gerçek hayatta, geçerli bir çözüm olabilmesi için çalıştırabilmelisiniz .
  • Kazanan, kodu en düşük çekiçleme ağırlığına sahip olan çözümdür.
  • Üzgünüz, bunun için boşlukta çözüm yok ! Tamam, boşlukları kodlayabilirsiniz, şimdi kuralları çözdüm :)

Karakter başına örnekler:

char |  binary  | weight
-----+----------+-------
a    | 01100001 | 3
x    | 01111000 | 4
?    | 00111111 | 6
\x00 | 00000000 | 0
\x7F | 01111111 | 7

0x20/ ASCII 32'yi referans olarak alırsak , uğultu ağırlığı hello world11 yerine 10 değil mi?
Cristian Lupascu

Ağırlık hello world11 neden? Sadece 10 karakter boşluktan farklıdır. Ayrıca - bir programın Hamming ağırlığı boşluklar hariç sadece uzunluğu gibi görünüyor. Normal kod golf çok farklı değil.
ugoren

Üzgünüm, bunu tamamen berbat ettim. Wikipedia'nın çekiç ağırlık makalesi oldukça yanıltıcıdır ve kuralları tamamen aşıladım. Şimdi yeniden yazıyorum. Güncelleme: Tamam, ASCII dizesinde 1 olarak ayarlanan bit sayısı olarak tanımlamak için yeniden yazılmıştır, vidalama için özür dileriz.
Polinom

@ugoren Daha düşük değerli ASCII karakterleri olan bir çözümün daha düşük çekiçleme ağırlığı vardır.
Polinom

1
Şimdi her şey mantıklı. BÜYÜK HARF, DİKKAT EDİN ~VE o.
ugoren

Yanıtlar:


6

J (33)

Biri 34'den daha düşük!

+/,#:3 u:

Ağır ilham tarafından bu cevap , ama birinin bir hamming ağırlığı düşürmek.

   +/,#:3 u:'+/,#:3 u:'
33

8

J, ağırlık 34

+/,#:a.i.

Kullanım - ölçülecek dizeyi tırnak işaretleri içine yerleştirin:

   +/,#:a.i.'+/,#:a.i.'
34

Alternatif olarak, klavyeden giriş almak (ağırlık 54):

   +/,#:a.i.1!:1[1
hello
21

Bunu yazmanın tek bir yolu var :)
ephemient

Değil ... Bir alt çekiçleme ağırlığına sahip bir çözüm buldum.
Junıʇǝɥʇuʎs

Bir vızıltı olmaya çalışmayın, ancak kurallar bir parça değil , bir program ister .
FUZxxl

5

J , 39

+/,#:a.i:]

Bu bir argüman alan bir işlevdir. (Veya ]doğrudan dize ile değiştirin ; Gareth'in belirttiği gibi, maliyeti 34'e düşürür.)

   + /, #: ai:] 'merhaba dünya'
45
   + /, #: ai:] '+ /, #: ai:]'
39

Büyük beyinler benzer düşünür. :-)
Gareth

5

Python, 189

print sum(bin(ord(A)).count("1")for A in raw_input())

2
Python 3 eşdeğeri print(sum(bin(ord(A)).count('1')for A in input()))180 puan alır.
dan04

4
@ dan04: 176 için tek yerine çift tırnak kullanın.
Keith Randall

5

QBasic, 322 311 286 264

H$=COMMAND$
FOR A=1 TO LEN(H$)
B=ASC(MID$(H$,A,1))
WHILE B>0
D=D+B MOD 2
B=B\2
WEND
NEXT
?D

İş için doğru araç, tabii ki hala berbat.


1
Tüm zamanların en sevdiğim dillerden birini kullanmak için +1. Bilgisayarda kod yazmayı öğrendiğim ilk dil.
Polinom

5

Tekli 0

Hepiniz bunun geleceğini biliyordunuz. Önce BrainFuck programı:

,[[>++[>>+>+<<<-]>>>
[<<<+>>>-]>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>
[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-]
[-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>>
[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<
[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<<<
[>>+<[>>+>+<<<-]>>>[<<<+>>>-]>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>
[<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]> 
[-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<<
[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<<<]>>>
[>+>+<<-]>>[<<+>>-][-]+<[>[-]<<[<<->>-]<<[>>+<<-]>>>[-]]>[<<<+<[-]>>>>
[-]]<<[->>>>+<<<<]<[-<<+>>]<<],]>>>>>>>.

"Okunabilir" hale getirmek için yeni satırlar ekledim ama 4066 Hamming ağırlığına sahip. Bir giriş dizesinin bölüm / kalanlarını art arda alıp tüm kalanları toplayarak çalışır. Tabii ki kendi başına çalıştırırsanız şunları elde edersiniz: 226 (4066% 256) (teknik olarak \ xe2) açıkça kazananı yönetir.

Şimdi onu Unary'e dönüştürüyoruz ve

000 ... 9*google^5.9 0's ... 000

'0' ve bom için 0 NULL karakter \ x00 için NULL karakterli tekli bir uygulama kullanıyoruz.

Bonus soru : Hangi ASCII karakterleri ciçin bu programı Ntekrarlardan oluşan bir dize üzerinde çalıştırabilir ve o karakteri çıkartabilirsiniz. (EG 32 boşluklu bir dizi bir boşluk verir). Hangi Niş değerleri (sonsuz sayıda çalışır veya hiçbiri işe yaramaz).


1
Bu çözümü anladığımdan emin değilim. Brainfuck programı büyük bir çekiç ağırlığına sahiptir. Unary, boş baytları bir program olarak kabul ediyor mu, yoksa Unary'yi yeniden mi uygulamanız gerekir? Eğer ikinciyse, bu gerçekten geçerli bir çözüm değildir - herkes sadece "Herhangi bir giriş baytının {sonuç} verdiği bir programlama dili tanımlayabilirim" diyebilir ve sitedeki her kod golf mücadelesini kazanabilir.
Polinom

1
Boş karakter Unary iyi olur. İhtiyacınız olan tek şey saymayı bırak demek için bir EOF. Aslında bu dosyayı okumak için bazı sözde-C: main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; }Unary karakteriniz olarak ne seçtiğiniz önemli değil (EOF olmadığı sürece).
Walpen

1
İşte boş karakterlerle iyi çalışan bir C derleyicisinin tek adı: ideone.com/MIvAg . Tabii ki bu programı yapmak için gereken dosya evrene uymayacaktı, ama onu çalıştırabilecek kapasiteye sahibiz.
12'de

3
Eğer yapamıyorsanız aslında çalıştırmak, gerçekten çözüm değil.
Polinom

4
As Carl Sagan bir zamanlar söyledi: "Eğer bir dize hamming ağırlığını hesaplamak isterseniz, önce 10 ^ 500 evrenlere icat gerekir." (milyarlar ve milyarlar bile)
12'de

4

Cı, ağırlık 322 263 256

Çekiç ağırlığının vurma ağırlığı sayılır mı?

main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))D+=*A%2;printf("%d",D-2);}

Çoğunlukla standart golf teknikleri kullanılır.
Tek bir döngü ağırlığı hesaplar (sağa kaydırma ve sıfıra kadar ekleme) ve dizeyi tarar (sıfıra ulaşıldığında işaretçiyi ilerletir).
Varsayım D2'ye (tek parametre) başlatılır.

Hamming ağırlık spesifik optimizasyonlar:
1. ABDH, her biri 2 ağırlık ile isimler için kullanılır.
2. *++Htercih edilir H[1].


Hah, şimdiye kadar ilk cümlenizi anlayamadım.
ekmek kutusu

Sonucu bir tekli sayı olarak çıkararak skoru 230'a kadar düşürebilirsiniz :main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
schnaader

@schnaader, @tekli sistemde bir rakam olduğunu hiç bilmiyordum . Ben sadece kullandığı düşündü 0.. 0. Ama buna gitmek istiyorsan, yol printf("@"+*a%2)daha kısadır.
ugoren

@ugoren: Unary kuralına / tanımına bağlıdır. Örneğin, en.wikipedia.org/wiki/Unary_numeral_system taksitli notları kullanır ve "Diğer geleneksel üslerde olduğu gibi tek başlı sıfırı temsil eden açık bir sembol yoktur" der.
schnaader

@schnaader, tamam, ama bence "sayı olarak" gereksinimi çok fazla artırıyor.
ugoren

4

Golf senaryosu 84 72 58

{2base~}%{+}*

(yardımları için Howard ve Peter Taylor'a teşekkürler)

Giriş: giriş dizesi yığının üzerinde olmalıdır (komut satırı bağımsız değişkeni olarak iletilir veya yalnızca yığına yerleştirilir).

Komut satırından çalıştırmanız durumunda, kullandığınızdan emin olun echo -n, aksi takdirde sondaki yeni satır da sayılacaktır.

Çıktı: çekiçleme ağırlık değerini konsola yazdırır

Program burada test edilebilir .


1
Golfscript büyük / küçük harfe duyarlı mı? Değilse, BASEyerine kullanarak birkaç bit kaydedebilirsiniz base. Güncelleme: Sadece kontrol edildi, BASEçalışmıyor. İyi çözüm :)
Polinom

@Polynomial TEST/ testcomment gördükten sonra denedim :) Ama işe yaramıyor.
Cristian Lupascu

İlk etapta {...}2*başvurarak kurtulabilirsiniz 2base~. Puan 72'ye düştü.
Howard

@Bu harika ipucu için teşekkürler! Cevabımda uyguladım.
Cristian Lupascu

Web GolfScript sayfanızın önemli bir sınırlamasını unuttuğunuz için test mekanizmanız yanlış. ;Stdin yerine koyduğunuz dizeden önce bir tane olmalıdır , bu yüzden bu (;gereksizdir. Sonra Howard'ın gözlemi onu 65'e indirir.
Peter Taylor

2

Perl, 80 (22 karakter)

Tamamlandı ve yapıldı:

perl -0777nE 'say unpack"%32B*"'

Veya 77 (21 karakter) ağırlığa sahip alternatif bir sürüm:

perl -0777pE '$_=unpack"%32B*"'

Bu sürümü çok sevmiyorum, çünkü çıktısı son satırsonu atlıyor.

Ağırlığı hesaplamak için, karakterleri normal şekilde saydığımı varsayıyorum ( perl -e/ hariç -E, ancak diğer seçenek karakterleri dahil). Bazı nedenlerden dolayı insanlar bu konuda şikayetçi ise, o zaman seçenekler olmadan yapabileceğim en iyisi 90 (26 karakter):

$/=$,,say unpack"%32B*",<>

Örnek kullanım:

$ perl -0777nE 'say unpack"%32b*"' rickroll.txt
7071

Boom.


2

Pyth - 15

Feragatname: Pyth bu mücadeleden daha genç olduğu için bu cevap kazanmaya uygun değildir.

.Bİkili gösterim için kullanır ve sayısını sayar "1".

/.BQ\1

Kaydedilmek üzere bir dizede girişi Alır zkarşı Q.

Burada çevrimiçi deneyin .


1

Scala 231

readLine().map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum

Otomatik test kodu:

"""readLine().map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum""".map(_.toInt.toBinaryString).flatten.map(_.toInt-48)sum

otomatik test modifikasyonu ile.


Ağırlık 495, 231 değil. 126 karakter ile ağırlık 231 elde edemezsiniz - bu ortalama 2'den azdır ve tüm yazdırılabilir karakterlerin ( @kullanmadığınız boşluk hariç ) en az 2 ağırlığı vardır.
ugoren

1
@ugoren: Ama sadece 65 karakter. Program neredeyse iki kez yazdırılır: Çekme ağırlığını hesaplamak için kod ve program için hesaplamak için ikinci kez statik giriş olarak. Ancak hesaplama parçasının önünde "readLine ()" eksiktir, çünkü değişmez girdiyi alır. Cevabın kendisini açıklığa kavuşturmaya çalıştım.
kullanıcı bilinmiyor

1

Java, kilo 931 774 499 454

Şu anda 300'den fazla ağırlığı olan tek cevap bu.

class H{public static void main(String[]A){System.out.print(new java.math.BigInteger(A[0].getBytes()).bitCount());}}

Komut satırı bağımsız değişkeni olarak girdi bekliyor.


1

GNU sed -r, 467 + 1

(Kullanım için +1 -r- veya +4 olmalı mı?)

Kaynak hattı başına tek değer olarak çıktılar; ondalık toplama dönüştürmek, çıktıyı yönlendirmek | tr -d "\n" | wc -c. Yazdırılabilir tüm ASCII karakterlerini (32-126) artı satır beslemeyi (10) sayar.

s@[a-z]@\U& @g
s@[?{}~]@      @g
s@[][/7;=>OW|^]@     @g
s@[-'+.3569:<GKMNSUVYZ\\]@    @g
s@[#%&)*,CEFIJL1248ORTX]@   @g
s@$|[!"$(ABDH0P`]@  @g
y! @!11!

Tüm karakterleri listelemekten kaçınmak zordur, ancak küçük harflerin Hamming ağırlığına karşılık gelen büyük harflerden daha fazla olduğunu gözlemleyerek azaltabiliriz. Bir deyim ayırıcısı olarak noktalı virgül (skor 5) yerine satırsonu (skor 2); örüntü sınırlayıcı olarak @(skor 1) veya !(skor 2) 'yi /(skor 5) tercih ediyoruz .

Not - doğru karakter kümelerini elde etmek için, bu tabloyu man asciiağırlıkça sıralanmış bir tablodan oluşturdum . Her karakterin toplam ağırlığını elde etmek için puanları sağa ve aşağıya eklemeniz yeterlidir:

   2 4   3 5 6   7 
   ---  ------   - 
0:   @   0 P `   p |0

1: ! A   1 Q a   q | 
2: " B   2 R b   r |1
4: $ D   4 T d   t | 
8: ( H   8 X h   x | 

3: # C   3 S c   s | 
5: % E   5 U e   u | 
6: & F   6 V f   v |2
9: ) I   9 Y i   y | 
A: * J   : Z j   z | 
C: , L   < \ l   | | 

7: ´ G   7 W g   w | 
B: + K   ; [ k   { |3
D: - M   = ] m   } | 
E: . N   > ^ n   ~ | 

F: / O   ? _ o     |4
   ---  ------   -  
    1      2     3

Bu başkalarına faydalı olabilir.


0

Julia 262 268

Değiştirilmiş sürüm 6 tasarruf için kullanışlı 'count_ones' fonksiyonunu kullanır (262)

show(mapreduce(x->count_ones(x),+,map(x->int(x),collect(ARGS[1]))))

Dahili tek sayma işlevini kullanmayan eski sürüm (268)

show(mapreduce(x->int(x)-48,+,mapreduce(x->bits(x),*,collect(ARGS[1]))))

Girdi için komut satırı bağımsız değişkenini kullanır.


0

CJam 52 veya 48

Giriş zaten yığınta değilse (52)

q:i2fbs:s:i:+

Giriş yığın üzerindeyse (48)

:i2fbs:s:i:+

Örneğin

"Hello World":i2fbs:s:i:+

0

Julia, HW 199

H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))

İle

A="H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))"

veya doğrudan dizeyi ekleyerek:

julia> H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect("H=mapreduce;H(B->B=='1',+,H(P->bits(P),*,collect(A[:])))")))
199

Yassı olmayan versiyon (HW 411) şöyle görünür:

bitstring=mapreduce(x->bits(x),*,collect(teststring[:]))
mapreduce(checkbit->checkbit=='1',+,bitstring)

Ve eğlenmek için, fırının problemi üstlenmesinin optimize edilmiş bir versiyonu (Hamming Weight 231 ):

A=mapreduce;show(A(B->int(B)-48,+,A(B->bits(B),*,collect(H[:]))))

ile

H="A=mapreduce;show(A(B->int(B)-48,+,A(B->bits(B),*,collect(H[:]))))"

0

HPPPL (HP Prime Programlama Dili), 74

sum(hamdist(ASC(a),0))

HP Prime grafik hesap makinesinin yerleşik bir hamdist () işlevi vardır. Her karakterin çekiçleme ağırlığı, 0'dan çekiçleme mesafesiyle aynıdır.

ASC (dize), bir dizedeki her karakterin ASCII değerlerinden oluşan bir dizi oluşturur.

hamdist (değer, 0) her ASCII değeri için çekiçleme mesafesini 0'dan hesaplar

sum () tüm değerleri toplar.

Kendi kaynak kodunun çekiç ağırlığının hesaplanması:

Hamming Ağırlığı HPPPL


0

05AB1E , ağırlık 17 (4 bayt )

ÇbSO

Çevrimiçi deneyin veya daha fazla test vakası doğrulayın .

Açıklama:

Ç       # Convert the characters in the (implicit) input to their ASCII decimal values
        #  i.e. "Test" → [84,101,115,116]
 b      # Convert those values to binary
        #  i.e. [84,101,115,116] → ["1010100","1100101","1110011","1110100"]
  S     # Split it into a list of 0s and 1s (implicitly flattens)
        #  i.e. ["1010100","1100101","1110011","1110100"]
        #   → [1,0,1,0,1,0,0,1,1,0,0,1,0,1,1,1,1,0,0,1,1,1,1,1,0,1,0,0]
   O    # Sum those (and output implicitly)
        #  i.e. [1,0,1,0,1,0,0,1,1,0,0,1,0,1,1,1,1,0,0,1,1,1,1,1,0,1,0,0] → 16

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.