Calcule el peso de hamming con bajo peso de hamming

19

Cree un programa que calcule el peso de una cadena. El ganador es el programa con el menor peso de hamming.

Reglas:

  • El peso de Hamming para un carácter ASCII se define como el número total de bits establecido 1en su representación binaria.
  • Suponga que la codificación de entrada es ASCII de 7 bits, se pasa a través de cualquier mecanismo de entrada que sea normal para su idioma (por ejemplo, stdin, args, etc.)
  • Envíe el resultado, como un número, a stdout o cualquier mecanismo de salida predeterminado / normal que utilice su idioma.
  • Debería ser evidente, pero debe ser capaz de ejecutar el programa, en la vida real, para que sea una solución válida.
  • Winner es la solución cuyo código tiene el menor peso de hamming.
  • Lo sentimos, no hay soluciones en espacios en blanco para este! Ok, puedes codificar en espacios en blanco ahora que he resuelto las reglas :)

Ejemplos por personaje:

char |  binary  | weight
-----+----------+-------
a    | 01100001 | 3
x    | 01111000 | 4
?    | 00111111 | 6
\x00 | 00000000 | 0
\x7F | 01111111 | 7
Polinomio
fuente
si tomamos 0x20/ ASCII 32 como referencia, ¿no es el zumbido de hello world10 en lugar de 11?
Cristian Lupascu
¿Por qué es el peso de hello world11? Solo 10 caracteres son diferentes de un espacio. Además, el peso de Hamming de un programa parece ser solo su longitud, excluyendo espacios. No es tan diferente del código normal de golf.
ugoren
Lo siento, lo arruiné totalmente. El artículo de Wikipedia sobre el peso pesado es bastante engañoso, y fubaré totalmente las reglas. Reescribiendo ahora. Actualización: Ok, reescrito para definirlo como el número de bits establecido en 1 en la cadena ASCII, perdón por el error.
Polinomial
@ugoren Una solución con caracteres ASCII de menor valor tiene un peso de hamming menor.
Polinomial
1
Ahora todo tiene sentido. Utiliza mayúscula, GUARDA de ~Y o.
ugoren

Respuestas:

6

J (33)

¡Uno más bajo que 34!

+/,#:3 u:

Muy inspirado por esta respuesta , pero con un peso de uno más bajo.

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

J, peso 34

+/,#:a.i.

Uso: coloque la cadena que se medirá entre comillas al final:

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

Alternativamente, tomando la entrada del teclado (peso 54):

   +/,#:a.i.1!:1[1
hello
21
Gareth
fuente
Solo hay una forma de escribir esto :)
ephemient
No hay ... Encontré una solución que tiene un peso inferior a uno.
Junıʇǝɥʇuʎs
No trato de ser un buzzkill, pero las reglas piden un programa, no un fragmento.
FUZxxl
5

J , 39

+/,#:a.i:]

Esta es una función que toma un argumento. (O reemplace ]con la cadena directamente; como señala Gareth, eso reduce el costo a 34).

   + /, #: ai:] 'hola mundo'
45
   + /, #: ai:] '+ /, #: ai:]'
39
efímero
fuente
Grandes mentes piensan igual. :-)
Gareth
5

Pitón, 189

print sum(bin(ord(A)).count("1")for A in raw_input())
Keith Randall
fuente
2
El equivalente de Python 3 print(sum(bin(ord(A)).count('1')for A in input())), tiene una puntuación de 180.
dan04
44
@ dan04: Use comillas dobles en lugar de simples 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

El tipo de herramienta adecuada para el trabajo, todavía apesta, por supuesto.

dejó de girar en sentido antihorario
fuente
1
+1 por usar uno de mis idiomas favoritos de todos los tiempos. Es el primer idioma que aprendí a codificar en una PC.
Polinomial
5

Unario 0

Todos sabían que se acercaba. Primero el programa BrainFuck:

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

Agregué nuevas líneas para que sea "legible", pero tiene un peso de Hamming de 4066. Funciona al obtener repetidamente el cociente / restos de una cadena de entrada y sumar todos los restos. Por supuesto, si lo ejecuta en sí mismo, obtiene: 226 (4066% 256) (técnicamente \ xe2) tan claramente que se declara ganador.

Ahora lo convertimos a Unary y obtenemos

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

Utilizamos una implementación unaria con caracteres NULL \ x00 para '0' y boom, con un peso de 0.

