Hitung berat hamming dengan berat hamming rendah

19

Buat program yang menghitung berat hamming dari string. Pemenang adalah program dengan bobot hamming terendah.

Aturan:

  • Hamming weight untuk karakter ASCII didefinisikan sebagai jumlah total bit yang diset 1dalam representasi binernya.
  • Asumsikan pengkodean input adalah ASCII 7-bit, melewati mekanisme input apa pun yang normal untuk bahasa Anda (mis. Stdin, args, dll.)
  • Keluarkan hasilnya, sebagai angka, ke stdout atau apa pun mekanisme keluaran default / normal yang digunakan bahasa Anda.
  • Seharusnya tidak perlu dikatakan, tetapi Anda harus dapat benar-benar menjalankan program, dalam kehidupan nyata, agar itu menjadi solusi yang valid.
  • Winner adalah solusi yang kodenya memiliki bobot hamming terendah.
  • Maaf, tidak ada solusi di spasi putih untuk yang satu ini! Ok, Anda bisa kode di whitespace sekarang saya sudah beres aturan :)

Contoh per karakter:

char |  binary  | weight
-----+----------+-------
a    | 01100001 | 3
x    | 01111000 | 4
?    | 00111111 | 6
\x00 | 00000000 | 0
\x7F | 01111111 | 7
Polinomial
sumber
jika kita menggunakan 0x20/ ASCII 32 sebagai rujukan, bukankah berat dengungan hello world10 daripada 11?
Cristian Lupascu
Mengapa beratnya hello world11? Hanya 10 karakter yang berbeda dari satu spasi. Juga - berat program Hamming tampaknya hanya panjangnya, tidak termasuk ruang. Tidak jauh berbeda dengan golf kode normal.
ugoren
Maaf, saya benar-benar mengacaukannya. Artikel berat hamming Wikipedia agak menyesatkan, dan saya benar-benar memahami aturannya. Menulis ulang sekarang. Pembaruan: Oke, tulis ulang untuk mendefinisikannya sebagai jumlah bit yang ditetapkan ke 1 dalam string ASCII, maaf atas kesalahannya.
Polinomial,
@ugoren Solusi dengan karakter ASCII bernilai lebih rendah memiliki bobot hamming yang lebih rendah.
Polinomial,
1
Sekarang semuanya masuk akal. GUNAKAN UPPERCASE, WASPADALAH ~DAN o.
ugoren

Jawaban:

6

J (33)

Satu lebih rendah dari 34!

+/,#:3 u:

Sangat terilhami oleh jawaban ini , tetapi bobot hamming satu lebih rendah.

   +/,#:3 u:'+/,#:3 u:'
33
ɐɔıʇǝɥʇu
sumber
8

J, berat 34

+/,#:a.i.

Penggunaan - tempatkan string yang akan diukur dalam tanda kutip di akhir:

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

Atau, mengambil input dari keyboard (berat 54):

   +/,#:a.i.1!:1[1
hello
21
Gareth
sumber
Hanya ada satu cara untuk menulis ini :)
ephemient
Tidak ada ... Saya menemukan solusi yang memiliki berat hamming yang lebih rendah.
ɐɔıʇǝɥʇuʎs
Bukan mencoba menjadi buzzkill, tetapi aturannya meminta program, bukan fragmen.
FUZxxl
5

J , 39

+/,#:a.i:]

Ini adalah fungsi yang mengambil satu argumen. (Atau ganti ]dengan string secara langsung; seperti yang dicatat Gareth, yang menurunkan biayanya menjadi 34.)

   + /, #: ai:] 'hello world'
45
   + /, #: ai:] '+ /, #: ai:]'
39
singkat
sumber
Pemikir hebat berfikir yang sama. :-)
Gareth
5

Python, 189

print sum(bin(ord(A)).count("1")for A in raw_input())
Keith Randall
sumber
2
Setara dengan Python 3 print(sum(bin(ord(A)).count('1')for A in input())),, memiliki skor 180.
dan04
4
@ dan04: Gunakan tanda kutip ganda alih-alih tunggal untuk 176.
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

Jenis alat yang tepat untuk pekerjaan itu, tentu saja masih menyebalkan.

berhenti mengubah counterclockwis
sumber
1
+1 untuk menggunakan salah satu bahasa favorit saya sepanjang masa. Ini adalah bahasa pertama yang saya pelajari untuk berkode pada PC.
Polinomial,
5

Unary 0

Anda semua tahu itu akan datang. Pertama program BrainFuck:

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

Saya menambahkan baris baru untuk membuatnya "dapat dibaca" tetapi memiliki berat Hamming 4066. Ia bekerja dengan berulang kali mendapatkan hasil bagi / sisa dari string input dan menambahkan semua sisanya. Tentu saja jika Anda menjalankannya sendiri Anda mendapatkan: 226 (4066% 256) (secara teknis \ xe2) jadi jelas itu mengatur dirinya sendiri pemenangnya.

Sekarang kita mengubahnya menjadi Unary dan dapatkan

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

Kami menggunakan implementasi unary dengan karakter NULL \ x00 untuk '0' dan boom, dengan bobot 0.

