Vytvořte program, který vypočítá příklepovou hmotnost řetězec. Vítězem je program s nejnižší Hammingovou váhou.
Pravidla:
- Hammingova váha pro znak ASCII je definována jako celkový počet bitů nastavený na
1
v jeho binární reprezentaci. - Předpokládejme, že vstupní kódování je 7bitové ASCII, prochází jakýmkoli vstupním mechanismem, který je pro váš jazyk normální (např. Stdin, args atd.)
- Výstup výsledku jako číslo na standardní výstup nebo jakýkoli výchozí / normální výstupní mechanismus, který váš jazyk používá.
- Mělo by to být samozřejmé, ale musíte být schopni skutečně spustit program, v reálném životě, aby byl platným řešením.
- Vítězem je řešení, jehož kód má nejnižší hammingovou váhu.
-
Omlouváme se, v mezerách pro toto žádné řešení!Dobře, nyní můžete kódovat v mezerách, nyní jsem vyřešil pravidla 🙂
Příklady podle znaků:
char | binary | weight -----+----------+------- a | 01100001 | 3 x | 01111000 | 4 ? | 00111111 | 6 \x00 | 00000000 | 0 \x7F | 01111111 | 7
Komentáře
Odpověď
J (33)
Jeden méně než 34!
+/,#:3 u:
Silně inspirováno touto odpovědí , ale o jednu nižší váhu.
+/,#:3 u:"+/,#:3 u:" 33
Odpověď
J, váha 34
+/,#:a.i.
Použití – umístěte řetězec, který se bude měřit v uvozovkách na konci:
+/,#:a.i."+/,#:a.i." 34
Alternativně lze převzít vstup z klávesnice (váha 54):
+/,#:a.i.1!:1[1 hello 21
Komentáře
- Existuje ‚ jediný způsob, jak to napsat 🙂 🙂
- Není ‚ t … našel jsem řešení, které má hammovací váhu o jednu nižší.
- Nesnažím se být buzzkill, ale pravidla požadují program, ne fragment.
Odpověď
J , 39
+/,#:a.i:]
Toto je funkce argument. (Nebo nahraďte ]
řetězcem přímo; jak poznamenává Gareth, cena se sníží na 34.)
+/,#:a.i:] "hello world" 45 +/,#:a.i:] "+/,#:a.i:]" 39
Komentáře
- Velké mozky si myslí stejně. 🙂
Odpověď
Python, 189
print sum(bin(ord(A)).count("1")for A in raw_input())
Komentáře
- Ekvivalent Pythonu 3,
print(sum(bin(ord(A)).count('1')for A in input()))
, má skóre 180. - @ dan04: Používejte dvojité uvozovky místo 176.
Odpověď
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
Druh ten správný nástroj pro práci, samozřejmě stále naštvaný.
Komentáře
- +1 pro používání jednoho z mých oblíbených jazyků všech dob. Je to ‚ první jazyk, který jsem se naučil programovat na PC.
Odpovědět
Unární 0
Všichni jste věděli, že to přijde. Nejprve program BrainFuck:
,[[>++[>>+>+<<<-]>>> [<<<+>>>-]>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>> [<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-] [-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>[<<<<<<->>>->>> [-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<< [>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<<< [>>+<[>>+>+<<<-]>>>[<<<+>>>-]>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>> [<<<<<<+>>>>>>-]<<<[>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]> [-]>[<<<<<<->>>->>>[-]<<<<<<[>>>>+>>+<<<<<<-]>>>>>>[<<<<<<+>>>>>>-]<<< [>>+>+<<<-]>>>[<<<+>>>-][-]<<[>>[-]<[>[-]+<[-]]<[-]]>[-]>]<<<<<<]>>> [>+>+<<-]>>[<<+>>-][-]+<[>[-]<<[<<->>-]<<[>>+<<-]>>>[-]]>[<<<+<[-]>>>> [-]]<<[->>>>+<<<<]<[-<<+>>]<<],]>>>>>>>.
Přidal jsem nové řádky, aby byl „čitelný“, ale má Hammingovu váhu 4066. Funguje to opakovaným získáváním kvocientu / zbytky vstupního řetězce a sečtení všech zbývajících. Samozřejmě, pokud ho spustíte sám, dostanete: 226 (4066% 256) (technicky \ xe2), takže jasně vládne sám vítězi.
Nyní jej převedeme na Unary a dostaneme
000 ... 9*google^5.9 0"s ... 000
Používáme unární implementaci s NULL znaky \ x00 pro „0“ a boom, snižující váhu 0.
Bonusová otázka : U jakých znaků ASCII c
můžete tento program spustit na řetězci skládajícím se z N
opakování a nechat jej vydat tento znak. (Např. Řetězec 32 mezer dává mezeru).Jaké hodnoty N
fungují (bude fungovat buď nekonečný počet, nebo žádný).
Komentáře
- Já ‚ si nejsem jistý, zda tomuto řešení rozumím. Program brainfuck má obrovskou hammingovou váhu. Přijímá Unary jako program nulové bajty, nebo byste museli znovu implementovat Unary? Pokud je to ‚ to druhé, není to ‚ skutečně platné řešení – každý by mohl říci “ Definuji programovací jazyk, kde libovolný jeden vstupní bajt dává {result} „, a vyhraji každou výzvu v oblasti kódu na webu.
- Null postava Unary by byla v pořádku. Vše, co potřebujete, je EOF, abyste řekli, že přestanete počítat. Ve skutečnosti zde ‚ je nějaký pseudo-C ke čtení tohoto souboru:
main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; }
Není ‚ Vůbec nezáleží na tom, co si vyberete za svého Unárního char (pokud to není ‚ t EOF). - Tady ‚ Je unární kompilátoru C, který funguje s prázdnými znaky: ideone.com/MIvAg . Soubor potřebný k vytvoření tohoto programu by se samozřejmě do vesmíru nehodil, ale máme kapacitu jej spustit.
- Pokud můžete ‚ t ve skutečnosti spustit, ‚ ve skutečnosti není řešením.
- As Carl Sagan jednou řekl: “ Chcete-li vypočítat hammingovu váhu řetězce, musíte nejprve vymyslet 10 ^ 500 vesmírů. “ (miliardy a miliardy, sudé)
Odpověď
C, váha 322 263 256
Počítá se hammingova hmotnost hammingovy váhy?
main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))D+=*A%2;printf("%d",D-2);}
Používá se převážně standardní golf techniky.
Jedna smyčka vypočítá váhu (posun doprava a přidání do nuly) a prohledá řetězec (po dosažení nuly posune ukazatel).
Za předpokladu, že D
je inicializována na 2 (jediný parametr).
Optimalizace podle Hammingovy váhy ons:
1. ABDH
, každá o hmotnosti 2, použitá pro jména.
2. *++H
přednost před H[1]
.
Komentáře
- Hah, vaší první větě jsem doposud úplně nerozuměl.
- Skóre můžete snížit až na 230 tak, že výsledek odešlete jako unární číslo:
main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
- @schnaader , Nikdy jsem nevěděl, že
@
je číslice v unárním systému. Myslel jsem, že používá pouze0
..0
. Ale pokud chcete jít tímto způsobem, cestaprintf("@"+*a%2)
je kratší. - @ugoren: Závisí na konvenci / definici unárního. Např. en.wikipedia.org/wiki/Unary_numeral_system používá srovnávací značky a říká “ Neexistuje žádný explicitní symbol představující nulu unární jako v jiných tradičních základnách „.
- @schnaader, OK, ale myslím, že ‚ s rozšířením požadavku “ na číslo “ příliš daleko.
odpověď
Golfscript 84 72 58
{2base~}%{+}*
(děkujeme Howardovi a Peteru Taylorovi za pomoc)
Vstup: vstupní řetězec musí být v zásobníku (předán jako příkazový řádek nebo jednoduše umístěný na zásobník).
Pokud jej spustíte z příkazového řádku, ujistěte se, že používáte echo -n
, jinak bude koncový nový řádek také započítává se.
Výstup: vytiskne do konzoly hodnotu hammovací hmotnosti
Program lze otestovat
zde .
Komentáře
- Rozlišuje Golfscript velká a malá písmena? Pokud ne, můžete uložit několik bitů pomocí
BASE
namístobase
. Aktualizace: Právě zkontrolováno,BASE
nefunguje ‚. Dobré řešení 🙂 - @Polynomial Zkoušel jsem to poté, co jsem viděl váš
TEST
/test
komentář 🙂 Ale není ‚ nefunguje. -
{...}2*
se můžete zbavit použitím2base~
na prvním místě. Dostane skóre až na 72. - @Howard díky za tento skvělý tip! ‚ Použil jsem to ve své odpovědi.
- Váš testovací mechanismus je špatný, protože jste ‚ zapomněli důležité omezení vaší stránky Web GolfScript. Měli byste mít
;
před řetězcem, který nahradíte stdin, takže(;
je zbytečné. Pozorování Howarda ‚ to pak sníží na 65.
Odpověď
Perl, 80 (22 znaků)
Hotovo a hotovo:
perl -0777nE "say unpack"%32B*""
Nebo zde je alternativní verze o hmotnosti 77 (21 znaků):
perl -0777pE "$_=unpack"%32B*""
Tato verze se mi moc nelíbí, protože její výstup vynechává konečný nový řádek.
Pro výpočet váhy předpokládám, že počítám znaky obvyklým způsobem (kromě perl -e
/ -E
, ale včetně dalších volitelných znaků). Pokud si z nějakého důvodu lidé na to stěžují, pak je nejlepší, co můžu bez možností udělat, 90 (26 znaků):
$/=$,,say unpack"%32B*",<>
Ukázkové použití:
$ perl -0777nE "say unpack"%32b*"" rickroll.txt 7071
Boom.
Odpověď
Pyth – 15
Zřeknutí se odpovědnosti: Tato odpověď nemůže vyhrát, protože Pyth je mladší než tato výzva.
Používá .B
pro binární reprezentaci a počítá počet "1"
„s.
/.BQ\1
Přijme vstup v řetězci, který uloží na z
proti Q
.
Odpověď
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
s úpravou vlastního testování.
Komentáře
- Je ‚ s váhou 495, ne 231. ‚ Nelze získat váhu 231 se 126 znaky – to ‚ s průměrem méně než 2 a všechny tisknutelné znaky (kromě
@
a prostoru, který ‚ t use) have weight 2 at least. - @ugoren: Ale to ‚ má pouze 65 znaků. Program se vytiskne téměř dvakrát: Jednou kód pro výpočet hammingovy hmotnosti a podruhé jako statický vstup pro výpočet pro program. Ve výpočetní části ale chybí “ readLine () „, protože to vyžaduje doslovný vstup. Pokusil jsem se objasnit samotnou odpověď.
Odpověď
Java, váha 931 774 499 454
Myslím, že toto je v tuto chvíli jediná odpověď s váhou přes 300.
class H{public static void main(String[]A){System.out.print(new java.math.BigInteger(A[0].getBytes()).bitCount());}}
Očekává vstup jako argument příkazového řádku.
Odpověď
GNU sed -r
, 467 + 1
(+1 pro použití -r
– nebo by to mělo být +4?)
Výstupy jako unární hodnota na zdrojový řádek; chcete-li převést na desetinnou částku, přesměrujte výstup na | tr -d "\n" | wc -c
. Počítá všechny tisknutelné znaky ASCII (32–126) plus řádkový posuv (10).
s@[a-z]@\U& @g s@[?{}~]@ @g s@[][/7;=>OW|^]@ @g s@[-"+.3569:<GKMNSUVYZ\\]@ @g s@[#%&)*,CEFIJL1248ORTX]@ @g s@$|[!"$(ABDH0P`]@ @g y! @!11!
Je těžké vyhnout se výpisu všech znaků, ale můžeme omezit toto pozorování, že malá písmena mají Hammingovu váhu o jednu více než odpovídající velká písmena. Preferujeme nový řádek (skóre 2) před středníkem (skóre 5) jako oddělovač příkazů; dáváme přednost @
(skóre 1) nebo !
(skóre 2) nad /
(skóre 5) jako oddělovač vzorů.
Poznámka – pro získání správných sad znaků jsem vytvořil tuto tabulku z tabulky v man ascii
, seřazené podle hmotnosti. Stačí přidat skóre vpravo a níže, abyste získali celkovou váhu každého znaku:
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
To by se ostatním mohlo ukázat jako užitečné.
Odpověď
Julia 262 268
Upravená verze používá praktickou funkci „count_ones“ pro uložení 6 (262)
show(mapreduce(x->count_ones(x),+,map(x->int(x),collect(ARGS[1]))))
Staré verze bez integrované funkce jednoho počítání (268)
show(mapreduce(x->int(x)-48,+,mapreduce(x->bits(x),*,collect(ARGS[1]))))
Pro vstup použije argument příkazového řádku.
Odpověď
CJam 52 nebo 48
Pokud vstup již není v zásobníku (52)
q:i2fbs:s:i:+
Pokud je vstup na zásobníku (48)
:i2fbs:s:i:+
Například
"Hello World":i2fbs:s:i:+
Odpověď
Julia, HW 199
H=mapreduce;H(B->B=="1",+,H(P->bits(P),*,collect(A[:])))
S
A="H=mapreduce;H(B->B=="1",+,H(P->bits(P),*,collect(A[:])))"
nebo přímým vložením řetězce:
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
negolfovaná verze (HW 411) vypadá takto:
bitstring=mapreduce(x->bits(x),*,collect(teststring[:])) mapreduce(checkbit->checkbit=="1",+,bitstring)
A pro zábavu tu je optimalizovaná verze (Hamming Weight 231 ) Bakergova řešení problému:
A=mapreduce;show(A(B->int(B)-48,+,A(B->bits(B),*,collect(H[:]))))
s
H="A=mapreduce;show(A(B->int(B)-48,+,A(B->bits(B),*,collect(H[:]))))"
odpověď
HPPPL (programovací jazyk HP Prime), 74
sum(hamdist(ASC(a),0))
Grafická kalkulačka HP Prime má zabudovanou funkci hamdist ().Hammingova váha každého znaku je stejná jako Hammingova vzdálenost od 0.
ASC (řetězec) vytvoří pole hodnot ASCII každého znaku v řetězci.
hamdist ( value, 0) vypočítá hammingovu vzdálenost od 0 pro každou hodnotu ASCII
sum () shrnuje všechny hodnoty.
Výpočet hammingovy hmotnosti vlastního zdrojového kódu:
Odpověď
05AB1E , váha 17 (4 bajtů )
ÇbSO
Vyzkoušejte to online nebo ověřit další testovací případy .
Vysvětlení:
Ç # 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
odpověď
Perl 6 , 102
+*.ords>>.base(2).comb(~1)
I když to není kódový golf, zdá se, že nejkratší řešení má také nejmenší hammingovou váhu …
0x20
/ ASCII 32 jako reference, není ‚ t hučeníhello world
10 spíše než 11?hello world
11? Pouze 10 znaků se liší od mezery. Také – Hammingova váha programu ‚ s se zdá být pouze jeho délkou, bez mezer. Ne tak odlišné od běžného golfu s kódem.~
Ao
.