Oblicz masę młota o niskiej masie młota


19

Utwórz program, który oblicza masę hamującą łańcucha. Zwycięzcą jest program o najniższej wadze młota.

Zasady:

  • Waga Hamminga dla znaku ASCII jest zdefiniowana jako całkowita liczba bitów ustawiona 1w jego reprezentacji binarnej.
  • Załóżmy, że kodowanie wejściowe to 7-bitowe ASCII, przekazywane przez dowolny mechanizm wejściowy, który jest normalny dla twojego języka (np. Standardowe, args itp.)
  • Wyprowadź wynik jako liczbę do standardowego lub innego domyślnego / normalnego mechanizmu wyjściowego używanego przez Twój język.
  • Powinno być oczywiste, ale musisz być w stanie uruchomić program w prawdziwym życiu, aby było to prawidłowe rozwiązanie.
  • Zwycięzca to rozwiązanie, którego kod ma najniższą masę młota.
  • Niestety, nie ma dla tego rozwiązania białych znaków ! Ok, możesz pisać w białych znakach, teraz uporządkowałem zasady :)

Przykłady poszczególnych znaków:

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

jeśli weźmiemy 0x20/ ASCII 32 jako odniesienie, to czy szum nie jest równy hello world10, a nie 11?
Cristian Lupascu

Dlaczego waży hello world11? Tylko 10 znaków różni się od spacji. Ponadto - waga Hamminga programu wydaje się być tylko długością, z wyłączeniem spacji. Nie różni się tak bardzo od normalnego golfa kodowego.
ugoren

Przepraszam, całkowicie to spieprzyłem. Artykuł o wadze w Wikipedii jest dość mylący, a ja całkowicie podoba mi się ten regulamin. Teraz piszę ponownie. Aktualizacja: Ok, przepisano ponownie, aby zdefiniować go jako liczbę bitów ustawioną na 1 w ciągu ASCII, przepraszam za zepsucie.
Wielomian

@ugoren Rozwiązanie ze znakami ASCII o niższej wartości ma niższą wagę hamującą.
Wielomian

1
Teraz to wszystko ma sens. WYKORZYSTANIE UPPERCASE, strzeż ~AND o.
ugoren

Odpowiedzi:



8

J, waga 34

+/,#:a.i.

Użycie - umieść ciąg do zmierzenia w cudzysłowie na końcu:

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

Alternatywnie, przyjmując dane z klawiatury (waga 54):

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

Jest tylko jeden sposób, aby to napisać :)
ephemient

Nie ma ... Znalazłem rozwiązanie, które ma ciężar o jeden niższy.
23ıʇǝɥʇuʎs

Nie próbując być bzikiem, ale zasady wymagają programu, a nie fragmentu.
FUZxxl,

5

J , 39

+/,#:a.i:]

Jest to funkcja przyjmująca jeden argument. (Lub zastąp ]bezpośrednio sznurkiem; jak zauważa Gareth, obniża to koszt do 34.)

   + /, #: ai:] 'hello world'
45
   + /, #: ai:] '+ /, #: ai:]'
39

Wielkie umysły myślą podobnie. :-)
Gareth

5

Python, 189

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

2
Odpowiednik w Pythonie 3 print(sum(bin(ord(A)).count('1')for A in input()))ma wynik 180.
dan04

4
@ dan04: Używaj podwójnych cudzysłowów zamiast pojedynczych w przypadku 176.
Keith Randall

5

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

Rodzaj właściwe narzędzie do pracy, nadal ssie oczywiście.


1
+1 za używanie jednego z moich ulubionych języków wszechczasów. To pierwszy język, którego nauczyłem się pisać na komputerze.
Wielomian

5

Unary 0

Wszyscy wiedzieliście, że to nadchodzi. Najpierw program BrainFuck:

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

Dodałem nowe wiersze, aby uczynić go „czytelnym”, ale ma wagę Hamminga 4066. Działa poprzez wielokrotne pobieranie ilorazu / reszty ciągu wejściowego i sumowanie wszystkich pozostałych. Oczywiście, jeśli uruchomisz go na sobie, otrzymasz: 226 (4066% 256) (technicznie \ xe2) tak wyraźnie, że rządzi się zwycięzcą.

Teraz przekształcamy go w Unary i otrzymujemy

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

Używamy jednoargumentowej implementacji ze znakami NULL \ x00 dla „0” i wysięgnika, co daje wagę 0.

Pytanie dodatkowe : Dla jakich znaków ASCII cmożesz uruchomić ten program na łańcuchu składającym się z Npowtórzeń i wypuścić ten znak. (Np. Ciąg 32 spacji daje spację). Jakie wartości Npracy (albo nieskończona ich liczba zadziała, albo żadna nie zadziała).


1
Nie jestem pewien, czy rozumiem to rozwiązanie. Program pieprzenia mózgu ma ogromną wagę. Czy Unary akceptuje bajty zerowe jako program, czy też trzeba ponownie wdrożyć Unary? Jeśli to drugie, nie jest to naprawdę poprawne rozwiązanie - każdy może po prostu powiedzieć: „Definiuję język programowania, w którym każdy pojedynczy bajt wejściowy daje {wynik}”, i wygrywa każde wyzwanie golfowe w kodzie na stronie.
Wielomian

1
Znak zerowy Unary byłby w porządku. Wszystko czego potrzebujesz to EOF, żeby powiedzieć „przestań liczyć”. W rzeczywistości oto pseudo-C, aby odczytać ten plik: main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; }Nie ma znaczenia, co wybierzesz jako swój Unary char (o ile nie jest to EOF).
walpen

1
Oto jeden z kompilatorów C, który działa dobrze ze znakami zerowymi : ideone.com/MIvAg . Oczywiście plik wymagany do stworzenia tego programu nie zmieściłby się we wszechświecie, ale jesteśmy w stanie go uruchomić.
walpen

3
Jeśli nie można faktycznie go uruchomić, to naprawdę nie jest rozwiązaniem.
Wielomian

4
Jak powiedział kiedyś Carl Sagan : „Jeśli chcesz obliczyć masę młotka, najpierw musisz wynaleźć 10 ^ 500 wszechświatów”. (miliardy, a nawet miliardy)
walpen

4

C, masa 322 263 256

Czy liczy się ciężar wbijający w młot?

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

Stosowane głównie standardowe techniki gry w golfa.
Pojedyncza pętla oblicza masę (przesuwa się w prawo i dodaje do zera) i skanuje ciąg znaków (przesuwa wskaźnik, gdy osiągnie zero).
Zakładając, że Djest inicjowany na 2 (pojedynczy parametr).

Optymalizacje specyficzne dla wagi Hamminga:
1. ABDH, każda z wagą 2, używana dla nazw.
2. *++Hpreferowane H[1].


Hah, kompletnie nie zrozumiałem twojego pierwszego zdania aż do teraz.
breadbox

Można dostać się na dół wynik 230 przez wyprowadzanie wynik jako jednoargumentowego numer:main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
schnaader

@ Schnaader, nigdy nie wiedziałem, że @jest cyfrą w systemie jednorzędowym. Myślałam, że używa tylko 0.. 0. Ale jeśli chcesz to zrobić, droga printf("@"+*a%2)jest krótsza.
ugoren

@ugoren: Zależy od konwencji / definicji unary. Np. En.wikipedia.org/wiki/Unary_numeral_system używa znaczników tally i mówi: „Nie ma wyraźnego symbolu reprezentującego zero w jedności, jak w innych tradycyjnych bazach”.
schnaader

@ Schnaader, OK, ale myślę, że to zbyt daleko rozszerza wymóg „jako liczba”.
ugoren

4

Golfscript 84 72 58

{2base~}%{+}*

(podziękowania dla Howarda i Petera Taylora za ich pomoc)

Dane wejściowe: ciąg wejściowy musi znajdować się na stosie (przekazany jako argument wiersza poleceń lub po prostu umieszczony na stosie).

Jeśli uruchamiasz go z wiersza poleceń, upewnij się, że używasz echo -n, w przeciwnym razie liczony będzie również znak nowej linii.

Wyjście: drukuje wartość masy młota na konsoli

Program można przetestować tutaj .


1
Czy rozróżniana jest wielkość liter w Golfscript? Jeśli nie, możesz zapisać kilka bitów, używając BASEzamiast base. Aktualizacja: właśnie zaznaczona, BASEnie działa. Dobre rozwiązanie :)
Wielomian

@Polynomial Próbowałem tego po obejrzeniu twojego TEST/ testkomentarza :) Ale to nie działa.
Cristian Lupascu

Możesz się go pozbyć {...}2*, aplikując 2base~w pierwszej kolejności. Uzyskuje wynik do 72.
Howard

@Howard dzięki za tę wspaniałą wskazówkę! Zastosowałem to w swojej odpowiedzi.
Cristian Lupascu,

Twój mechanizm testowy jest nieprawidłowy, ponieważ zapomniałeś ważnego ograniczenia strony Web GolfScript. Powinieneś mieć ;przed ciągiem, który zastępujesz stdin, więc nie (;jest to konieczne. Następnie obserwacja Howarda sprowadza się do 65.
Peter Taylor

2

Perl, 80 (22 znaków)

Sporządzono i zrobiono:

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

Lub tutaj jest alternatywna wersja o wadze 77 (21 znaków):

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

Nie podoba mi się jednak ta wersja, ponieważ jej wynik pomija ostatnią nową linię.

Aby obliczyć wagę, zakładam, że liczę znaki w zwykły sposób (wyłączając perl -e/ -E, ale włączając inne znaki opcji). Jeśli z jakiegoś powodu ludzie narzekają na to, to najlepsze, co mogę zrobić bez opcji, to 90 (26 znaków):

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

Przykładowe użycie:

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

Bum.


2

Pyth - 15

Oświadczenie: Ta odpowiedź nie kwalifikuje się do wygrania, ponieważ Pyth jest młodszy od tego wyzwania.

Wykorzystuje .Breprezentację binarną i zlicza liczbę "1".

/.BQ\1

Pobiera dane wejściowe w ciągu, aby zaoszczędzić na zkontra Q.

Wypróbuj online tutaj .


1

Scala 231

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

Kod testowy:

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

z modyfikacją samokontroli.


Ma wagę 495, a nie 231. Nie można uzyskać wagi 231 ze 126 znakami - to średnio mniej niż 2, a wszystkie znaki do wydruku (z wyjątkiem @i spacji, których nie używasz) mają co najmniej wagę 2.
ugoren

1
@ugoren: Ale to tylko 65 znaków. Program jest drukowany prawie dwa razy: Raz kod do obliczenia masy młota, a drugi raz jako dane statyczne, aby obliczyć go dla programu. Jednak w części obliczeniowej brakuje „readLine ()” z przodu, ponieważ pobiera ona dosłowne dane wejściowe. Próbowałem wyjaśnić samą odpowiedź.
użytkownik nieznany

1

Java, waga 931 774 499 454

Myślę, że w tej chwili jest to jedyna odpowiedź o wadze ponad 300.

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

Oczekuje danych wejściowych jako argumentu wiersza poleceń.


1

GNU sed -r, 467 + 1

(+1 za użycie -r- czy powinno to być +4?)

Wyjściowe wartości jednostkowe na linię źródłową; aby przekonwertować na liczbę dziesiętną, przekieruj wyjście na | tr -d "\n" | wc -c. Zlicza wszystkie drukowalne znaki ASCII (32-126), plus wysuw wiersza (10).

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

Trudno jest uniknąć wyszczególnienia wszystkich znaków, ale możemy to zmniejszyć, zauważając, że małe litery mają ciężar Hamminga o jeden większy niż odpowiadające im wielkie litery. Wolimy znak nowej linii (wynik 2) niż średnik (wynik 5) jako separator instrukcji; my wolimy @(wynik 1) lub! (wynik 2) niż /(wynik 5) jako ogranicznik wzoru.

Uwaga - aby uzyskać odpowiednie zestawy znaków, stworzyłem tę tabelę od tej man ascii, posortowanej według wagi. Po prostu dodaj wyniki bezpośrednio i poniżej, aby uzyskać całkowitą wagę każdej postaci:

   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

Może się to przydać innym.


0

Julia 262 268

Zmodyfikowana wersja wykorzystuje przydatną funkcję „count_ones” dla oszczędności 6 (262)

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

Stara wersja bez wbudowanej funkcji liczenia (268)

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

Używa argumentu wiersza poleceń do wprowadzania danych.


0

CJam 52 lub 48

Jeśli dane wejściowe nie są jeszcze na stosie (52)

q:i2fbs:s:i:+

Jeśli dane wejściowe są na stosie (48)

:i2fbs:s:i:+

Na przykład

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

0

Julia, HW 199

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

Z

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

lub bezpośrednio wstawiając ciąg:

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

Wersja bez golfa (HW 411) wygląda następująco:

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

A dla zabawy, oto zoptymalizowana wersja (Hamming Weight 231 ) podejścia Bakerga do problemu:

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

z

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

0

HPPPL (HP Prime Programming Language), 74

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

Kalkulator graficzny HP Prime ma wbudowaną funkcję hamdist (). Masa uderzenia każdego znaku jest taka sama, jak odległość uderzenia od 0.

ASC (ciąg) tworzy tablicę wartości ASCII każdego znaku w ciągu.

hamdist (wartość, 0) oblicza odległość uderzenia od 0 dla każdej wartości ASCII

sum () sumuje wszystkie wartości.

Obliczanie masy młota własnego kodu źródłowego:

Waga Hamminga HPPPL


0

05AB1E , waga 17 (4 bajty )

ÇbSO

Wypróbuj online lub sprawdź kilka innych przypadków testowych .

Wyjaśnienie:

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.