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
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 bruker0
..0
. Men hvis du vil gå dette, erprintf("@"+*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 forbase
. 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 å bruke2base~
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
.
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:
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
+*.ords>>.base(2).comb(~1)
Selv om dette ikke er kode golf, synes den korteste løsningen også å ha den minste hammingvekten …
0x20
/ ASCII 32 som referanse, er ikke ‘ t brumvekten tilhello world
10 i stedet for 11?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.~
OGo
.