Lag et program som beregner hammingvekt av en streng. Vinneren er programmet med den laveste hammingvekten.

Regler:

  • Hammingvekt for et ASCII-tegn er definert som det totale antall bits satt til 1 i sin binære representasjon.
  • Anta at inngangskoding er 7-biters ASCII, ført gjennom hvilken som helst inngangsmekanisme som er normal for språket ditt (f.eks. Stdin, args osv.) >
  • Send resultatet, som et tall, til stdout eller hvilken som helst standard / normal utgangsmekanisme språket ditt bruker.
  • Det burde si seg selv, men du må være i stand til å faktisk kjøre programmet, i det virkelige liv, for at det skal være en gyldig løsning.
  • Vinneren er løsningen hvis kode har den laveste hammingvekten.
  • Beklager, ingen løsninger i whitespace for denne! Ok, du kan kode i whitespace nå har jeg ordnet opp i reglene 🙂

Eksempler per tegn:

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

Kommentarer

  • hvis vi tar 0x20 / ASCII 32 som referanse, er ikke ‘ t brumvekten til hello world 10 i stedet for 11?
  • Hvorfor er vekten av hello world 11? Bare 10 tegn er forskjellige fra et mellomrom. Også – et program ‘ s Hamming-vekt ser ut til å være akkurat lengden, unntatt mellomrom. Ikke så forskjellig fra vanlig kodegolf.
  • Beklager, jeg slo helt sammen dette. Wikipedia ‘ s hamming weight artikkel er ganske misvisende, og jeg fubar fullstendig ‘ redigerte reglene. Skriver om nå. Oppdatering: Ok, omskrevet for å definere det som antall bits satt til 1 i ASCII-strengen, beklager skruen.
  • @ugoren En løsning med lavere -verdi ASCII-tegn har lavere hammingvekt.
  • Nå er alt fornuftig. BRUK HOVEDUPPERASJON, PAS PÅ ~ OG o.

Svar

J (33)

En lavere enn 34!

+/,#:3 u: 

Tungt inspirert av dette svaret , men en tyngdevekt på en lavere.

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

Svar

J, vekt 34

+/,#:a.i. 

Bruk – plasser streng som skal måles med anførselstegn på slutten:

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

Alternativt kan du ta input fra tastaturet (vekt 54):

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

Kommentarer

  • ‘ er bare en måte å skrive dette på:)
  • Det er ikke ‘ t … Jeg fant en løsning som har en hammingvekt på en lavere.
  • Ikke prøver å være en buzzkill, men reglene ber om et program, ikke et fragment.

Svar

J , 39

+/,#:a.i:] 

Dette er en funksjon som tar en argument. (Eller erstatt ] med strengen direkte. Som Gareth bemerker, det koster ned til 34.)

 +/,#:a.i:] "hello world" 45 +/,#:a.i:] "+/,#:a.i:]" 39 

Kommentarer

  • Store sinn tenker likt. 🙂

Svar

Python, 189

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

Kommentarer

  • Python 3-ekvivalenten, print(sum(bin(ord(A)).count('1')for A in input())), har poengsummen 180.
  • @ dan04: Bruk dobbelt anførselstegn i stedet for enkelt for 176.

Svar

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 

Type det rette verktøyet for jobben, fremdeles suger selvfølgelig.

Kommentarer

  • +1 for å bruke et av mine favoritt språk gjennom tidene. Det er ‘ det første språket jeg lærte å kode inn på en PC.

Svar

Unary 0

Dere visste alle at det kom. Først BrainFuck-programmet:

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

Jeg la til nye linjer for å gjøre det «lesbart», men det har en Hamming-vekt på 4066. Det fungerer ved å gjentatte ganger få kvotienten / restene av en inngangsstreng og legge sammen alle resten. Selvfølgelig hvis du kjører den på seg selv får du: 226 (4066% 256) (teknisk \ xe2) så klart at den regjerer seg selv som vinner.

Nå konverterer vi den til Unary og får

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

Vi bruker en unary implementering med NULL-tegn \ x00 for «0» og bom, hamming vekt på 0.

Bonusspørsmål : For hvilke ASCII-tegn c kan du kjøre dette programmet på en streng som består av N repisjoner og få den til å sende det tegnet. (E.G. en streng på 32 mellomrom gir et mellomrom).Hvilke verdier av N fungerer (enten et uendelig antall av dem vil fungere, eller ingen vil).

