El pasado 11 de marzo se ha publicado el artículo Unexpected biases in the distribution of consecutive primes en el que muestra que los números primos repelen a otros primos que terminan en el mismo dígito.
La lista de los últimos dígitos de los 30 primeros números es
[2,3,5,7,1,3,7,9,3,9,1,7,1,3,7,3,9,1,7,1,3,9,3,9,7,1,3,7,9,3] |
Se observa que hay 6 números que su último dígito es un 1 y de sus consecutivos 4 terminan en 3 y 2 terminan en 7.
Definir la función
distribucionUltimos :: Int -> M.Matrix Integer |
tal que (distribucionUltimos n) es la matriz cuyo elemento (i,j) indica cuántos de los n primeros números primos terminan en i y su siguiente número primo termina en j. Por ejemplo,
λ> distribucionUltimos 30 ( 0 0 4 0 0 0 2 0 0 ) ( 0 0 1 0 0 0 0 0 0 ) ( 0 0 0 0 1 0 4 0 4 ) ( 0 0 0 0 0 0 0 0 0 ) ( 0 0 0 0 0 0 1 0 0 ) ( 0 0 0 0 0 0 0 0 0 ) ( 4 0 1 0 0 0 0 0 2 ) ( 0 0 0 0 0 0 0 0 0 ) ( 2 0 3 0 0 0 1 0 0 ) λ> distribucionUltimos (10^5) ( 4104 0 7961 0 0 0 8297 0 4605 ) ( 0 0 1 0 0 0 0 0 0 ) ( 5596 0 3604 0 1 0 7419 0 8387 ) ( 0 0 0 0 0 0 0 0 0 ) ( 0 0 0 0 0 0 1 0 0 ) ( 0 0 0 0 0 0 0 0 0 ) ( 6438 0 6928 0 0 0 3627 0 8022 ) ( 0 0 0 0 0 0 0 0 0 ) ( 8830 0 6513 0 0 0 5671 0 3995 ) |
Nota: Se observa cómo se “repelen” ya que en las filas del 1, 3, 7 y 9 el menor elemento es el de la diagonal.
Soluciones
import Data.Numbers.Primes import Data.Array import qualified Data.Matrix as M -- (ultimo n) es el último dígito de n. ultimo :: Integer -> Integer ultimo n = n `mod` 10 -- ultimos es la lista de el último dígito de los primos. -- λ> take 20 ultimos -- [2,3,5,7,1,3,7,9,3,9,1,7,1,3,7,3,9,1,7,1] ultimos :: [Integer] ultimos = map ultimo primes -- ultimosConsecutivos es la lista de los últimos dígitos de los primos -- consecutivos. -- λ> take 10 ultimosConsecutivos -- [(2,3),(3,5),(5,7),(7,1),(1,3),(3,7),(7,9),(9,3),(3,9),(9,1)] ultimosConsecutivos :: [(Integer,Integer)] ultimosConsecutivos = zip ultimos (tail ultimos) -- (histograma r is) es el vector formado contando cuantas veces -- aparecen los elementos del rango r en la lista de índices is. Por -- ejemplo, -- ghci> histograma (0,5) [3,1,4,1,5,4,2,7] -- array (0,5) [(0,0),(1,2),(2,1),(3,1),(4,2),(5,1)] histograma :: (Ix a, Num b) => (a,a) -> [a] -> Array a b histograma r is = accumArray (+) 0 r [(i,1) | i <- is, inRange r i] distribucionUltimos :: Int -> M.Matrix Integer distribucionUltimos n = M.fromList 9 9 (elems (histograma ((1,1),(9,9)) (take n ultimosConsecutivos))) |
Solución en Maxima
distribucionUltimos (n) := block ( [r : zeromatrix (9,9), xs : ultimos (n), i, j], unless length (xs) < 2 do ( i : first (xs), j : second (xs), r[i,j] : 1 + r[i,j], xs : rest (xs)), r)$ /* ultimos(n) es la lista del último dígito de los n primeros primos. (%i5) ultimos (30); (%o5) [2,3,5,7,1,3,7,9,3,9,1,7,1,3,7,3,9,1,7,1,3,9,3,9,7,1,3,7,9,3,7] */ ultimos (n) := block ([r:[], p:2], for k from 0 thru n do ( r : cons (mod (p,10), r), p : next_prime (p) ), reverse (r))$ |