Imágenes binarias de recuentos de triángulos

18

Mis desafíos tienden a ser un poco difíciles y poco atractivos. Así que aquí hay algo fácil y divertido.

Secuencia de Alcuin

La secuencia de Alcuin A(n) se define contando triángulos. A(n)es el número de triángulos con lados enteros y perímetro n. Esta secuencia se llama después de Alcuin of York.

Los primeros elementos de esta secuencia, comenzando con n = 0son:

0, 0, 0, 1, 0, 1, 1, 2, 1, 3, 2, 4, 3, 5, 4, 7, 5, 8, 7, 10, 8, ...

Por ejemplo A(9) = 3, porque los únicos triángulos con lados enteros y perímetro 9son 1 - 4 - 4, 3 - 3 - 3y 2 - 3 - 4. Puedes ver los 3 triángulos válidos a continuación.

Triángulos con lados enteros y perímetro 9

Hay algunos patrones bastante interesantes en esta secuencia. Por ejemplo A(2*k) = A(2*k - 3).

Para obtener más información, consulte A005044 en OEIS.

Desafío

Pero su desafío es sobre la representación binaria de estos números. Si convertimos cada número de secuencia en su representación binaria, los colocamos en vectores de columna y los alineamos, se crea una imagen binaria bastante interesante.

En la siguiente imagen puede ver la representación binaria de los números de secuencia A(0), A(1), ..., A(149). En la primera columna puede ver la representación binaria de A(1), en la segunda columna la representación de A(1), y así sucesivamente.

Representación binaria de la secuencia de Alcuin de n = 0 a 149

Puede ver algún tipo de patrón repetitivo en esta imagen. Incluso se parece un poco a los fractales, si observa, por ejemplo, la imagen con los números de secuencia A(600), A(601), ..., A(899).

Representación binaria de la secuencia de Alcuin de n = 600 a 899

Tu trabajo es generar esa imagen. Su función, su script recibirá dos enteros 0 <= m < n, y tiene que generar la imagen binaria de la secuencia de Alcuin A(m), A(m+1), A(m+2), ..., A(n-2), A(n-1). Entonces la entrada 0, 150genera la primera imagen, la entrada 600, 900la segunda imagen.

Puede usar cualquier formato de gráficos popular que desee. Digamos que todos los formatos que se pueden convertir a png usando image.online-convert.com . Alternativamente, puede mostrar la imagen en la pantalla. ¡No se permiten filas blancas iniciales!

Este es el código de golf. Entonces gana el código más corto (en bytes).

Jakube
fuente
3
Eh, estaba interesado en hacer este desafío hasta que llegué a la parte de crear una imagen binaria. Parece un paso extraño. No tengo ganas de aprender una biblioteca para la creación de imágenes en Python, y espero que si lo hiciera, no habría mucho para el golf.
xnor
1
@xnor: Luego usa un formato de imagen simple como PBM .
Jakube
¿Es white=1 and black=0o al revés?
Maltysen
@Maltysen white=0 and black=1. Entonces al revés. A(0)produce una columna blanca, A(9)=3produce una columna blanca con 2 píxeles negros en la parte inferior.
Jakube
1
¿Estás seguro de que la primera imagen es correcta? Tiene 0,0,0,1,0,2mientras que la lista al comienzo de la pregunta dice 0,0,0,1,0,1.
Maltysen

Respuestas:

2

J ( 52 45 (página de códigos 437))

Esto estaría permitido (creo)

[:|:' █'{~[:#:[:([:<.48%~*:+24+6*]*2|])(}.i.)

Hex dump

(Nada especial en realidad, el cuadrado negro es DB 16 o 219 10 en la página de códigos 437.)

0000: 5b 3a 7c 3a 27 20 db 27 7b 7e 5b 3a 23 3a 5b 3a   [:|:' .'{~[:#:[:
0010: 28 5b 3a 3c 2e 34 38 25 7e 2a 3a 2b 32 34 2b 36   ([:<.48%~*:+24+6
0020: 2a 5d 2a 32 7c 5d 29 28 7d 2e 69 2e 29            *]*2|])(}.i.)

Uso

Esto se genera de la siguiente manera (las etiquetas de código lo confunden al agregar espacio entre las líneas):

   A=:[:|:' █'{~[:#:[:([:<.48%~*:+24+6*]*2|])(}.i.)
   0 A 100
                                                                             █ █████████████████████                                          
                                                     █ ██████████████████████ █              █ █████                          
                                     █ ██████████████ █          █ ██████████ █      █ ██████ █                   
                         █ ██████████ █      █ ██████ █    █ ████ █    █ ████ █  █ ██ █  █ ██ █  █ █  
                 █ ██████ █    █ ████ █  █ ██ █  █ ██ █  █  █  █  █  █  ██ ██ ██  ██  ██  ██  ██  ██
           █ ████ █  █ ██ █  █  █  █  ██  ██  ██  ██  ██  █  █  █  █ ██ █  █ ████ █                               
       █ ██ █  █  ██  ██  ██  █  █ ██ █                █ ██ █  █  ██  ██  ██  █  █ ██ █                                   
   █ ██ ██  ██ ██ █        █ ██ ██  ██ ██ █        █ ██ ██  ██ ██ █        █ ██ ██  ██ ██ █        █    
   2000 A 2100
████████████████████████████████████████████████████████████████████████████████████████████████████

████████████████████████████████████████████████████████████████████████████████████████████████████
                                                                             █ █████████████████████
                             █ ██████████████████████████████████████████████ █
     █ ██████████████████████ █                      █ ██████████████████████ █
█████ █          █ ██████████ █          █ ██████████ █          █ ██████████ █          █ █████████
 ████ █    █ ████ █    █ ████ █    █ ████ █    █ ████ █    █ ████ █    █ ████ █    █ ████ █    █ ███
█  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █
██  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █ ██ ██ █
 █ ██ ██ ██ ██ ██ █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  █  ██ ██ ██ ██ ██  █  █
  ██ ██ ██  █  █  ██ ██ ██  █  █  █  █  █  █  █  █  █  █  █  █  █  █ ██ ██ ██ █  █  █  █ ██ █  █ ██
 █ ██ █  █ ██ █  █ ██ █  █ ██ █  █  █  █  █  █  █  █  █  █  ██ ██ ██  █  █  ██  ██ ██ ██  ██  ██  ██
  ██  ██  ██  ██  ██  ██  ██  ██ ██ ██  █  █  █  █  █  █ ██ █  █ ██ █  █ ████ █    █ ██████ █
█ █                        █ ████ █  █ ██ █  █  █  █  ██  ██  ██  ██  ██  █  █  █  █ ██ █  █ ████ █
 █ ██ █                █ ██ █  █  ██  ██  ██  █  █ ██ █                █ ██ █  █  ██  ██  ██  █  █ █
██  ██ ██ █        █ ██ ██  ██ ██ █        █ ██ ██  ██ ██ █        █ ██ ██  ██ ██ █        █ ██ ██

En la consola J estándar, no hay espacio entre líneas, por lo que llamo a la regla 'Alternativamente, puede mostrar la imagen en la pantalla'. (En ninguna parte decía que esta imagen tenía que ser representada como un formato de imagen sensible internamente)

EDITAR: Jconsole (a diferencia de JQT) usa la página de códigos 437 como valor predeterminado, y REPRESENTA los rectángulos correctamente cuando los usa desde una cadena.

ɐɔıʇǝɥʇuʎs
fuente
9

Mathematica, 126 122 121 89 bytes

Image[1-Thread@IntegerDigits[l=Round[(#+3#~Mod~2)^2/48]&/@Range@##,2,⌈2~Log~Max@l⌉]]&

Esto define una función sin nombre que toma los dos enteros como parámetros y muestra la imagen en la pantalla. Traza cada cuadrado como un solo píxel, pero si lo desea, puede acercarlo.

Ahora estoy usando una fórmula explícita dada en el artículo de OEIS (la primera en la sección de Mathematica, gracias a David Carraher por señalarlo). También es increíblemente rápido ahora.

Aquí está el código sangrado con algunos comentarios:

Image[1-Thread@IntegerDigits[   (* 3. Convert each number to padded binary, transpose
                                      invert colours, and render as Image. *)
    l = Round[
      (#+3#~Mod~2)^2/48
    ] & /@ Range@##,            (* 1. Turn input into a range and get the Alcuin
                                      number for each element. *)
    2,
    ⌈2~Log~Max@l⌉               (* 2. Determine the maximum number of binary digits. *)
]] &

Aquí está la salida para 0, 600:

ingrese la descripción de la imagen aquí

Martin Ender
fuente
Casi del mismo tamaño (porque el techo izquierdo y derecho deben estar detallados):Image[1 - Thread@IntegerDigits[ l = Round[If[EvenQ[#], #^2, (# + 3)^2]/48] & /@ Range@##, 2, \[LeftCeiling]2~Log~Max@l\[RightCeiling]]] &
DavidC
@DavidCarraher Gracias, lo jugué un poco más. :) (Debería haber consultado el artículo de OEIS.)
Martin Ender
8

CJam ( 56 55 53 caracteres) / GolfScript (64 caracteres)

CJam:

"P1"q~,>{_1&3*+_*24+48/}%_:e>2b,\2_$#f+2fbz(,@@:~~]N*

GolfScript:

"P1"\~,>{.1&3*+.*24+48/}%.$-1=2base,\{2.$?+2base}%zip(,@@{~}/]n*

Ambos producen resultados en formato NetPBM, y son esencialmente puertos entre sí.

Disección

CJam                 GolfScript           Explanation

"P1"                 "P1"\                NetPBM header
q~,>                 ~,>                  Create array [m .. n-1]
{_1&3*+_*24+48/}%    {.1&3*+.*24+48/}%    Map the sequence calculation
_:e>2b,\             .$-1=2base,\         Compute image height H as highest bit
                                          in largest number in sequence
2_$#f+2fb            {2.$?+2base}%        Map sequence to bits, ensuring that
                                          each gives H bits by adding 2^H
z(,@@                zip(,@@              Transpose and pull off dummy row to use
                                          its length as the "width" in the header
:~~                  {~}/                 Flatten double array and dump on stack
]N*                  ]n*                  Separate everything with whitespace

Gracias a Optimizer para CJam 56 -> 53.

Peter Taylor
fuente
1
¿Alguna razón por la que no tiene "P1" al principio y por lo tanto ahorra 1 byte evitando el ``?
Optimizador
@Optimizer, demasiado acostumbrado a pensar en GS.
Peter Taylor
No del todo: la altura debe aparecer en la salida. Pero todavía hay un ahorro por hacer con el acortamiento del mapa.
Peter Taylor
51:'PoXq~{_1&3*+_*24+48/}%>_:e>2b,\2_$#f+2fbz(,@@]e_N*
Optimizador
5

Pyth - 101 60 59

Salidas a .pbm. Es probable que se pueda jugar más al golf.

Km.B/++24*dd**6%d2d48rvzQJCm+*\0-eSmlkKlddK"P1"lhJlJjbmjbdJ

Altamente ignorante porque estaré traduciendo a Pyth.

La explicación viene después. Ahora mire el código Python equivalente.

Utiliza el algoritmo OEIS para calcular la secuencia y luego se convierte en binario, rellena los números, realiza una rotación de matriz y lo formatea en una pbmimagen. Como no estoy usando la fuerza bruta, es increíblemente rápido.

         K=
 m          rvzQ      Map from eval input to eval input
  .B                  Binary rep
   /      48          Divided by 48
    ++                Triple sum      
     24               Of 24,
     *dd              Square of d
     **               Triple product
      6               6
      %d2             Modulo d%2
      d               Var d
J                     Set J=
 C                    Matrix rotation from columns of row to rows of columns
  m           K       Map K (This does padding)
   +                  String concat
    *                 String repeat
     \0               "0"
     -     ld         Subtract the length of the column from
      eS              The max
       mlkK           Of all the column lengths
    d                 The column
"P1"                  Print header "P1"
l                     Length of
 hJ                   First row
lJ                    Number of columns
jb                    Join by linebreaks
 m  J                 Map on to J
  jb                  Joined columns by linb
   d

Aquí está el 600,900ejemplo:

600 - 900

Pruébalo aquí en línea .

Maltysen
fuente
4

R - 127 125

No estoy seguro si esto cumple totalmente con las reglas. No genera una imagen en un archivo, pero crea un ráster y lo traza a un dispositivo de salida.

Encontré la misma fórmula que Martin, pero aquí .

Utiliza una función sin nombre.

require(raster);function(m,n)plot(raster(mapply(function(n)rev(as.integer(intToBits(round((n+n%%2*3)^2/48)))),m:n),0,n,0,32))

Ejecutar de la siguiente manera

require(raster);(function(m,n)plot(raster(mapply(function(n)rev(as.integer(intToBits(round((n+n%%2*3)^2/48)))),m:n),0,n,0,32)))(0,600)

Produce la siguiente trama

ingrese la descripción de la imagen aquí

MickyT
fuente
Puede soltar 7 bytes si no se adjunta rasteral espacio de nombres, ya que raster()es lo único específico de ese paquete. En cambio, solo hazlo raster::raster(...).
Alex A.
@AlexA. Gracias, haré esa edición
MickyT
@AlexA. Desafortunadamente lo probé y me da errores. Sospecho que es porque la trama también requiere sp. Veré si puedo localizarlo.
MickyT
Gorrón. Lamento haberte llevado por mal camino.
Alex A.
3

Python 2 + PIL , 255 184

Mi primera versión usó PIL para mostrar una imagen:

i,R,B=input,range,lambda x:bin((x*x+6*x*(x%2)+24)/48)[2:]
def F(k,v):i.load()[k]=v
a,b=i(),i();h=len(B(b));from PIL import Image;i=Image.new('P',(b-a,h))
[F((x-a,y),int(B(x).zfill(h)[y])) for x in R(a,b) for y in R(h)]
i.putpalette([255]*3+[0]*3)
i.show()

La nueva versión solo produce una imagen PPM en blanco y negro en stdout:

i,R,B=input,range,lambda x:bin((x*x+6*x*(x%2)+24)/48)[2:]
def p(s):print s
a,b=i(),i();h=len(B(b));p('P1 %i %i'%(b-a,h))
[p(' '.join([B(x).zfill(h)[y] for x in R(a,b)])) for y in R(h)]
dieter
fuente
Algunos caracteres se guardan para la versión PPM: no necesita un espacio antes for. Puedes evitar los parens x%2cambiando el orden a x%2*.... Es más corto no definir imprimir como una función y solo usar dos forbucles anidados , usar print ...,para evitar nuevas líneas y un espacio printen blanco para comenzar una nueva línea. Un truco para forzar que las expansiones binarias tengan longitud hsin zfilles agregar 2**h, luego extraer los últimos hdígitos.
xnor
2

JAVASCRIPT - 291

Código:

(function(a,b,c){c.width=b;t=c.getContext('2d');t.strokeStyle='black';for(i=a;i<=b;i++){g=(Math.floor(((i*i)+6*i*(i%2)+24)/48)>>>0).toString(2);l=g.length;for(j=0;j<l;j++){if(g[l-1-j]=='1'){t.rect(i-a,j,1,1);t.fill();}}}document.body.appendChild(c);})(0,300,document.createElement('canvas'))

Explicación:

(function (a, b, c) {
    //setting canvas width
    c.width = b;
    //get context 2d of canvas
    t = c.getContext('2d');
    //setting storke style.
    t.strokeStyle = 'black';
    //looping from a to b
    for (i = a; i <= b; i++) {
        //calculating A(i) and converting it to a binary string
        g = (Math.floor(((i * i) + 6 * i * (i % 2) + 24) / 48) >>> 0).toString(2);
        //looping through that string
        for (j = 0; j < g.length; j++) {
            //since canvas is upside down and the first digit is actually the last digit:
            if (g[g.length - 1 - j] == '1') {
                //we create the 1 by 1 rect
                t.rect(i - a, j, 1, 1);
                //we draw the rect
                t.fill();
            }
        }
    }
    //we append everything to the body
    document.body.appendChild(c);
    //parameters are put here
})(0, 300, document.createElement('canvas'))

Resultado:

Sí, el resultado está al revés, pero eso se debe a que 0,0en un js canvasestá arriba a la izquierda. : 3 Secuencia de Alquin

Manifestación:

Demo en jsfiddle

kemicofa apoya a Monica
fuente