Mostrando las entradas con la etiqueta ES. Mostrar todas las entradas
Mostrando las entradas con la etiqueta ES. Mostrar todas las entradas

5 de abril de 2021

Huevos de Pascua de Chocolate Caseros

Estuvimos haciendo huevos de Pascua de chocolate caseros. (Acá lo usual es una cáscara de chocolate duro, con confites o juguetes adentro.) A mi hija de 4 años le encantó, aunque hizo un poco de enchastre. Sobre todo ayudó a pasar los pedazos de chocolate de la bolsa donde los compramos al recipiente para derretirlo, y a llenar las mitades de los huevos con los confites.

Las fotos quedaron muy lindas:




Los huevos en el mundo real no quedaron tan lindos, así que no tengo nada inspirador para decir sobre la receta. Mejor busquen una receta de alguien que sepa lo que está haciendo.

Lo importante es elegir el huevo correcto y el ángulo correcto para sacar la foto. (Ni siquiera era el mejor huevo, era el que se veía mejor en la foto.) (Otro truco es sacar muchas fotos y elegir la mejor. En este caso no lo usé. La primera foto quedó muy linda.) (El envoltorio de celofán causó muchos problemas, pero se ve bien en la foto.)

La única conclusión inspiradora es que no crean todo lo que se publica en Internet.

1 de enero de 2021

Fryday Uncember 1st

I can't believe it! A leap day was okay, a leap second was a bit too much, but a whole extra month is too much. 

Anyway, I'm more concerned about 13/13/2020. It sounds bad. It sounds bad.

30 de diciembre de 2020

Eclipse (casi) total del 14 de diciembre de 2020

Hace unos días hubo un eclipse parcial acá en Buenos Aires (79%<<<<100%). Fue un eclipse total a unos 1000km de acá, pero por la pandemia y el trabajo no pudimos ir a verlo.

Fue casi al mediodía. Era raro porque todo se veía normal pero con poca luz. El cielo tenía el color celeste normal, no era gris como un día nublado ni rojizo como en un atardecer. Todo tenía la coloración normal, pero con poca luz.

No llegué a armarme una cámara oscura casera, pero las hojas de los árboles forman pequeños agujeritos que tienen el mismo efecto, y se ven en el suelo la imágen del Sol con forma de media luna. (Es una combinación de palabras muy extraña.) Con el viento los agujeritos se mueven, aparecen y desaparecen, así que hay media lunas danzantes. Es muy lindo el efecto.

 Foto de la sombre durante el eclipse.

Para comparar, saqué otras fotos tres días después a la misma hora, porque siempre es bueno tener lo más parecido a un grupo de control que uno pueda conseguir. No encontré una foto del lugar anterior, pero me gusta cómo salió. Así que estas son dos fotos que comparan un lugar cercano.

Foto de la sombre durante el eclipse.
 

 
Foto del mismo lugar tres días después.

30 de abril de 2020

Coquitos para la cuarentena

Seguimos de cuarentena, pero teníamos un poco de coco rayado e hicimos coquitos:
  • 200g de coco rayado
  • 200g de azucar
  • 2 huevos
  • No tengo idea qué tan caliente estaba el horno.
Les dimos forma a mano, así que les quedaron a los costados unas rayas quemaditas muy simpáticas.

 Coquitos: En la foto ya faltan algunos

(Probamos una segunda vez, pero la mezcla quedó muy seca y después de cocinarlos se desmenuzaban. Es muy extraño. ¿Quizás dependa de la humedad del coco rayado?) 

30 de marzo de 2020

Sobre el billete de AR$5 en Argentina

[En cuarentena]

[Debería haber escrito esto hace un mes, porque con lo de la cuarentena por el Covid-19 la situación cambió mucho, y la mayor parte de esto no tiene sentido ahora. Igualmente me parece una historia que merece ser contada y tengo algo de tiempo libre.] [Por ahora estamos bien. Gracias por preguntar.]

Érase una vez, durante el mes de febrero …

El cambio efectivo del (US)dólar está a aproximadamente AR$80, así que siguiendo las estimaciones del artículo sobre la moneda de AR$1, las monedas de AR$2 deberían caer en desuso. (Sorprendentemente tardó menos de lo esperado.)
Esta no es una regla estricta, si no que es una costumbre en Argentina. En el último tiempo (enero-febrero), ya estuve viendo que empezamos a redondear los precios a pagar a un múltiplo de AR$5. Por ejemplo, si había que pagar AR$102, era probable que nadie exigiera la moneda de AR$2.


Teníamos en circulación billetes de AR$5 y monedas de AR$5, pero los billetes estaban medio viejos y recientemente salieron de circulación. O sea que se los puede cambiar en un banco, pero no se los puede usar en un negocio.
¡El problema es que la cantidad de monedas de AR$5 es aproximadamente1/4 ó 1/5 de la cantidad de billetes! Entonces al dejar de circular los billetes de AR$5 nadie tiene suficientes monedas de AR$5.

Si no hay monedas …

La solución es entonces usar las monedas de AR$2 y hasta revolver los cajones y desempolvar las de AR$1 que ya habían caído prácticamente en desuso. Creo haber visto más monedas de AR$1 en los últimos días (de febrero) que en los últimos meses. En general, al pagar las monedas se combinan para formar un múltiplo de AR$5 porque muchos de los precios de productos discretos ya están redondeados. (Aunque hay excepciones como los caramelos que valen AR$3 y son un problema.)
 


Mi propuesta (en febrero) es entonces pegar con La Gotita dos monedas de AR$2 y una moneda de AR$1 y obtener un combo de AR$5. Sería mucho más cómodo que andar buscando y eligiendo las monedas de a una (aunque quizás ilegal). Sin embargo, a los dos días seguro aparece uno que reemplaza la moneda del medio por una trucha para obtener un 40% de ganancia.

[Situación actual]

[Por la situación actual, estamos tratando de hacer sólo una o dos compras semanales en el supermercado. Es una compra grande y la pagamos con tarjeta de crédito, así que a nadie le importa si hay o no hay monedas.]

4 de febrero de 2020

Bytes aleatorios generados cuánticamente en Racket

Busquemos los bytes

La semana pasada leí sobre el proyecto QuantumRNG for OpenQu que se autodefine como “números cuánticos aleatorios como servicio”. La idea es usarlo para obtener algunos números aleatorios en Racket, usando los módulos net/http-client y json

Esta función crea una cadena de bytes de longitud n usando el servicio.

#lang racket

(require net/http-client
         json)

(define (quantum-random-bytes n)
  (define-values (status headers content)
    (http-sendrecv "random.openqu.org"        
                   (string-append "/api/randint"
                                  "?size=" (number->string n)
                                  "&min=0"
                                  "&max=255")))
  (list->bytes (hash-ref (read-json content) 'result)))

(quantum-random-bytes 5) ; ==> #"\2\353<\223\346"
(quantum-random-bytes 5) ; ==> #"\240\200\242\364\25"
(quantum-random-bytes 5) ; ==> #"\201\370\367\32\25"

Otras funciones como random-bytes

A modo de comparación, podemos usar la función crypto-random-bytes y también podemos escribir nuestra propia función random-bytes que usa el generador de números pseudoaleatorios incorporado.

(require racket/random) ; for crypto-random-bytes
(define (random-bytes n)
  (list->bytes
   (for/list ([i (in-range n)])
    (random 256))))

(random-bytes 5)         ; ==> #"E\31\366\4\333"
(crypto-random-bytes 5)  ; ==> #"b\345\207\315\""
(quantum-random-bytes 5) ; ==> #"\30`\325\3377"

(require file/sha1) ; for bytes->hex-string

(bytes->hex-string (quantum-random-bytes 5)) ; ==> "00b7c4d6db"
(bytes->hex-string (crypto-random-bytes 5))  ; ==> "662b108fd2"
(bytes->hex-string (random-bytes 5))         ; ==> "da25419554"

Como era de esperar, los resultados de todos ellos parecen cosas aleatorias similares sin sentido. Pero se ve más lindo verlo como cosas hexadecimales aleatorias sin sentido.

La primera es determinista, pero utiliza el tiempo de inicio del programa como semilla, por lo que se obtienen resultados diferentes en cada ejecución. Es lo suficientemente bueno como para un juego o simulación, y se puede usar random-seed para obtener la misma secuencia.

La segunda utiliza el generador de números aleatorios del sistema operativo y es criptográficamente segura. El sistema operativo combina muchas fuentes de entropía, pero todas (¿la mayoría?) son fuentes clásicas. (Es como tirar un dado, es difícil de predecir, pero no es realmente aleatorio.)

El tercero usa un sistema cuántico para producir los números aleatorios. Estos números son verdaderamente aleatorios (si la mecánica cuántica es correcta). Pero no es buena idea usarlos para una contraseña y otras aplicaciones de seguridad porque el dueño del servidor puede tener una copia (o estar mintiendo y enviando los dígitos de pi). O alguien podrían estar interceptando tu conexión a Internet (¡esto usa http, no https!).

(Notar que esto no son qbits. La “q” se elimina en la generación mucho antes de que se envíen a través del cable.)

Supongo que se puede usar para una buena elección de números aleatorios en forma cuántica, como la posición inicial de un juego de solitario. Es "mejor" que simplemente mezclar las cartas, pero probablemente sea indistinguible para el jugador. Para una versión segura, es necesario comprar la versión en hardware (y verificar que funciona según lo declarado).

Testeando los números

En un artículo anterior, usé Random Sanity que es un servicio que realiza una verificación mínima de los números aleatorios. Puede tener falsos positivos y puede que no detecte números aleatorios falsos, por lo que solo es útil para detectar implementaciones muy malas de generadores de números (pseudo) aleatorios.

Usando las funciones definidas en ese artículo para contactar este servicio, obtenemos:


(test-random-bytes (random-bytes 64))         ; ==> #t ;probably
(test-random-bytes (crypto-random-bytes 64))  ; ==> #t
(test-random-bytes (quantum-random-bytes 64)) ; ==> #t
(with-random-seed 1234567890
  (test-random-bytes (random-bytes 64)))      ; ==> #f

El primero en general es verdadero, pero puede ser falso si todos generamos y enviamos los números creados por el generador de números pseudoaleatorios. Usando la paradoja del cumpleaños, con 38 personas que comienzan el programa en el mismo segundo, tenemos un 50% de posibilidades de tener una colisión. (O que se derrita el servidor, lo que pase primero.) El último es falso porque está usando una semilla fija, y yo ya lo testeé y el servidor ahora detecta la colisión.

Notar que ahora que los bytes han sido testeados, son aún menos seguros porque otra persona más tiene una copia.

Algunas ideas para probar

  • Hay una llamada API para obtener algunos bytes en el formato base64. Probé usarla, pero recibo un mensaje de error. Es posible que funcione más adelante. Puede ser útil base64-decode.
  • Sin ninguna buena razón, estoy generando una cadena de bytes aleatoria en lugar de un único número aleatorio. Con algunas modificaciones es fácil hacer una función que reemplace a (random n). Notar que el valor max del intervalo en el servicio está incluido en los resultados, así que hay que restar 1 antes de enviar la solicitud. No se que tan grande puede ser max.
  • Hay otra llamada API para obtener números de coma flotante, que se puede usar para escribir una función que reemplace a (random). Pero es importante recordar que el viaje de ida y vuelta en la red puede llevar más tiempo del tolerable para un programa interactivo.

Bonus: Otro servicio similar en español

Mientras buscaba más información encontré varios servicios similares, pero la mayoría de ellos pedían algún tipo de registración. Uno que es fácil de usar es el ANU Quantum Random Numbers Server. Probémoslo también:

(define (other-quantum-random-bytes n)
  (define-values (status headers content)
    (http-sendrecv "qrng.anu.edu.au"        
                   (string-append "/API/jsonI.php"
                                  "?length=" (number->string n)
                                  "&type=uint8")))
  (list->bytes (hash-ref (read-json content) 'data)))

(other-quantum-random-bytes 5) ; ==> #"\25\n1\236K"
(other-quantum-random-bytes 5) ; ==> #"\271\375'\272\205"
(other-quantum-random-bytes 5) ; ==> #"\23\362\324\271\\"
(bytes->hex-string (other-quantum-random-bytes 5)) ; ==> "9366b3f8d2"
(test-random-bytes (other-quantum-random-bytes 64)) ; ==> #t

El link a la API es difícil de encontrar, pero este servidos solo soporta int8, int16 y cadenas de bits en algún tipo de formato hexadecimal. Por otro lado, soporta https, pero esta parte queda como ejercicio para el lector.

22 de septiembre de 2019

Más sobre los paralelogramos de primos

Introducción

Estuve leyendo un artículo sobre como graficar los “paralelogramos de primos” en J usando verbos (en ingés), que está basado en la segunda parte de un video de Numberphile (en ingés).

La idea es tomar el n-ésimo primo y restarle el número que se obtiene invirtiendo el orden de su representación en base 2. Por ejemplo, el 16-avo primo es 53=1101012, al darlo vuelta queda 1010112=43, así que el valor es 53-43=10. Al graficar esta función aparecen unos paralelogramos.


La duda que me surgió es qué pasaba si graficábamos todos los números en vez de dibujar sólo los primos. Y además entender de dónde vienen estos paralelogramos.

Módulos adicionales

Para graficarlos en Racket vamos a necesitar usar algunos modulos adicionales, así que empezamos con

#lang racket
(require math/number-theory)
(require plot)
#;(plot-new-window? #t)

A mí también me gusta modificar cómo aparecen los números en los ejes. Es medio técnico y casi o cambia el resultado. El código está abajo.

Reconstruyendo el dibujo

Primero definimos la función que invierte el orden de los bits en la representación binaria del número.

(define (binary-reverse x)
  (let loop ([x x] [r 0])
    (if (zero? x)
       r
       (loop (quotient x 2) (+ (* 2 r) (remainder x 2))))))

Veamos algunos ejemplos

(for ([i (in-range 16)])
  (define r (binary-reverse i))
  (displayln (list i r (number->string i 2) (number->string r 2))))

> (0 0 0 0)
> (1 1 1 1)
> (2 1 10 1)
> (3 3 11 11)
> (4 1 100 1)
> (5 5 101 101)
> (6 3 110 11)
> (7 7 111 111)
> (8 1 1000 1)
> (9 9 1001 1001)
> (10 5 1010 101)
> (11 13 1011 1101)
> (12 3 1100 11)
> (13 11 1101 1011)
> (14 7 1110 111)
> (15 15 1111 1111)

Nota: Es posible definirla usando strings, pero usar strings siempre es mucho más lento que operar directamente con los números enteros.

Para simplificar la notación, llamemos inv a esta función que invierte el orden de los bits, p a la función que calcula el n-esimo primo y f a f(n)=n-inv(n).
Ahora podemos hacernos una lista con los puntos (n, f(p(n))) = (n, p(n) - inv(p(n))) en forma de vectores.

(define prim/original (for/list ([i (in-naturals 1)]
                                 [p (in-list (next-primes 1 10000))])
                        (vector i (- p (binary-reverse p)))))

Nota: Es posible escribir nuestra propia función para tertear primalidad, pero las funciones next-primes y prime? son mejores.

Y la dibujamos con plot

(plot (points prim/original))




Arreglamos el color y la opacidad para que el dibujo sea más lindo

(plot #:title "Prime Paralelograms (original)"
      (points prim/original
              #:sym 'dot
              #:color 'blue #:alpha .5)
      #:x-label "n" #:y-label "f(p(n))"
      #:x-min 0)  


Para guardar la imagen usamos plot-file

(plot-file #:title "Prime Paralelograms (original)"
           (points prim/original
                   #:sym 'dot
                   #:color 'blue #:alpha .5)
           "prime-paralelograms(original).png"
           #:x-label "n" #:y-label "f(p(n))"
           #:x-min 0)

Para poder compararla con el próximo gráfico, la dibujamos de vuelta. Pero con las etiquetas de los valores del eje x hacia la izquierda (para que el borde del gráfico sea el borde de la imagen).

(parameterize ([plot-x-tick-label-anchor 'top-right])
  (plot #:title "Prime Paralelograms (original)"
        (points prim/original
                #:sym 'dot
                #:color 'blue #:alpha .5)
        #:x-label "n" #:y-label "f(p(n))"
        #:x-min 0))
  

Ahora cambiamos lo que graficamos. Cambiamos la posición en x de los puntos, en vez de tomar el número de primo tomamos el valor del primo, o sea que en vez de dibujar (n, f(p(n)) dibujamos (p(n), f(p(n)) = (p, f(p)).

(define prim/new (for/list ([i (in-naturals 1)]
                            [p (in-list (next-primes 1 10000))])
                   (vector p (- p (binary-reverse p)))))

(parameterize ([plot-x-tick-label-anchor 'top-right])
  (plot #:title "Prime Paralelograms"
        (points prim/new
                #:sym 'dot
                #:color 'blue #:alpha .5)
        #:x-label "p(n)" #:y-label "f(p(n))"
        #:x-min 0))

Podemos compararlo con el dibujo anterior:
El dibujo que obtenemos es muy similar, si ignoramos la escala del eje x. Los paralelogramos cortan en posiciones ligeramente diferentes, pero son muy parecidos.
Lo que pasa es que si dibujamos el n-esimo primo obtenemos casi una recta.

(define prim/scale (for/list ([i (in-naturals 1)]
                              [p (in-list (next-primes 1 10000))])
                     (vector i p)))

(plot #:title "Primes"
      (points prim/scale
              #:sym 'dot)
      #:x-label "n" #:y-label "p(n) = nth prime"
      #:x-min 0)


La inversa es la función que cuenta la cantidad de primos que en general se llama pi(n) y su pendiente va cambiando lentamente, más o menos como 1/log(n), pero log(n) es una función que crece muy lentamente. Así que el cambio entre los gráficos es casi una transformación lineal y por eso a cambiar el eje en los dibujos anteriores vemos que la forma de los paralelogramos cambia poco. (Deberíamos poder notar más distorsión en los primeros paralelogramos.)

Comparando con todos los números

Veamos ahora como queda el gráfico cuando usamos todos los números en vez de sólo los primos. Para poder comparar mejor los gráficos, fijamos el mismo rango para el eje y en todos los gráficos. Además, me gusta elegir un tamaño de gráfico para que la recta y=x tenga aproximadamente 45°. (En Excel uno hace un gráfico y después con el mouse arregla todos los detalles de los ejes y escalas. Acá hay que poner todo eso en el programa para que las escalas queden exactamente como uno quiere.)

(define all (for/list ([i (in-range 1 131072)])
              (vector i (- i (binary-reverse i)))))

(plot #:title "All Paralelograms"
      (points all
              #:sym 'dot
              #:color 'black #:alpha .1)
      #:x-label "n" #:y-label "f(n)"
      #:y-min -65536 #:y-max 131072
      #:x-min 0
      #:width 400 #:height 600)


Repetimos el gráfico de los primos en la misma escala, armando la lista de primos en este rango de una manera ligeramente diferente.

(define prim (for/list ([i (in-range 1 131072)]
                        #:when (prime? i))
              (vector i (- i (binary-reverse i)))))

(plot #:title "Prime Paralelograms"
      (points prim
              #:sym 'dot
              #:color 'blue #:alpha .5)
      #:x-label "p" #:y-label "f(p)"
      #:y-min -65536 #:y-max 131072
      #:x-min 0
      #:width 400 #:height 600)


Y los superponemos

(plot #:title "All vs Prime Paralelograms"
      (list (points all
                    #:sym 'dot
                    #:color 'black #:alpha .1)
            (points prim
                    #:sym 'dot
                    #:color 'blue #:alpha .5))
      #:x-label "n" #:y-label "f(n)"
      #:y-min -65536 #:y-max 131072
      #:x-min 0
      #:width 400 #:height 600)
 [Gráfico]

Lo que vemos es que los paralelogramos de los primos ocupan la mitad de abajo de los paralelogramos que se forman cuando graficamos todos los números.

Pares e impares

Casi todos los primos son impares. Por ser impares al invertir el orden de sus cifras en binario se obtiene un número con la misma cantidad de cifras en binario. Así que es aproximadamente del mismo tamaño. Se pueden hacer algunas acotaciones y formalizar esta idea, pero es más lindo comparar en el gráfico que pasa cuando reemplazamos los números primos por los números impares.

(define odd (for/list ([i (in-range 1 131072 2)])
              (vector i (- i (binary-reverse i)))))

(plot #:title "All vs Odd Paralelograms"
      (list (points all
                    #:sym 'dot
                    #:color 'black #:alpha .1)
            (points odd
                    #:sym 'dot
                    #:color 'red #:alpha .1))
      #:x-label "n" #:y-label "f(n)"
      #:y-min -65536 #:y-max 131072
      #:x-min 0
      #:width 400 #:height 600)


Vemos que los impares ocupan el esencialmente los mismos paralelogramos, aunque hay menos huecos.

En cambio, los números pares terminan en 0 en binario, así que al invertir el orden de sus cifras en binario al menos pierden una cifra y son más chicos. Al dibujar tenemos

(define even (for/list ([i (in-range 2 131072 2)])
               (vector i (- i (binary-reverse i)))))

(plot #:title "All vs Even Paralelograms"
      (list (points all
                    #:sym 'dot
                    #:color 'black #:alpha .1)
            (points even
                    #:sym 'dot
                    #:color 'green #:alpha .1))
      #:x-label "n" #:y-label "f(n)"
      #:y-min -65536 #:y-max 131072
      #:x-min 0
      #:width 400 #:height 600)


Vemos que los pares ocupan esencialmente las mitades de arriba, o sea que no se superponen con lo pintado por los primos. Entonces que los huequitos en los paralelogramos de los primos se deben a números impares no primos.

Algunas ideas para probar

  • ¿Qué pasa en base 3? ¿Es la generalización obvia? ¿En base 4 son banderitas?
  • Redibujar para ver sólo los primeros paralelogramos. El cambio de escala no es tan lineal al principio y al dibujar los paralelogramos del artículo original (n, f(p(n)) deberían estar más deformados.
  • Redibujar todo con el eje x en escala logarítmica para que todos los paralelogramos tengan el mismo ancho y se pueda ver bien los primeros. No sé qué escala usar para el eje y. ¿Quizás haya que dibujar cada paralelogramo por separado?
  • Los primos no son aleatorios, pero parecen bastante aleatorios. Podría ser interesante generar una lista de truchi-primos, filtrando los números impares con una distribución parecida a la de los primos y ver cómo queda el gráfico.

Cambiando el formato de las etiquetas

A mí me gusta modificar cómo aparecen los números en los ejes, no me gusta que 100000 aparece como 105. Esta parte es medio técnica y casi no cambia el resultado, así que no voy a explicar los detalles. (Parece una buena idea para un PR como una opción adicional de linear-ticks.)

(require plot/utils)
(define ((linear-ticks-format/no-sc) min max pre-ticks)
  (define digits (digits-for-range min max))
  (map (lambda (pt)
         (real->plot-label (pre-tick-value pt) digits #f))
       pre-ticks))
(define (linear-ticks/no-sc) (ticks (linear-ticks-layout) (linear-ticks-format/no-sc)))
(plot-x-ticks (linear-ticks/no-sc)) ; almost global change
(plot-y-ticks (linear-ticks/no-sc)) ; almost global change

Código completo

#lang racket
(require math/number-theory)
(require plot)
#;(plot-new-window? #t)

(require plot/utils)
(define ((linear-ticks-format/no-sc) min max pre-ticks)
  (define digits (digits-for-range min max))
  (map (lambda (pt)
         (real->plot-label (pre-tick-value pt) digits #f))
       pre-ticks))
(define (linear-ticks/no-sc) (ticks (linear-ticks-layout) (linear-ticks-format/no-sc)))
(plot-x-ticks (linear-ticks/no-sc)) ; almost global change
(plot-y-ticks (linear-ticks/no-sc)) ; almost global change

(define (binary-reverse x)
  (let loop ([x x] [r 0])
    (if (zero? x)
       r
       (loop (quotient x 2) (+ (* 2 r) (remainder x 2))))))

(for ([i (in-range 16)])
  (define r (binary-reverse i))
  (displayln (list i r (number->string i 2) (number->string r 2))))

#;(for ([i (in-range 128)]
        #:when (prime? i))
    (define r (binary-reverse i))
    (displayln (list i r (number->string i 2) (number->string r 2))))

;ORIGINAL
(define prim/original (for/list ([i (in-naturals 1)]
                                 [p (in-list (next-primes 1 10000))])
                        (vector i (- p (binary-reverse p)))))

(plot (points prim/original))

(plot #:title "Prime Paralelograms (original)"
      (points prim/original
              #:sym 'dot
              #:color 'blue #:alpha .5)
      #:x-label "n" #:y-label "f(p(n))"
      #:x-min 0)

(plot-file #:title "Prime Paralelograms (original)"
           (points prim/original
                   #:sym 'dot
                   #:color 'blue #:alpha .5)
           "prime-paralelograms(original).png"
           #:x-label "n" #:y-label "f(p(n))"
           #:x-min 0)

(parameterize ([plot-x-tick-label-anchor 'top-right])
  (plot #:title "Prime Paralelograms (original)"
        (points prim/original
                #:sym 'dot
                #:color 'blue #:alpha .5)
        #:x-label "n" #:y-label "f(p(n))"
        #:x-min 0))

;NEW
(define prim/new (for/list ([i (in-naturals 1)]
                            [p (in-list (next-primes 1 10000))])
                   (vector p (- p (binary-reverse p)))))

(parameterize ([plot-x-tick-label-anchor 'top-right])
  (plot #:title "Prime Paralelograms"
        (points prim/new
                #:sym 'dot
                #:color 'blue #:alpha .5)
        #:x-label "p(n)" #:y-label "f(p(n))"
        #:x-min 0))

;SCALE
(define prim/scale (for/list ([i (in-naturals 1)]
                              [p (in-list (next-primes 1 10000))])
                     (vector i p)))

(plot #:title "Primes"
      (points prim/scale
              #:sym 'dot)
      #:x-label "n" #:y-label "p(n) = nth prime"
      #:x-min 0)

;All
(define all (for/list ([i (in-range 1 131072)])
              (vector i (- i (binary-reverse i)))))

(plot #:title "All Paralelograms"
      (points all
              #:sym 'dot
              #:color 'black #:alpha .1)
      #:x-label "n" #:y-label "f(n)"
      #:y-min -65536 #:y-max 131072
      #:x-min 0
      #:width 400 #:height 600)

(define prim (for/list ([i (in-range 1 131072)]
                        #:when (prime? i))
              (vector i (- i (binary-reverse i)))))

(plot #:title "Prime Paralelograms"
      (points prim
              #:sym 'dot
              #:color 'blue #:alpha .5)
      #:x-label "p" #:y-label "f(p)"
      #:y-min -65536 #:y-max 131072
      #:x-min 0
      #:width 400 #:height 600)

(plot #:title "All vs Prime Paralelograms"
      (list (points all
                    #:sym 'dot
                    #:color 'black #:alpha .1)
            (points prim
                    #:sym 'dot
                    #:color 'blue #:alpha .5))
      #:x-label "n" #:y-label "f(n)"
      #:y-min -65536 #:y-max 131072
      #:x-min 0
      #:width 400 #:height 600)

; ODD and EVEN
(define odd (for/list ([i (in-range 1 131072 2)])
              (vector i (- i (binary-reverse i)))))

(plot #:title "All vs Odd Paralelograms"
      (list (points all
                    #:sym 'dot
                    #:color 'black #:alpha .1)
            (points odd
                    #:sym 'dot
                    #:color 'red #:alpha .1))
      #:x-label "n" #:y-label "f(n)"
      #:y-min -65536 #:y-max 131072
      #:x-min 0
      #:width 400 #:height 600)

(define even (for/list ([i (in-range 2 131072 2)])
               (vector i (- i (binary-reverse i)))))

(plot #:title "All vs Even Paralelograms"
      (list (points all
                    #:sym 'dot
                    #:color 'black #:alpha .1)
            (points even
                    #:sym 'dot
                    #:color 'green #:alpha .1))
      #:x-label "n" #:y-label "f(n)"
      #:y-min -65536 #:y-max 131072
      #:x-min 0
      #:width 400 #:height 600)