Kommentarer

  • Jeg ‘ er ikke sikker på at jeg forstår denne løsningen. The brainfuck-programmet har en enorm hamming-vekt. Godtar Unary nullbyte som et program, eller må du implementere Unary på nytt? Hvis det ‘ er sistnevnte, er det ‘ egentlig ikke en gyldig løsning – noen kan bare si » Jeg definerer et programmeringsspråk der en enkelt inngangsbyte gir {resultat} «, og vinner hver kode golfutfordring på nettstedet.
  • En null karakter Unary ville være bra. Alt du trenger er en EOF for å si stopp. Faktisk her er ‘ noe pseudo-C for å lese den filen: main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; } Stemmer ikke ‘ t betyr i det hele tatt hva du velger å være din Unary-røye (så lenge den ikke er ‘ t EOF).
  • Vel her ‘ er uenig for C-kompilatoren som fungerer bra med null tegn: ideone.com/MIvAg . Selvfølgelig vil filen som kreves for å lage dette programmet ikke passe i universet, men vi har kapasitet til å kjøre det.
  • Hvis du kan ‘ t faktisk kjør det, det ‘ er egentlig ikke en løsning.
  • Som Carl Sagan sa en gang: » Hvis du ønsker å beregne hammingvekten til en streng, må du først finne opp 10 ^ 500 universer. » (milliarder og milliarder, til og med)

Svar

C, vekt 322 263 256

Teller hammingvekten til hammingvekten?

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

Brukt for det meste standard golf teknikker.
En enkelt sløyfe beregner vekt (skifter til høyre og legger til null) og skanner strengen (avanserer pekeren når null er nådd).
Forutsatt at D er initialisert til 2 (enkeltparameter).

Hamming vekt spesifikk optimizati ons:
1. ABDH, med vekt 2 hver, brukt til navn.
2. *++H foretrukket fremfor H[1].

Kommentarer

  • Hah, jeg klarte ikke å forstå den første setningen din før akkurat nå.
  • Du kan få poengsummen ned til 230 ved å angi resultatet som et unary nummer: main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
  • @schnaader , Jeg visste aldri at @ var et siffer i det unary systemet. Jeg trodde det bare bruker 0 .. 0. Men hvis du vil gå dette, er printf("@"+*a%2) kortere.
  • @ugoren: Avhenger av konvensjonen / definisjonen av unary. F.eks. no.wikipedia.org/wiki/Unary_numeral_system bruker stemmemarkeringer og sier » Det er ikke noe eksplisitt symbol som representerer null i unary som det er i andre tradisjonelle baser «.
  • @schnaader, OK, men jeg tror det ‘ s strekker kravet » som et tall » for langt.

Svar

Golfscript 84 72 58

{2base~}%{+}* 

(takk til Howard og Peter Taylor for deres hjelp)

Input: inputstrengen må være på bunken (sendes som kommandolinje argument, eller rett og slett plassert på bunken).

Hvis du kjører det fra kommandolinjen, må du sørge for at du bruker echo -n, ellers vil også den etterfølgende linjen også telles.

Output: skriver ut verdien for hammingvekt til konsollen

Programmet kan testes

her .

