Skapa ett program som beräknar hammingvikt för en sträng. Vinnaren är programmet med den lägsta hammingvikten.

Regler:

  • Hammingvikt för ett ASCII-tecken definieras som det totala antalet bitar inställt på 1 i sin binära representation.
  • Antag att ingångskodning är 7-bitars ASCII, skickas genom vilken inmatningsmekanism som är normal för ditt språk (t.ex. stdin, args, etc.)
  • Skicka resultatet, som ett nummer, till stdout eller vilken standard / normal utmatningsmekanism som ditt språk använder.
  • Det borde vara självklart, men du måste kunna faktiskt köra programmet i verkligheten, för att det ska vara en giltig lösning.
  • Vinnaren är den lösning vars kod har lägst hammingvikt.
  • Tyvärr, inga lösningar i whitespace för den här! Okej, du kan koda i whitespace nu har jag ordnat upp reglerna 🙂

Exempel per tecken:

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

Kommentarer

  • om vi tar 0x20 / ASCII 32 som referens, är inte ’ t brummande vikten av hello world 10 snarare än 11?
  • Varför är vikten på hello world 11? Endast tio tecken skiljer sig från ett mellanslag. Ett program ’ s Hamming-vikt verkar bara vara dess längd, exklusive mellanslag. Inte så annorlunda än vanlig kodgolf.
  • Tyvärr, jag förstörde det här helt. Wikipedia ’ s hamming viktartikel är ganska vilseledande, och jag fubar helt ’ redigerade reglerna. Skriva om nu. Uppdatering: Okej, skrivs om för att definiera det som antalet bitar satt till 1 i ASCII-strängen, ursäkt för skruvningen.
  • @ugoren En lösning med lägre -värde ASCII-tecken har en lägre hammingvikt.
  • Nu är allt vettigt. ANVÄND UPPERCASE, SE upp för ~ OCH o.

Svar

J (33)

En lägre än 34!

+/,#:3 u: 

Tungt inspirerad av det här svaret , men en hammingvikt på en lägre.

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

Svar

J, vikt 34

+/,#:a.i. 

Användning – placera sträng som ska mätas med citat i slutet:

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

Alternativt kan du ta inmatning från tangentbordet (vikt 54):

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

Kommentarer

  • ’ är bara ett sätt att skriva detta:)
  • Det finns inte ’ t … Jag hittade en lösning som har en hammingvikt på en lägre.
  • Försöker inte vara en buzzkill, men reglerna ber om ett program, inte ett fragment.

Svar

J , 39

+/,#:a.i:] 

Detta är en funktion som tar en argument. (Eller ersätt ] med strängen direkt; som Gareth antecknar, det kostar ner till 34.)

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

Kommentarer

  • Stora sinnen tänker lika. 🙂

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 poängen 180.
  • @ dan04: Använd dubbla citat istället för singel för 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 

Typ av rätt verktyg för jobbet, suger naturligtvis fortfarande.

Kommentarer

  • +1 för att använda ett av mina favoritspråk genom tiderna. Det är ’ det första språket jag lärde mig att koda in på en dator.

Svar

Unary 0

Ni visste alla att det skulle komma. Först BrainFuck-programmet:

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

Jag lade till nya rader för att göra det ”läsbart” men det har en Hamming-vikt på 4066. Det fungerar genom att upprepade gånger få kvoten / rester av en inmatningssträng och lägga till alla återstoder. Självklart om du kör det på sig själv får du: 226 (4066% 256) (tekniskt \ xe2) så tydligt att det regerar själv vinnaren.

Nu konverterar vi det till Unary och får

div id = ”235c480adc”>

Vi använder en enhetlig implementering med NULL-tecken \ x00 för ”0” och bom, hamming vikt på 0.

Bonusfråga : För vilka ASCII-tecken c kan du köra programmet på en sträng som består av N upprepningar och låt den mata ut den karaktären. (E.G. en sträng på 32 mellanslag ger ett mellanslag).Vilka värden för N fungerar (antingen ett oändligt antal av dem fungerar eller ingen fungerar).

