... Ah lo siento, no hay palomitas de maíz aquí, solo POPCNT.
Escriba el programa o la función más corta que tome un número n
y genere todos los enteros de 0 a 2 n - 1, en orden ascendente de número de 1 bits en la representación binaria de los números (popcount). No se permiten duplicados.
El orden de los números con el mismo popcount está definido por la implementación.
Por ejemplo, para n = 3
, todos estos resultados son válidos:
0, 1, 2, 4, 3, 5, 6, 7
[0, 4, 1, 2, 5, 3, 6, 7]
0 4 2 1 6 5 3 7
El formato de entrada y salida está definido por la implementación para permitir el uso de funciones de lenguaje para mejorar el código. Hay algunas restricciones en la salida:
- Los números deben salir en formato decimal.
La salida debe contener un separador razonable entre los números (separador final permitido, pero no inicial).
Avance de línea (
\n
), pestaña (\t
), espacio,,
,.
,;
,|
,-
,_
,/
son separador bastante razonable. No me importan espacios adicionales para una impresión bonita, pero no use letras o dígitos como separadores.- Los números y separadores pueden estar rodeados por
[ ]
,{ }
o cualquier matriz o notación de lista. - No imprima nada más no mencionado anteriormente.
Prima
Multiplique su puntaje por 0.5 si su solución puede generar el número sobre la marcha. El espíritu de este bono es que si fuera a convertir directamente su solución de impresión en un generador, el generador solo usa como máximo la memoria O (n) donde n es el número de bits como se definió anteriormente. (No tiene que convertir su solución en generador). Tenga en cuenta que si bien impongo n <= 28, la memoria necesaria para almacenar todos los números aún crece exponencialmente, y una solución de clasificación ingenua acumularía al menos 4 GB de memoria en n = 28.
Agregue alguna explicación simple de cómo funciona su solución antes de reclamar este bono.
Respuestas:
Pyth, 9 bytes
o
rder por els
um de la representación de base 2 (jN2
) sobre el rango (U
) de2 ^ Q
.(
Q
=eval(input())
)Pruébalo aquí
fuente
Python 2, 75 * 0.5 = 37.5
Repetidamente genera el siguiente más alto
v
con el mismo POPCOUNT por este algoritmo de giro de bits .En realidad, resultó más fácil generarlos disminuyendo el conteo de pops, luego imprimió el complemento para aumentarlo. De esa forma, luego se
v
desborda2**n
, simplemente eliminamos todos losn
bits, excepto&N
dondeN=2**n-1
, y eso le da al popcount número uno más pequeño más bajo. De esa manera, solo podemos hacer un bucle. Probablemente haya una mejor solución que encuentre directamente el siguiente número más bajo con el mismo POPCOUNT.Debido a un problema de poste de la cerca, necesitamos comenzar
v=2**(n+1)-1
para que la operación produzcav=N-1
en el primer bucle.Salida para
4
:fuente
console.log()
vsprint
). Tal vez el truco es demasiado pesado.v=N-~N
J, 19 caracteres, sin bonificación.
2 ^ y
- dos al poder dey
.i. 2 ^ y
- los enteros de0
a(2 ^ y) - 1
.#: i. 2 ^ y
- cada uno de estos enteros representados en la base dos.+/"1 #: i. 2 ^ y
- las sumas de cada representación(i. 2 ^ y) /: +/"1 #: i. 2 ^ y
- el vectori. 2 ^ y
ordenado por el orden de los elementos del vector anterior, nuestra respuesta.fuente
Python, 63 caracteres
fuente
C 179 * 0.5 = 89.5
EDITAR: 157 * 0.5 = 78.5
EDITAR: 132 * 0.5 = 66
o un poco mejor formateado:
¿Que hace?
calcula el último número para mostrar (pow (2, n) - 1)
el bucle externo itera sobre el recuento de bits (de 0 a n-1) mientras que el bucle interno solo cuenta de 0 a m
En x86 existe la instrucción POPCNT que se puede usar para contar los bits establecidos. GCC y los compiladores compatibles pueden admitir la función __builtin_popcount que básicamente compila esa instrucción.
fuente
CJam, 13 bytes
Implementación bastante sencilla.
Cómo funciona :
Pruébalo en línea aquí
fuente
Mathematica,
5046.
fuente
JavaScript (ES6) 41 (82 * 0.5)
La forma más simple, golf
Sin golf
Prueba en la consola Firefox / FireBug
fuente
Bash + coreutils, 66
Uno para comenzar:
fuente
sort
lleva mucho tiempo. Con n = 28,sort
necesitará ordenar 2 ^ 28 líneas / ~ 13GB de datos.Haskell, (87 * 0.5) = 43,5
Ejemplo de uso:
f 4
que genera[0,1,2,4,8,3,5,9,6,10,12,7,11,13,14,15]
Cómo funciona: sin ordenar ni iterar repetidamente sobre [0..2 ^ n-1] y buscar números que contengan i 1s.
Las
#
funciones auxiliares toman dos parámetrosa
yb
construyen una lista de cada número compuesto pora
1s yb
0s. La función principalf
requiere#
cada combinación dea
yb
dondea+b
es igualn
, comenzando sinn
números 1 y 0 para tener los números en orden. Gracias a la pereza de Haskell, todas esas listas no tienen que construirse completamente en la memoria.fuente
++
dea#b
media que necesita el lado izquierdo (que podría ser grande) que se produce por completo y luego se copia antes de que se produjo el primer elemento en el resultado, violando de esta manera los requisitos para la bonificación?Ruby 47 caracteres
Al igual que Python de @KeithRandall:
fuente
Mathematica, 26
Ejemplo:
fuente
Perl, 64/2 = 32
Simplemente iterar sobre los
[0..2^n-1]
n + 1
tiempos de rango . En cada iteración imprima solo los números que tienen un número de 1 bits igual a la variable de iteración ($i
). Los bits se cuentan contando1
(y/1//
) en el número convertido a cadena binaria consprintf
.Prueba a .
Perl, 63
Enfoque de clasificación:
fuente
Java 8, 205
fuente
C ++ 11, 117 caracteres:
Sin golf:
Explicación:
Crea un conjunto de pares int, int. El primer int es el recuento de bits, el segundo es el número. Los pares se comparan según su primer parámetro, por lo que el conjunto se ordena por conteo de bits.
fuente