Pregunta adicional : ¿Para qué caracteres ASCII cpuede ejecutar este programa en una cadena que consiste en Nrepeticiones y hacer que emita ese carácter? (Por ejemplo, una cadena de 32 espacios da un espacio). Qué valores de Ntrabajo (un número infinito de ellos funcionará o ninguno lo hará).

Walpen
fuente
1
No estoy seguro de entender esta solución. El programa Brainfuck tiene un enorme peso de hamming. ¿Unary acepta bytes nulos como programa, o necesitaría volver a implementar Unary? Si es lo último, no es realmente una solución válida: cualquiera podría decir "Defino un lenguaje de programación donde cualquier byte de entrada da {resultado}" y gana todos los desafíos de código de golf en el sitio.
Polinomial
1
Un personaje nulo Unary estaría bien. Todo lo que necesitas es un EOF para decir que dejes de contar. De hecho, aquí hay algunos pseudo-C para leer ese archivo: main(){ bignum Unarynum = 0; int c; while(EOF!=(c=readchar())){ Unarynum++; } return Unarynum; }no importa en absoluto lo que elijas ser tu personaje Unary (siempre que no sea EOF).
walpen
1
Bueno, aquí hay un compilador unario para C que funciona bien con caracteres nulos: ideone.com/MIvAg . Por supuesto, el archivo requerido para hacer este programa no encajaría en el universo, pero tenemos la capacidad de ejecutarlo.
walpen
3
Si realmente no puede ejecutarlo, no es realmente una solución.
Polinomial
44
Como dijo una vez Carl Sagan : "Si desea calcular el peso de una cuerda, primero debe inventar 10 ^ 500 universos". (miles de millones, incluso)
walpen
4

C, peso 322 263 256

¿Cuenta el peso de hamming del peso de hamming?

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 golf estándar.
Un solo bucle calcula el peso (desplazando a la derecha y sumando hasta cero) y escanea la cadena (avanza el puntero cuando llega a cero).
Suponiendo que Dse inicializa a 2 (parámetro único).

Optimizaciones específicas del peso de Hamming:
1. ABDH, con un peso de 2 cada uno, utilizado para los nombres.
2. *++Hpreferido sobre H[1].

Ugoren
fuente
Hah, no entendí completamente tu primera oración hasta ahora.
breadbox
Puede obtener el puntaje hasta 230 enviando el resultado como un número unario :main(D,H,A)char*A,**H;{for(A=*++H;*A;A+=!(*A/=2))if(*A%2)printf("@");}
schnaader
@schnaader, nunca supe que @había un dígito en el sistema unario. Pensé que sólo utiliza 0.. 0. Pero si quieres ir de esta manera, printf("@"+*a%2)es más corto.
ugoren
@ugoren: Depende de la convención / definición de unario. Por ejemplo, en.wikipedia.org/wiki/Unary_numeral_system usa marcas de conteo y dice "No hay un símbolo explícito que represente cero en unario como lo hay en otras bases tradicionales".
schnaader
@schnaader, está bien, pero creo que está extendiendo el requisito "como un número" demasiado lejos.
ugoren
4

Golfscript 84 72 58

{2base~}%{+}*

(gracias a Howard y Peter Taylor por su ayuda)

Entrada: la cadena de entrada debe estar en la pila (pasada como argumento de línea de comando, o simplemente colocada en la pila).

En caso de que lo ejecute desde la línea de comando, asegúrese de usarlo echo -n; de lo contrario, la nueva línea final también se contará.

Salida: imprime el valor del peso de hamming en la consola

El programa se puede probar aquí .