Kommentarer

  • Jag ’ jag är inte säker på att jag förstår den här lösningen. The brainfuck-programmet har en enorm hammingvikt. Accepterar Unary null byte som ett program, eller skulle du behöva implementera Unary igen? Om det ’ är det senare, är det ’ inte riktigt en giltig lösning – vem som helst kan bara säga ” Jag definierar ett programmeringsspråk där varje ingångsbyte ger {resultat} ” och vinner varje kodgolfutmaning på webbplatsen.
  • En null karaktär Unary skulle vara bra. Allt du behöver är en EOF för att säga sluta räkna. Faktum är att här ’ är lite pseudo-C för att läsa den filen: main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; } Inte ’ spelar ingen roll vad du väljer att vara din unary char (så länge det inte är ’ t EOF).
  • Tja här ’ är oenig för C-kompilatorn som fungerar bra med nulltecken: ideone.com/MIvAg . Naturligtvis skulle filen som krävs för att göra detta program inte passa i universum, men vi har kapacitet att köra den.
  • Om du kan ’ t faktiskt kör det, det ’ är inte riktigt en lösning.
  • Som Carl Sagan sa en gång: ” Om du vill beräkna hammingvikten för en sträng måste du först uppfinna 10 ^ 500 universer. ” (miljarder och miljarder, jämnt)

Svar

C, vikt 322 263 256

Räknar hammingviktens hammande vikt?

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

Används mestadels standard golf tekniker.
En enda slinga beräknar vikt (skiftar åt höger och lägger till tills noll) och skannar strängen (flyttar pekaren när noll nås).
Antar att D initialiseras till 2 (enstaka parameter).

Hamming vikt specifik optimizati ons:
1. ABDH, med vikt 2 vardera, används för namn.
2. *++H föredras framför H[1].

Kommentarer

  • Hah, jag förstod helt din första mening förrän just nu.
  • Du kan få poängen ner till 230 genom att ange resultatet som ett unary nummer: main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
  • @schnaader , Jag visste aldrig att @ var en siffra i det unary systemet. Jag trodde att den bara använder 0 .. 0. Men om du vill gå detta så är printf("@"+*a%2) kortare.
  • @ugoren: Beror på konventionen / definitionen av unary. T.ex. sv.wikipedia.org/wiki/Unary_numeral_system använder stämplar och säger ” Det finns ingen uttrycklig symbol som representerar noll på samma sätt som i andra traditionella baser ”.
  • @schnaader, OK, men jag tror att det ’ s sträcker kravet ” som ett nummer ” för långt.

Svar

Golfscript 84 72 58

{2base~}%{+}* 

(tack till Howard och Peter Taylor för deras hjälp)

Ingång: inmatningssträngen måste finnas på stacken (skickas som kommandorad argument, eller helt enkelt placeras på stacken).

Om du kör det från kommandoraden, se till att du använder echo -n, annars kommer den efterföljande nya raden också räknas.

Output: skriver ut hammingviktsvärdet till konsolen

Programmet kan testas

här .

Kommentarer

  • Är Golfscript skiftlägeskänslig? Om inte, kan du spara några bitar genom att använda BASE istället för base. Uppdatering: Just markerad, BASE fungerar inte ’. Bra lösning 🙂
  • @ Polynomial Jag försökte det efter att ha sett din TEST / test kommentar 🙂 Men det gör det inte ’ t fungerar.
  • Du kan bli av med {...}2* genom att tillämpa 2base~ i första hand. Får poäng ner till 72.
  • @Howard tack för det här fantastiska tipset! Jag ’ har tillämpat det i mitt svar.
  • Din testmekanism är fel eftersom du ’ har glömt en viktig begränsning av din Web GolfScript-sida. Du bör ha en ; före strängen som du ersätter stdin, så att (; är onödig. Då får Howards ’ s observation ner till 65.

Svar

Perl, 80 (22 tecken)

Klar och gjort:

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

Eller här är en alternativ version med vikten 77 (21 tecken):

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

Jag gillar dock inte den versionen lika mycket, för dess utdata utelämnar den sista nya raden.

För att beräkna vikten antar jag att jag räknar tecken på vanligt sätt (exklusive perl -e / -E, men inklusive andra alternativtecken). Om människor av någon anledning klagar på det här är det bästa jag kan göra utan alternativ 90 (26 tecken):

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

Exempel på användning:

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

Boom.

Svar

Pyth – 15

Ansvarsfriskrivning: Detta svar kan inte vinna eftersom Pyth är yngre än denna utmaning.

Använder .B för binär representation och räknar antalet "1" ”s.

/.BQ\1 

Tar inmatning i en sträng för att spara på z kontra Q.

Prova det online här .

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 modifiering av självtest.

Kommentarer

  • Det ’ vikt 495, inte 231. Du kan ’ t få vikt 231 med 126 tecken – att ’ är i genomsnitt mindre än 2 och alla utskrivbara tecken (förutom @ och mellanslag, som du inte ’ inte använda) har minst 2 vikt.
  • @ugoren: Men det ’ är bara 65 tecken. Programmet skrivs ut nästan två gånger: En gång koden för att beräkna hammingvikten och en andra gång som statisk ingång för att beräkna den för programmet. Men den beräknande delen saknar ” readLine () ” framför, eftersom det tar bokstavlig inmatning. Jag försökte klargöra själva svaret.

Svar

Java, vikt 931 774 499 454

Jag tror att det här är det enda svaret just nu med en vikt över cirka 300.

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

Förväntar inmatning som ett kommandoradsargument.

Svar

GNU sed -r, 467 + 1

(+1 för användning av -r – eller ska det vara +4?)

Matar ut som ett enhetligt värde per källrad; för att konvertera till ett decimaltal, omdirigera utdata till | tr -d "\n" | wc -c. Räknar alla utskrivbara ASCII-tecken (32-126), plus radmatning (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 är svårt att undvika att lista alla tecken, men vi kan minska detta observerar att gemena bokstäver har en Hamming-vikt på en mer än motsvarande versaler. Vi föredrar newline (poäng 2) framför semikolon (poäng 5) som en uttalande separator; vi föredrar @ (poäng 1) eller ! (poäng 2) över / (poäng 5) som mönsteravgränsare.

Obs – för att få rätt uppsättningar tecken skapade jag den här tabellen från tabellen i man ascii, sorterad efter vikt. Lägg bara till poängen till höger och nedan för att få den totala vikten för varje tecken:

 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 

Detta kan visa sig vara användbart för andra.

Svar

Julia 262 268

Ändrad version använder praktisk ”count_ones” -funktion för att spara 6 (262)

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

Gammal version med ingen inbyggd en-räkningsfunktion (268)

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

Använder kommandoradsargument för inmatning.

Svar

CJam 52 eller 48

Om ingång inte redan finns i stacken (52)

q:i2fbs:s:i:+ 

Om ingången finns på stacken (48)

:i2fbs:s:i:+ 

Till exempel

"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 genom att direkt infoga strängen:

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 ofullständiga versionen (HW 411) ser ut så här:

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

Och för skojs skull är här en optimerad version (Hamming Vikt 231 ) av bakergar tar upp 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-grafräknaren har en inbyggd hamdist-funktion ().Hammingvikten för varje tecken är densamma som hammingsavståndet från 0.

ASC (sträng) skapar en matris med ASCII-värdena för varje tecken i en sträng.

hamdist ( värde, 0) beräknar hammingsavståndet från 0 för varje ASCII-värde

summa () summerar alla värden.

Beräkning av hammingvikten för sin egen källkod:

Hamming Vikt HPPPL

Svar

05AB1E , vikt 17 (4 byte )

ÇbSO 

Prova online eller verifiera några fler testfall .

Förklaring:

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

Prova online!

Även om detta inte kodar golf verkar den kortaste lösningen också ha den minsta hammingvikten …

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *