Calcular o peso do hamming com baixo peso do hamming

19

Crie um programa que calcule o peso limite de uma string. O vencedor é o programa com o menor peso de hamming.

Regras:

  • O peso de Hamming para um caractere ASCII é definido como o número total de bits definido 1em sua representação binária.
  • Suponha que a codificação de entrada seja ASCII de 7 bits, transmitida por qualquer mecanismo de entrada normal para seu idioma (por exemplo, stdin, args, etc.)
  • Envie o resultado, como um número, para stdout ou qualquer mecanismo de saída padrão / normal que seu idioma utilize.
  • Não é preciso dizer, mas você deve ser capaz de executar o programa, na vida real, para que seja uma solução válida.
  • Winner é a solução cujo código tem o menor peso de hamming.
  • Desculpe, não há soluções em branco para este! Ok, você pode codificar em espaço em branco agora que resolvi as regras :)

Exemplos por caractere:

char |  binary  | weight
-----+----------+-------
a    | 01100001 | 3
x    | 01111000 | 4
?    | 00111111 | 6
\x00 | 00000000 | 0
\x7F | 01111111 | 7
Polinomial
fonte
se tomarmos 0x20/ ASCII 32 como referência, o peso do zumbido é hello world10 e não 11?
Cristian Lupascu
Por que o peso é hello world11? Apenas 10 caracteres são diferentes de um espaço. Além disso - o peso de Hamming de um programa parece ter apenas o seu comprimento, excluindo espaços. Não é tão diferente do código normal de golfe.
precisa saber é o seguinte
Desculpe, eu estraguei totalmente isso. O artigo sobre peso da Wikipedia é bastante enganador, e eu adotei totalmente as regras. Reescrevendo agora. Atualização: Ok, reescrito para defini-lo como o número de bits definido como 1 na string ASCII, desculpe pela bagunça.
Polinomial
@ugoren Uma solução com caracteres ASCII de menor valor tem um menor peso de hamming.
Polinomial
11
agora tudo faz sentido. USE MAIÚSCULAS, cuidado com ~E o.
ugoren

Respostas:

6

J (33)

Um menor que 34!

+/,#:3 u:

Fortemente inspirado por esta resposta , mas com um peso menor do que um.

   +/,#:3 u:'+/,#:3 u:'
33
ɐɔıʇǝɥʇuʎs
fonte
8

J, peso 34

+/,#:a.i.

Uso - coloque a sequência a ser medida entre aspas no final:

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

Como alternativa, recebendo informações do teclado (peso 54):

   +/,#:a.i.1!:1[1
hello
21
Gareth
fonte
Há apenas uma maneira de escrever este :)
ephemient
Não há ... Encontrei uma solução que tem um peso de hamming menor.
ɐɔıʇǝɥʇuʎs
Não tentando ser uma brincadeira, mas as regras pedem um programa, não um fragmento.
FUZxxl
5

J , 39

+/,#:a.i:]

Esta é uma função que aceita um argumento. (Ou substitua ]pela string diretamente; como observa Gareth, isso reduz o custo para 34.)

   + /, #: ai:] 'olá mundo'
45
   + /, #: ai:] '+ /, #: ai:]'
39.
efémero
fonte
Mentes brilhantes pensam igual. :-)
Gareth
5

Python, 189

print sum(bin(ord(A)).count("1")for A in raw_input())
Keith Randall
fonte
2
O equivalente em Python 3 print(sum(bin(ord(A)).count('1')for A in input())), tem uma pontuação de 180.
dan04
4
@ dan04: usar aspas duplas em vez de único para 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

Tipo da ferramenta certa para o trabalho, ainda é péssimo, é claro.

deixou de girar contra-relógio
fonte
11
+1 por usar um dos meus idiomas favoritos de todos os tempos. É o primeiro idioma que aprendi a codificar em um PC.
Polynomial
5

Unário 0

Todos vocês sabiam que estava chegando. Primeiro o programa BrainFuck:

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

Eu adicionei novas linhas para torná-lo "legível", mas tem um peso de Hamming de 4066. Ele funciona obtendo repetidamente o quociente / restante de uma string de entrada e somando todos os restantes. Obviamente, se você executá-lo por conta própria, obtém: 226 (4066% 256) (tecnicamente \ xe2) tão claramente que se decide como vencedor.

Agora nós o convertemos para Unary e obtemos

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