Kommentarer

  • Er Golfscript store og små bokstaver? Hvis ikke, kan du lagre noen bit ved å bruke BASE i stedet for base. Oppdatering: Bare avmerket, BASE fungerer ikke ‘. God løsning 🙂
  • @ Polynomial Jeg prøvde det etter å ha sett TEST / test kommentaren 🙂 Men det gjør det ikke ‘ t fungerer.
  • Du kan kvitte deg med {...}2* ved å bruke 2base~ i utgangspunktet. Får poengsummen ned til 72.
  • @Howard takk for dette gode tipset! Jeg ‘ har brukt den i svaret mitt.
  • Testmekanismen din er feil, fordi du ‘ har glemt en viktig begrensning på Web GolfScript-siden din. Du bør ha en ; foran strengen du erstatter stdin, slik at (; er unødvendig. Så får Howards ‘ observasjon det ned til 65.

Svar

Perl, 80 (22 tegn)

Ferdig og ferdig:

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

Eller her er en alternativ versjon med vekt 77 (21 tegn):

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

Jeg liker ikke den versjonen like mye, skjønt fordi utdataene utelater den endelige nye linjen.

For å beregne vekten, antar jeg at jeg teller tegn på vanlig måte (unntatt perl -e / -E, men inkludert andre valgtegn). Hvis folk av en eller annen grunn klager over dette, så er det beste jeg kan gjøre uten alternativer 90 (26 tegn):

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

Eksempelbruk:

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

Boom.

Svar

Pyth – 15

Ansvarsfraskrivelse: Dette svaret er ikke kvalifisert for å vinne siden Pyth er yngre enn denne utfordringen.

Bruker .B for binær representasjon og teller antall "1" «s.

/.BQ\1 

Tar inndata i en streng for å lagre på z versus Q.

Prøv det online her .

Svar

Scala 231

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

Selftesting code:

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

med modifisering av selftesting.

Kommentarer

  • Det ‘ vekt 495, ikke 231. Du kan ‘ t får vekt 231 med 126 tegn – at ‘ er et gjennomsnitt på mindre enn 2, og alle tegn som kan skrives ut (unntatt @ og mellomrom, som du ikke ‘ t bruk) har vekt 2 i det minste.
  • @ugoren: Men det ‘ er bare 65 tegn. Programmet skrives ut nesten to ganger: En gang koden for å beregne hammingvekten, og en gang til som statisk inngang for å beregne den for programmet. Men den kalkulerende delen mangler » readLine () » foran, fordi det tar bokstavelig inngang. Jeg prøvde å avklare selve svaret.

Svar

Java, vekt 931 774 499 454

Jeg tror dette er det eneste svaret for øyeblikket med en vekt over 300.

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

Forventer inndata som kommandolinjeargument.

Svar

GNU sed -r, 467 + 1

(+1 for bruk av -r – eller skal det være +4?)

Skriver ut som en enhetlig verdi per kildelinje; for å konvertere til et desimaltotal, omdirigere utdata til | tr -d "\n" | wc -c. Teller alle utskrivbare ASCII-tegn (32-126), pluss linjemating (10).

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

Det er vanskelig å unngå å oppføre alle tegn, men vi kan redusere Dette observerer at små bokstaver har en Hamming-vekt på en mer enn tilsvarende store bokstaver. Vi foretrekker newline (score 2) fremfor semikolon (score 5) som en setningsskiller, vi foretrekker @ (score 1) eller ! (score 2) over / (score 5) som mønsteravgrensning.

Merk – for å få de riktige settene med tegn, opprettet jeg denne tabellen fra tabellen i man ascii, sortert etter vekt. Bare legg til poengene rett og under for å få totalvekten til hvert tegn:

 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 

Dette kan vise seg å være nyttig for andre.

Svar

Julia 262 268

Endret versjon bruker hendig «count_ones» -funksjon for å lagre 6 (262)

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

Gammel versjon som ikke bruker en innebygd en-tellingsfunksjon (268)

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

Bruker kommandolinjeargument for inndata.

Svar

CJam 52 eller 48

Hvis input ikke allerede er på bunken (52)

q:i2fbs:s:i:+ 

Hvis inndata er på stack (48)

:i2fbs:s:i:+ 

For eksempel

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

Svar

Julia, HW 199

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

Med

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

eller ved å sette inn strengen direkte:

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 

Den ugolfede versjonen (HW 411) ser slik ut:

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

Og for moro skyld, her er en optimalisert versjon (Hamming Weight 231 ) av bakergs tak på problemet:

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

med

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

Svar

HPPPL (HP Prime Programming Language), 74

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

HP Prime-grafkalkulatoren har en innebygd hamdist-funksjon ().Hammingsvekten til hvert tegn er den samme som hamringsavstanden fra 0.

ASC (streng) oppretter en matrise med ASCII-verdiene til hvert tegn i en streng.

hamdist ( verdi, 0) beregner hammingsavstanden fra 0 for hver ASCII-verdi

sum () oppsummerer alle verdier.

Beregning av hammingvekt for egen kildekode:

Hamming vekt HPPPL

Svar

05AB1E , vekt 17 (4 byte )

ÇbSO 

Prøv det online eller verifisere noen flere testtilfeller .

Forklaring:

 Ç # 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  

Svar

Perl 6 , 102

Prøv det online!

Selv om dette ikke er kode golf, synes den korteste løsningen også å ha den minste hammingvekten …

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *