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
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änder0
..0
. Men om du vill gå detta så ärprintf("@"+*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örbase
. 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ämpa2base~
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
.
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:
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
+*.ords>>.base(2).comb(~1)
Även om detta inte kodar golf verkar den kortaste lösningen också ha den minsta hammingvikten …
0x20
/ ASCII 32 som referens, är inte ’ t brummande vikten avhello world
10 snarare än 11?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.~
OCHo
.