Números mágicos de popcount


25

Hay un famoso algoritmo complicado para contar el número de bits establecidos en un entero sin signo de 32 bits:

int popcount(unsigned x) {
   x = (x & 0x55555555) + ((x >> 1) & 0x55555555);
   x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
   x = (x & 0x0F0F0F0F) + ((x >> 4) & 0x0F0F0F0F);
   x = (x & 0x00FF00FF) + ((x >> 8) & 0x00FF00FF);
   x = (x & 0x0000FFFF) + ((x >>16) & 0x0000FFFF);
   return x;
}

No lo explicaré aquí. ¡Pero imagine un código similar para enteros de 512 bits! Las constantes hexadecimales serían enormes y formarían un bonito patrón. Su tarea es simplemente imprimir esta salida exacta :

0x55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
0x33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f
0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff
0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff
0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff
0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff
0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000ffffffffffffffffffffffffffffffff
0x0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Sin espacios finales, por favor, aunque una nueva línea final es opcional.

Este es el , por lo que gana la respuesta más corta (en bytes).


¿Se nos permite tomar entradas (como en algo como 0x0x0x0x0x0x0x0x0x)?
ouflak

@ouflak No. ———
Lynn

Respuestas:


3

05AB1E , 26 22 21 bytes

05AB1E usa la codificación CP-1252 .

9F„0x0NÍo×9ooNoo>÷hJ,

Pruébalo en línea!

Explicación

9F                      # for N in [0 ... 8]
  „0x                   # push the string "0x"
     0NÍo×              # push 2**(N-2) zeroes
          9oo           # 2**2**9
                 ÷      # //
             Noo>       # (2**2**N+1)
                  h     # converted to base-16
                   J    # join everything to string
                    ,   # print with a newline

Otras versiones que podrían mejorarse

9F9ooNoo>÷h¾6o×J7o£R…0xÿ,
9F9ooNoo>÷h0žy×ìR7o£R…0xÿ,
9FX0No×1No×JCh7o×1K7o£…0xÿ,
8ÝovX0y×1y×JCh7o×1K7o£…0xÿ,
9F1NoÅ0D>)˜JCh1K7o×7o£…0xÿ,

21

Python 2, 52 49 46 bytes

El késimo número viene dado por 2**512/(2**2**k + 1). Esto es para un número de 512 bits, por lo que es trivial extender el patrón a diferentes anchos.

l=2;exec"print'0x%0128x'%(2**512/-~l);l*=l;"*9

3 bytes guardados gracias a Dennis.
3 bytes guardados gracias a xnor.


2
Las ventajas de los enteros de precisión arbitraria ...
ETHproductions

Agradable. Esto ahorra algunos bytes.
Dennis

Más corto para seguir cuadrando:l=2;exec"print'0x%0128x'%(2**512/-~l);l*=l;"*9
xnor

1
Me calienta el corazón ver a Python en la delantera :)
Tobias Kienzler

44
@TuukkaX Solo tengo mucha experiencia con trucos poco retorcidos. Utilicé mucho Wolfram Alpha para simplificar sumas y demás. Pero, básicamente, hice el patrón 01010101, 00010001, 00000001, y luego se multiplica por aquellos 1, 11, 1111para obtener los patrones binarios correctos. Por ejemplo 01010101, puede obtener la fórmula para un cierto ancho w haciendo sum 2^(2*k) for k = 0, w/2 - 1y descubriendo que es (2**w - 1)/3.
orlp

7

PHP, 111 110 108 bytes

Un byte guardado gracias a @ user59178.

<?=($p=str_pad)("0x",130,5).$p($s="\n0x",131,3);for($x=1;$x<65;$x*=2)echo($p($s,131,$p(0,$x,0).$p(f,$x,f)));

¿Cuál es el patrón para 1024 bits? :RE


1
Puede guardar un byte utilizando en $x<65lugar de $i++<7. Esta vez lo probé y todo.
user59178

6

Retina , 43 bytes

:`
0x128$*5
:`5
3
;{:`33
0f
0(f+)(0+)
0$2$1

Pruébalo en línea!

Explicación

Esto hace mucho uso de la :opción generalmente infrautilizada que le permite imprimir resultados intermedios, porque es mucho más corto modificar una sola línea que generar toda la salida.

:`
0x128$*5

Esto reemplaza la entrada vacía con 0xseguida de 128 5sy la imprime para generar la primera línea.

:`5
3

Éste reemplaza la 5s con 3s para generar la segunda línea y también la imprime.

;{:`33
0f

Esta es la última línea con mayúsculas especiales y se convierte cada dos 3s 0fpara generar la tercera línea. Esto también inicia un ciclo a través de las últimas dos etapas ( {). Sin embargo, esta etapa no hará nada después de la primera iteración, excepto imprimir el estado actual. Los ;suprime la salida al final del programa para evitar la duplicación de la última línea.

0(f+)(0+)
0$2$1

Esta sustitución ahora transforma cada línea en la siguiente, intercambiando cualquier otro par de fsy 0s. La condición de "cualquier otro par" se aplica haciendo coincidir un cero delante del f, lo que hace que sea imposible hacer coincidir pares consecutivos ya que las coincidencias no pueden superponerse.


6

Vim, 32 bytes

i5<CR>3<Esc>qqYpVrf$<C-V>{yPG1vr0q6@q<C-V>{I0x<Esc>

Solo necesito escribir manualmente el primero 5y 3, y la macro se encarga del resto, "duplicando el conteo de bits" cada vez que se ejecuta. El orden de los pasos en la macro es un poco extraño (hacer una nueva flínea, copiar en bloque, reutilizar el tamaño del bloque visual para poner 0s en la flínea), pero es la variante más rápida que he encontrado.


5

Pyth, 26 bytes

V9%"0x%0128x"/^2 512h^2^2N

Puerto de mi respuesta de Python.


5

J, 46 34 bytes

Estoy trabajando en esto, pero a este bebé le gusta quedarse en 46 bytes ... ¡Ya no! -12 bytes gracias a millas!

'0x',"1'5','3','0f'(128$#)"{~2^i.7

Pruébalo en línea! :RE

Resultado

   '0x',"1'5','3','0f'(128$#)"{~2^i.7
0x55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
0x33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f
0x00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff
0x0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff
0x00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff00000000ffffffff
0x0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff0000000000000000ffffffffffffffff
0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff00000000000000000000000000000000ffffffffffffffffffffffffffffffff
0x0000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff

Para esta respuesta, necesitaba (idealmente) un verbo con rango 0 1para usarlo en la u"vdefinición de rango; sin embargo, millas observaron que 0 _era suficiente para la tarea en cuestión.

┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬──┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│= │< │<.│<:│> │>.│>:│+ │+.│+:│* │*.│*:│_ 0 0│_ 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│0 0 0│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│- │-.│-:│% │%.│%:│^ │^.│$ │$.│$:│~.│~:│0 0 0│0 _ _│0 _ _│0 0 0│2 _ 2│0 0 0│0 0 0│0 0 0│_ 1 _│_ _ _│_ _ _│_ 0 0│_ 0 0│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│| │|.│, │,.│,:│; │;:│# │#.│#:│! │/:│\:│0 0 0│_ 1 _│_ _ _│_ _ _│_ _ _│_ _ _│1 _ _│_ 1 _│1 1 1│_ 1 0│0 0 0│_ _ _│_ _ _│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│[ │[:│] │{ │{.│{:│}.│}:│".│":│? │?.│a │_ _ _│_ _ _│_ _ _│1 0 _│_ 1 _│_ 0 0│_ 1 _│_ 0 0│1 _ _│_ 1 _│0 0 0│_ 0 0│_ _ _│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│A │A.│b │C │C.│d │D │e │e.│E │E.│f │H │_ _ _│1 0 _│_ _ _│_ _ _│1 1 _│_ _ _│_ _ _│_ _ _│_ _ _│_ _ _│0 _ _│_ _ _│_ _ _│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│i │i.│i:│I │I.│j │j.│L │L.│M │o │o.│p │_ _ _│1 _ _│0 _ _│_ _ _│1 _ _│_ _ _│0 0 0│_ _ _│_ 0 0│_ _ _│_ _ _│0 0 0│_ _ _│
├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼──┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│p.│p:│q │q:│r │r.│s │s:│S │t │T │u:│x:│1 1 0│0 _ _│_ _ _│0 0 0│_ _ _│0 0 0│_ _ _│_ _ _│_ _ _│_ _ _│_ _ _│_ _ _│_ _ _│
└──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴──┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘

Aquí puede ver un montón de representaciones de cadenas de verbos con sus respectivos rangos. Este es el script que usé para generarlo.


Un verbo con rango 0 _está bien aquí. Puede acortarlo a 34 bytes con'0x',"1'5','3','0f'(128$#)"{~2^i.7
millas del

@miles Huh. Pensé que lo había intentado ... ¡genial! y olvidé la función de relleno automático de filas de J, ¡gracias de nuevo!
Conor O'Brien

4

En realidad , 25 bytes

9r`╙╙u9╙╙\#"0x%0128x"%`Mi

Pruébalo en línea!

Esta solución utiliza el hecho de que f(n) = 2**512//(2**2**n + 1)(donde //se divide la división) para compilar los valores.

Explicación:

9r`╙╙u9╙╙\#"0x%0128x"%`Mi
9r`╙╙u9╙╙\#"0x%0128x"%`M   for n in range(1, 10):
      9╙╙\                   2**2**9//
   ╙╙u                                (2**2**n + 1)
          #"0x%0128x"%       pad with zeroes to 128 digits, prefix with "0x"
                        i  flatten and implicitly print

4

JavaScript (Firefox 30+), 139 113 112 92 83 80 bytes

_=>[for(x of"970123456")(f=y=>y--?f(y)+(x>6?x-4:y>>x&1&&'f'):'0x')(128)].join`
`

Finalmente golpee el punto dulce recursivo :-) Utiliza una comprensión de cadena práctica y elegante para guardar 3 bytes en .map:

_=>[..."970123456"].map(x=>(f=y=>y--?f(y)+(x>6?x-4:y>>x&1&&'f'):'0x')(128)).join`
`

.replace también tiene 83 bytes:

_=>"970123456".replace(/./g,x=>(f=y=>y--?f(y)+(x>6?x-4:y>>x&1&&'f'):'0x')(128)+`
`)

Si se permitiera una nueva línea principal, esto también sería de 80 bytes:

_=>"970123456".replace(/./g,x=>(f=y=>y--?f(y)+(x>6?x-4:y>>x&1&&'f'):`
0x`)(128))


3

Chicle , 65 bytes

00000000: c5cb 4501 0441 1043 d17b d4fc 254b d110  ..E..A.C.{..%K..
00000010: f7cb 9761 9e7a 8d45 e451 4ce4 564c 04d7  ...a.z.E.QL.VL..
00000020: 2e11 b02b 8f08 80df aa5e 11fe fc77 762c  ...+.....^...wv,
00000030: 428b 5b8e ae8b 30c1 13b6 ce8b b091 377a  B.[...0.......7z
00000040: 01                                       .

Respuesta obligatoria de Bubblegum.


3

Haskell, 84 72 bytes

Portar la respuesta de @ orlp:

import Text.Printf
mapM(\n->printf"0x%0128x\n"$div(2^2^9)$2^2^n+1)[0..8]

Alternativas de 94 bytes sin el poder de Text.Printf:

import Data.List
mapM(putStrLn.("0x"++))$transpose$("53"++).reverse<$>sequence(["0f"]<*[1..7])

r=[0..127]
mapM(putStrLn.("0x"++))$('5'<$r):('3'<$r):[["0f"!!mod(div x(2^y))2|x<-r]|y<-[0..6]]

@nimi whoops, debe haberse cargado Control.Monaden el REPL. Fijo.
Angs

3

PowerShell v2 +, 68 bytes

5,3|%{"0x"+"$_"*128}
($a=1)..7|%{"0x"+('0'*$a+'f'*$a)*(128/($a*=2))}

PowerShell no tiene enteros de precisión arbitrarios sin usar [bigint]llamadas, y esos no se pueden convertir fácilmente a hexadecimales, por lo que en su lugar estamos tratando esto como un desafío basado en cadenas.

La primera línea maneja la repetición 5y 3simplemente haciendo una multiplicación de cadena a los 128caracteres y clavando una 0xen el frente.

La siguiente línea recorre de $a=1a 7, cada iteración genera otra cadena. Una vez más, tenemos la 0xtachuela al frente, y estamos haciendo una multiplicación de cuerdas en el medio para construir el número apropiado 0y fconcatenado juntos, y luego haciendo la multiplicación de cadenas de eso al número apropiado de caracteres. Tenga en cuenta que estamos usando variables $aaquí, y no el contador de bucles $_, por lo que podemos escalar correctamente (de lo contrario, tendríamos que hacer un bucle como 1,2,4,8,16,32,64|%{...}, que es más largo).

Las cadenas resultantes se dejan en la tubería, y la salida por vía implícita Write-Outputocurre al finalizar el programa, con una nueva línea entre los elementos.


3

V , 43 bytes

64i0fòYpÓ¨¨0«©¨f«©©û2}/²²³³òdd{3ÄÒ5jÒ3Îi0x

Pruébalo en línea!

Utiliza una de las expresiones regulares comprimidas más largas que he necesitado en una respuesta V. Aquí está la versión más legible, donde agregué un byte para expresiones regulares legibles y cambié el carácter de escape no imprimible a<esc>

64i0f<esc>òYpÓö((0+)(f+)){2}/²²³³òdd{3ÄÒ5jÒ3Îi0x

Explicación (usando la versión legible):

64i0f<esc>                                          " Insert 64 "0f"s and escape to normal mode
          ò                      ò                  " Recursively:
           Yp                                       "   Duplicate this line
             Ó                                      "   Substitute:
              ö                                     "     (Optionally Turn the readable version on)
               ((0+)(f+))                           "     One or more '0's followed by one or more 'f's
                         {2}                        "     Repeated twice
                            /                       "   With:
                             ²²                     "     The second capture group twice (the '0's)
                               ³³                   "     Followed by the third capture group twice (the 'f's)
                                                    "   Once the search is not found, the loop will break
                                  dd                " Delete a line (because we have one too many)
                                    {               " Move to the first line
                                     3Ä             " Make three copies of this line
                                       Ò5           " Replace the first one with '5's
                                         jÒ3        " Move down a line and replace the second with '3's
                                            Î       " On every line:
                                             i0x    "   Insert a '0x'

3

JavaScript (ES6), 74 72 70 bytes

Incluye la nueva línea final opcional.

f=(i=1152)=>i--?f(i)+(i&127?'':`
0x`)+('53'[y=i>>7]||i&1<<y-2&&'f'):''


2

Pyth - 31 30 bytes

Para obtener el patrón, excepto los 3's y 5' s, se reduce acumulativamente, duplicando cada vez los trozos.

jm+"0x".[dd128+`3+`5.u.iNN6"0f

Pruébelo en línea aquí .


2

Lote, 216 bytes

@echo off
set s=5
call:c
set s=3
call:c
set a=0
set b=f
for /l %%i in (1,1,7)do call:l %%i
exit/b
:l
set s=%a%%b%
:c
for /l %%j in (0%1,1,6)do call set s=%%s%%%%s%%
echo 0x%s%
set a=%a%%a%
set b=%b%%b%

2

Vim 72 bytes

i0x128a5Ypll128r3o0x64a0fa0Ypqqffdt0fft0p@qq@qqwYp@qq@w@w@w@w:%s/0$

TryItOnline!

No imprimibles

i0x^[128a5^[Ypll128r3o0x^[64a0f^[a0^[Ypqqffdt0fft0p@qq@qqwYp@qq@w@w@w@w:%s/0$

Los 4 @ws al final me están molestando, pero debido a que confiaba en @qfallar al final de una línea, también falla el @w. Podría intentar ejecutar q 32 veces y ver si estropea las líneas posteriores.


2

C, 146 bytes

#define F for(i=0;++i<129;)s[i+1]=
#define P ;puts(s);
i,j;f(){char s[131]={'0','x'};F'5'P F'3'P for(j=1;(j*=2)<129;){F(i-1)%j<j/2?'0':'f'P}}

Sin golf:

#define F for(i=0;++i<129;)s[i+1]=
#define P ;puts(s);
i,j;f(){
  char s[131]={'0','x'};
  F'5'P
  F'3'P
  for(j=1;(j*=2)<129;){
    F(i-1)%j<j/2?'0':'f'P 
  }
}


2

brainfuck , 211 bytes

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

Pruébalo en línea!


1
197 bytes a través de algunas verificaciones de bucle diferentes. Estoy bastante seguro de que el xgenerador se puede mover fuera del circuito ahora
Jo King



1

C #, 168 bytes

()={string R="",o="0",f="f";for(int i=0,j;i<9;i++){R+="0x";if(i>2){o+=o;f+=f;}for(j=0;j<128;){R+=i<1?"5":i<2?"3":o+f;j+=i>1?(int)Math.Pow(2,i-1):1;}R+="\n";}return R;};

1

Stax , 19 bytes

⌡hÅék╝94"ºé♪╛#V┐5í╒

Ejecutar y depurarlo

Desempaquetado, sin golf y comentado, se ve así.

512r        [0..511]
{:Brm       convert each to bits and reverse each
M           transpose matrix, filling missing elements in rectangle with zero
m           map over each element of array, using the rest of the program.  outputs implicitly.
  4/        split bits into groups of 4
  {:b|Hm    convert each 4-bit binary number to single digit hex string
  .0xp      print "0x" without newline

Ejecute este


1

/// , 193 bytes

/*/\/\///X/
0x*F/5555*G/FFFF*T/3333*U/TTTT*o/0f0f*1/oooo*t/00ff*2/tttt*g/0000*h/ffff*4/ghgh*6/gghh*7/gggg*8/hhhh*9/7788/0xGGGGGGGGXUUUUUUUUX11111111X22222222X44444444X66666666X78787878X99X77988

Pruébalo en línea!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.