Pertanyaan bonus : Untuk karakter ASCII apa cAnda dapat menjalankan program ini pada string yang terdiri dari Nreposisi dan mengeluarkannya dari karakter tersebut. (EG string 32 spasi memberi ruang). Nilai-nilai Npekerjaan apa (baik jumlah mereka yang tak terbatas akan berfungsi, atau tidak ada yang mau).

walpen
sumber
1
Saya tidak yakin saya mengerti solusi ini. Program brainfuck memiliki berat hamming yang besar. Apakah Unary menerima byte nol sebagai program, atau Anda perlu mengimplementasikan kembali Unary? Jika yang terakhir, itu bukan solusi yang benar - siapa pun bisa mengatakan "Saya mendefinisikan bahasa pemrograman di mana setiap byte input tunggal memberikan {hasil}", dan memenangkan setiap tantangan golf kode di situs.
Polinomial
1
Karakter nol Unary akan baik-baik saja. Yang Anda butuhkan hanyalah EOF untuk mengatakan berhitung. Sebenarnya inilah beberapa pseudo-C untuk membaca file itu: main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; }Tidak masalah sama sekali apa yang Anda pilih untuk menjadi karakter Unary Anda (asalkan bukan EOF).
walpen
1
Nah ini kompiler unary to C yang berfungsi baik dengan karakter nol: ideone.com/MIvAg . Tentu saja file yang diperlukan untuk membuat program ini tidak muat di alam semesta, tetapi kami memiliki kapasitas untuk menjalankannya.
walpen
3
Jika Anda tidak dapat benar-benar menjalankannya, itu tidak benar-benar solusi.
Polinomial
4
Seperti yang pernah dikatakan Carl Sagan : "Jika Anda ingin menghitung berat palu string, Anda harus terlebih dahulu menciptakan 10 ^ 500 alam semesta." (milyaran dan milyaran, genap)
walpen
4

C, berat 322 263 256

Apakah berat hamming dari hamming weight dihitung?

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

Kebanyakan digunakan teknik golf standar.
Satu loop menghitung berat (menggeser ke kanan dan menambahkan sampai nol) dan memindai string (memajukan pointer ketika nol tercapai).
Dengan asumsi Ddiinisialisasi ke 2 (parameter tunggal).

Optimal berat spesifik Hamming:
1. ABDH, dengan bobot 2 masing-masing, digunakan untuk nama.
2. *++Hlebih disukai daripada H[1].

ugoren
sumber
Hah, aku benar-benar gagal memahami kalimat pertamamu sampai sekarang.
kotak roti
Anda bisa mendapatkan skor hingga 230 dengan mengeluarkan hasilnya sebagai angka unary :main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
schnaader
@ schnaader, saya tidak pernah tahu @angka dalam sistem unary. Saya pikir itu hanya menggunakan 0.. 0. Tetapi jika Anda ingin pergi ini, cara, printf("@"+*a%2)lebih pendek.
ugoren
@ugoren: Tergantung pada konvensi / definisi unary. Misalnya en.wikipedia.org/wiki/Unary_numeral_system tidak menggunakan tanda penghitungan dan mengatakan "Tidak ada simbol eksplisit yang mewakili nol di unary seperti yang ada di pangkalan tradisional lainnya".
schnaader
@ schnaader, OK, tapi saya pikir itu melampaui persyaratan "sebagai angka" terlalu jauh.
ugoren
4

Golfscript 84 72 58

{2base~}%{+}*

(Terima kasih kepada Howard dan Peter Taylor untuk bantuan mereka)

Input: string input harus berada di tumpukan (dilewatkan sebagai argumen baris perintah, atau cukup ditempatkan di tumpukan).

Jika Anda menjalankannya dari baris perintah, pastikan Anda menggunakan echo -n, jika tidak maka baris tambahan juga akan dihitung.

Output: mencetak nilai bobot hamming ke konsol

Program ini dapat diuji di sini .