Cristian Lupascu
fuente
1
¿Golfscript distingue entre mayúsculas y minúsculas? De lo contrario, puede guardar algunos bits utilizando en BASElugar de base. Actualización: Acabo de marcar, BASEno funciona. Buena solución :)
Polynomial
@Polynomial Lo intenté después de ver tu TEST/ testcomentario :) Pero no funciona.
Cristian Lupascu
Puede deshacerse {...}2*aplicando 2base~en primer lugar. Obtiene un puntaje de 72.
Howard
@Howard gracias por este gran consejo! Lo apliqué en mi respuesta.
Cristian Lupascu
Su mecanismo de prueba es incorrecto, porque ha olvidado una limitación importante de su página Web GolfScript. Debería tener un ;antes de la cadena que sustituye por stdin, por lo que (;es innecesario. Luego, la observación de Howard lo reduce a 65.
Peter Taylor
2

Perl, 80 (22 caracteres)

Hecho y hecho:

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

O aquí hay una versión alternativa con un peso de 77 (21 caracteres):

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

Sin embargo, no me gusta mucho esa versión porque su salida omite la nueva línea final.

Para calcular el peso, supongo que estoy contando caracteres de la manera habitual (excluyendo perl -e/ -E, pero incluyendo otros caracteres de opción). Si por alguna razón la gente se queja de esto, lo mejor que puedo hacer sin opciones es 90 (26 caracteres):

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

Uso de la muestra:

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

Auge.

caja de pan
fuente
2

Pyth - 15

Descargo de responsabilidad: esta respuesta no es elegible para ganar ya que Pyth es más joven que este desafío.

Utiliza .Bpara la representación binaria y cuenta el número de "1"'s.

/.BQ\1

Toma entrada en una cadena para guardar en zversus Q.

Pruébelo en línea aquí .

Maltysen
fuente
1

Scala 231

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

Código de autocomprobación:

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

con modificación de autocomprobación.

usuario desconocido
fuente
Tiene un peso de 495, no de 231. No puede obtener el peso de 231 con 126 caracteres, eso es un promedio de menos de 2, y todos los caracteres imprimibles (excepto el @espacio, que no usa) tienen un peso de 2 al menos.
ugoren
1
@ugoren: Pero solo son 65 caracteres. El programa se imprime casi dos veces: una vez el código para calcular el peso de hamming, y una segunda vez como entrada estática para calcularlo para el programa. Pero a la parte calculadora le falta el "readLine ()" al frente, porque toma la entrada literal. Traté de aclarar la respuesta en sí.
usuario desconocido
1

Java, peso 931 774 499 454

Creo que esta es la única respuesta en este momento con un peso de más de 300.

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

Espera entrada como argumento de línea de comando.

SuperJedi224
fuente
1

ÑU sed -r , 467 + 1

(+1 para uso de -r- ¿o debería ser +4?)

Salidas como un valor unario por línea de origen; para convertir a un total decimal, redirija la salida a | tr -d "\n" | wc -c. Cuenta todos los caracteres ASCII imprimibles (32-126), más el salto de línea (10).

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

Es difícil evitar enumerar todos los caracteres, pero podemos reducir esto observando que las letras minúsculas tienen un peso de Hamming de uno más que las letras mayúsculas correspondientes. Preferimos nueva línea (puntaje 2) sobre punto y coma (puntaje 5) como separador de enunciados; preferimos @(puntaje 1) o !(puntaje 2) sobre/ (puntaje 5) como delimitador de patrón.

Nota: para obtener los conjuntos de caracteres correctos, creé esta tabla a partir de la una man ascii, ordenada por peso. Simplemente agregue los puntajes correctos e inferiores para obtener el peso total de cada personaje:

   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

Esto podría resultar útil para otros.

Toby Speight
fuente
0

Julia 262 268

La versión modificada utiliza la práctica función 'count_ones' para ahorrar 6 (262)

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

Versión antigua que no utiliza una función de conteo integrada (268)

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

Utiliza el argumento de la línea de comando para la entrada.

Bakerg
fuente
0

CJam 52 o 48

Si la entrada aún no está en la pila (52)

q:i2fbs:s:i:+

Si la entrada está en la pila (48)

:i2fbs:s:i:+

Por ejemplo

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

Julia, HW 199

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

Con

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

o insertando directamente la cadena:

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

La versión sin golf (HW 411) se ve así:

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

Y por diversión, aquí hay una versión optimizada (Hamming Weight 231 ) del enfoque de Bakerg sobre el problema:

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

con

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

HPPPL (lenguaje de programación HP Prime), 74

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

La calculadora gráfica HP Prime tiene una función incorporada hamdist (). El peso de hamming de cada personaje es el mismo que la distancia de hamming desde 0.

ASC (cadena) crea una matriz de los valores ASCII de cada carácter en una cadena.

hamdist (valor, 0) calcula la distancia de hamming desde 0 para cada valor ASCII

sum () resume todos los valores.

Cálculo del peso de hamming de su propio código fuente:

Hamming Weight HPPPL

ML
fuente
0

05AB1E , peso 17 (4 bytes )

ÇbSO

Pruébalo en línea o verifique algunos casos de prueba más .

Explicación:

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

Perl 6 , 102

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

Pruébalo en línea!

Si bien este no es el código de golf, la solución más corta también parece tener el menor peso de hamming ...

Jo King
fuente