Usamos uma implementação unária com caracteres NULL \ x00 para '0' e boom, prejudicando o peso de 0.

Pergunta de bônus : Para quais caracteres ASCII cvocê pode executar este programa em uma sequência que consiste em Nrepetições e faz com que ele produza esse caractere. (Por exemplo, uma cadeia de 32 espaços dá um espaço). Quais valores do Ntrabalho (um número infinito deles funcionará ou nenhum funcionará).

Walpen
fonte
11
Não sei se entendi essa solução. O programa brainfuck tem um enorme peso hamming. O Unary aceita bytes nulos como um programa ou você precisaria reimplementar o Unary? Se for o último, não é realmente uma solução válida - qualquer um poderia simplesmente dizer "Eu defino uma linguagem de programação onde qualquer byte de entrada fornece {result}" e vencer todos os desafios de código de golfe no site.
Polynomial
11
Um caractere nulo Unário seria bom. Tudo que você precisa é de um EOF para parar de contar. De fato, aqui estão alguns pseudo-C para ler esse arquivo: main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; }Não importa o que você escolhe como seu caractere Unário (contanto que não seja EOF).
walpen
11
Bem, aqui está um compilador unário ao C que funciona bem com caracteres nulos: ideone.com/MIvAg . É claro que o arquivo necessário para criar este programa não se encaixaria no universo, mas temos a capacidade de executá-lo.
walpen
3
Se você não pode realmente executá-lo, não é realmente uma solução.
Polinomial
4
Como Carl Sagan disse uma vez: "Se você deseja calcular o peso de uma corda, primeiro deve inventar 10 ^ 500 universos". (bilhões e bilhões, até)
walpen
4

C, peso 322 263 256

O peso do hamming conta?

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

Utilizado principalmente técnicas de golfe padrão.
Um único loop calcula o peso (deslocando para a direita e adicionando até zero) e varre a string (avança o ponteiro quando o zero é atingido).
Supondo que Dseja inicializado como 2 (parâmetro único).

Otimizações específicas de peso de Hamming:
1. ABDH, com peso 2 cada, usadas para nomes.
2. *++Hpreferido sobre H[1].

Ugoren
fonte
Hah, não consegui entender sua primeira frase até agora.
breadbox
Você pode obter o baixo score de 230 emitindo o resultado como um unário número:main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
schnaader
@ Schnaader, eu nunca soube que @era um dígito no sistema unário. Eu pensei que ele só usa 0.. 0. Mas se você quiser ir por esse caminho, printf("@"+*a%2)é mais curto.
ugoren
@ugoren: Depende da convenção / definição de unário. Por exemplo, en.wikipedia.org/wiki/Unary_numeral_system usa marcas de registro e diz "Não há símbolo explícito representando zero em unário, como em outras bases tradicionais".
schnaader
@ Schnaader, OK, mas acho que está ampliando demais o requisito "como número".
ugoren
4

Golfscript 84 72 58

{2base~}%{+}*

(obrigado a Howard e Peter Taylor pela ajuda)

Entrada: a sequência de entrada deve estar na pilha (passada como argumento da linha de comando ou simplesmente colocada na pilha).

Caso você o execute na linha de comando, certifique-se de usá-lo echo -n; caso contrário, a nova linha à direita também será contada.

Saída: imprime o valor do peso hamming no console

O programa pode ser testado aqui .