Cristian Lupascu
sumber
1
Apakah Golfscript case-sensitive? Jika tidak, Anda dapat menyimpan beberapa bit dengan menggunakan BASEalih-alih base. Pembaruan: Baru diperiksa, BASEtidak berfungsi. Solusi yang bagus :)
Polinomial
@ Polinomial Saya mencobanya setelah melihat TEST/ testkomentar Anda :) Tetapi tidak berhasil.
Cristian Lupascu
Anda dapat menyingkirkannya {...}2*dengan mendaftar 2base~terlebih dahulu. Skor turun menjadi 72.
Howard
@Howard, terima kasih atas tip yang luar biasa ini! Saya sudah menerapkannya dalam jawaban saya.
Cristian Lupascu
Mekanisme pengujian Anda salah, karena Anda lupa batasan penting dari halaman Web GolfScript Anda. Anda harus memiliki ;sebelum string yang Anda ganti dengan stdin, jadi itu (;tidak perlu. Lalu pengamatan Howard membuatnya menjadi 65.
Peter Taylor
2

Perl, 80 (22 karakter)

Dilakukan dan dilakukan:

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

Atau inilah versi alternatif dengan berat 77 (21 karakter):

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

Saya tidak terlalu suka versi itu, karena outputnya menghilangkan baris terakhir.

Untuk menghitung bobot, saya mengasumsikan bahwa saya menghitung karakter dengan cara biasa (tidak termasuk perl -e/ -E, tetapi termasuk karakter opsi lainnya). Jika karena alasan tertentu orang mengeluh tentang hal ini, maka yang terbaik yang dapat saya lakukan tanpa opsi adalah 90 (26 karakter):

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

Penggunaan sampel:

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

Ledakan.

kotak roti
sumber
2

Pyth - 15

Penafian: Jawaban ini tidak memenuhi syarat untuk menang karena Pyth lebih muda dari tantangan ini.

Menggunakan .Buntuk representasi biner dan menghitung jumlah "1".

/.BQ\1

Mengambil input dalam string untuk menghemat zversus Q.

Cobalah online di sini .

Maltysen
sumber
1

Scala 231

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

Kode selftesting:

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

dengan modifikasi selftesting.

Pengguna tidak diketahui
sumber
Beratnya 495, bukan 231. Anda tidak bisa mendapatkan berat 231 dengan 126 karakter - itu rata-rata kurang dari 2, dan semua karakter yang dapat dicetak (kecuali @dan ruang, yang tidak Anda gunakan) setidaknya memiliki bobot 2.
ugoren
1
@ugoren: Tapi itu hanya 65 karakter. Program dicetak hampir dua kali: Setelah kode untuk menghitung berat hamming, dan yang kedua sebagai input statis untuk menghitungnya untuk program. Tetapi bagian penghitungan tidak memiliki "readLine ()" di depan, karena ia membutuhkan input literal. Saya mencoba mengklarifikasi jawabannya sendiri.
pengguna tidak diketahui
1

Jawa, berat 931 774 499 454

Saya pikir ini adalah satu-satunya jawaban saat ini dengan berat lebih dari 300.

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

Mengharapkan input sebagai argumen baris perintah.

SuperJedi224
sumber
1

GNU sed -r, 467 +1

(+1 untuk penggunaan -r- atau seharusnya +4?)

Output sebagai nilai unary per baris sumber; untuk mengkonversi ke total desimal, redirect output ke | tr -d "\n" | wc -c. Menghitung semua karakter ASCII yang dapat dicetak (32-126), plus linefeed (10).

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

Sulit untuk menghindari daftar semua karakter, tetapi kita dapat mengurangi ini mengamati bahwa huruf kecil memiliki berat Hamming satu lebih dari huruf besar yang sesuai. Kami lebih suka baris baru (skor 2) daripada titik koma (skor 5) sebagai pemisah pernyataan; kami lebih suka @(skor 1) atau !(skor 2) lebih dari /(skor 5) sebagai pembatas pola.

Catatan - untuk mendapatkan set karakter yang tepat, saya membuat tabel ini dari yang masuk man ascii, diurutkan berdasarkan berat. Cukup tambahkan skor tepat dan di bawah ini untuk mendapatkan bobot keseluruhan dari setiap karakter:

   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

Ini mungkin terbukti bermanfaat bagi orang lain.

Toby Speight
sumber
0

Julia 262 268

Versi modifikasi menggunakan fungsi 'count_ones' yang praktis untuk menghemat 6 (262)

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

Versi lama tanpa fungsi bawaan satu penghitungan (268)

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

Menggunakan argumen baris perintah untuk input.

bakerg
sumber
0

CJam 52 atau 48

Jika input belum ada di stack (52)

q:i2fbs:s:i:+

Jika input ada di tumpukan (48)

:i2fbs:s:i:+

Sebagai contoh

"Hello World":i2fbs:s:i:+
bakerg
sumber
0

Julia, HW 199

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

Dengan

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

atau dengan langsung memasukkan string:

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

Versi ungolfed (HW 411) terlihat seperti ini:

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

Dan untuk bersenang-senang, ini adalah versi yang dioptimalkan (Hamming Weight 231 ) dari bakerg's mengambil masalah:

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

dengan

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

HPPPL (Bahasa Pemrograman Utama HP), 74

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

Kalkulator grafik HP Prime memiliki fungsi hamdist () bawaan. Berat hamming masing-masing karakter sama dengan jarak hamming dari 0.

ASC (string) membuat array nilai ASCII dari setiap karakter dalam sebuah string.

hamdist (value, 0) menghitung jarak hamming dari 0 untuk setiap nilai ASCII

jumlah () jumlah semua nilai.

Menghitung bobot hamming dari kode sumbernya sendiri:

Berat Hamming HPPPL

ML
sumber
0

05AB1E , berat 17 (4 byte )

ÇbSO

Cobalah secara online atau verifikasi beberapa kasus uji lagi .

Penjelasan:

Ç       # 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
Kevin Cruijssen
sumber
0

Perl 6 , 102

+*.ords>>.base(2).comb(~1)

Cobalah online!

Meskipun ini bukan kode golf, solusi terpendek tampaknya juga memiliki bobot hamming terkecil ...

Jo King
sumber