Cristian Lupascu
fonte
11
O Golfscript diferencia maiúsculas de minúsculas? Caso contrário, você pode salvar alguns bits usando em BASEvez de base. Atualização: Apenas marcada, BASEnão funciona. Boa solução :) #
789 Polynomial
@ Polynomial Eu tentei isso depois de ver o seu TEST/ testcomment :) Mas isso não funciona.
Cristian Lupascu
Você pode se livrar {...}2*aplicando 2base~em primeiro lugar. Se marcar até 72.
Howard
@ Howard obrigado por esta ótima dica! Eu apliquei na minha resposta.
Cristian Lupascu
Seu mecanismo de teste está errado, porque você esqueceu uma limitação importante da sua página Web GolfScript. Você deve ter um ;antes da string que substitui por stdin, de modo que isso (;é desnecessário. Em seguida, a observação de Howard recebe-lo para baixo para 65.
Peter Taylor
2

Perl, 80 (22 caracteres)

Feito e feito:

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

Ou aqui está uma versão alternativa com um peso de 77 (21 caracteres):

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

Mas não gosto muito dessa versão, porque sua saída omite a nova linha final.

Para calcular o peso, estou assumindo que estou contando caracteres da maneira usual (excluindo o perl -e/ -E, mas incluindo outros caracteres de opção). Se, por algum motivo, as pessoas reclamarem disso, o melhor que posso fazer sem opções é 90 (26 caracteres):

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

Uso da amostra:

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

Estrondo.

caixa de pão
fonte
2

Pitão - 15

Exoneração de responsabilidade: Esta resposta não é elegível para ganhar, pois Pyth é mais jovem que esse desafio.

Usa .Bpara representação binária e conta o número de "1"'s.

/.BQ\1

Recebe entrada em uma string para economizar em zversus Q.

Experimente online aqui .

Maltysen
fonte
1

Scala 231

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

Código Selestesting:

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

com modificação de autoteste.

Usuário desconhecido
fonte
É o peso 495, não 231. Você não pode obter o peso 231 com 126 caracteres - isso é uma média inferior a 2, e todos os caracteres imprimíveis (exceto o @espaço, que você não usa) têm pelo menos peso 2.
Ugoren
11
@ugoren: Mas são apenas 65 caracteres. O programa é impresso quase duas vezes: uma vez o código para calcular o peso do hamming e uma segunda vez como entrada estática para calculá-lo para o programa. Mas a parte do cálculo está faltando o "readLine ()" na frente, porque recebe a entrada literal. Eu tentei esclarecer a resposta em si.
usuário desconhecido
1

Java, peso 931 774 499 454

Acho que esta é a única resposta no momento com um peso acima de 300.

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

Espera entrada como um argumento de linha de comando.

SuperJedi224
fonte
1

GNU sed -r, 467 + 1

(+1 para uso de -r- ou deve ser +4?)

Saídas como um valor unário por linha de origem; para converter para um total decimal, redirecione a saída para | tr -d "\n" | wc -c. Conta todos os caracteres ASCII imprimíveis (32-126), mais o avanço de linha (10).

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

É difícil evitar listar todos os caracteres, mas podemos reduzir isso observando que as letras minúsculas têm um peso de Hamming mais uma que as letras maiúsculas correspondentes. Preferimos nova linha (escore 2) ao ponto e vírgula (escore 5) como separador de declaração; preferimos @(pontuação 1) ou !(pontuação 2) a /(pontuação 5) como delimitador de padrões.

Nota - para obter os conjuntos corretos de caracteres, criei esta tabela a partir da tabela man ascii, classificada por peso. Basta adicionar as pontuações à direita e abaixo para obter o peso total de cada personagem:

   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

Isso pode ser útil para outras pessoas.

Toby Speight
fonte
0

Julia 262 268

A versão modificada utiliza a útil função 'count_ones' para economizar 6 (262)

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

Versão antiga, sem a função de contagem única incorporada (268)

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

Usa argumento de linha de comando para entrada.

Bakerg
fonte
0

CJam 52 ou 48

Se a entrada ainda não estiver na pilha (52)

q:i2fbs:s:i:+

Se a entrada estiver na pilha (48)

:i2fbs:s:i:+

Por exemplo

"Hello World":i2fbs:s:i:+
Bakerg
fonte
0

Julia, HW 199

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

Com

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

ou inserindo diretamente a string:

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

A versão ungolfed (HW 411) tem a seguinte aparência:

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

E, por diversão, aqui está uma versão otimizada (Hamming Weight 231 ) da opinião da bakerg sobre o problema:

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

com

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

HPPPL (Linguagem de programação HP Prime), 74

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

A calculadora gráfica HP Prime possui uma função hamdist () integrada. O peso de hamming de cada caractere é o mesmo que a distância de hamming de 0.

ASC (string) cria uma matriz dos valores ASCII de cada caractere em uma string.

hamdist (valor, 0) calcula a distância de hamming de 0 para cada valor ASCII

sum () resume todos os valores.

Cálculo do peso hamming do seu próprio código-fonte:

Peso de martelo HPPPL

ML
fonte
0

05AB1E , peso 17 (4 bytes )

ÇbSO

Experimente online ou verifique mais alguns casos de teste .

Explicação:

Ç       # 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
Kevin Cruijssen
fonte
0

Perl 6 , 102

+*.ords>>.base(2).comb(~1)

Experimente online!

Enquanto isso não é código de golfe, a solução mais curta também parece ter o menor peso de hamming ...

Brincadeira
fonte