(Acest articol a fost publicat pentru prima dată pe R – TomazTsqlși cu amabilitate a contribuit la R-bloggeri). (Puteți raporta problema legată de conținutul acestei pagini aici)
Doriți să vă distribuiți conținutul pe R-bloggeri? dați clic aici dacă aveți un blog, sau aici dacă nu aveți.
Stanislaw Ulam, Los Alamos, 1963 s-a plictisit într-o întâlnire și a început să mâzgâie numere întregi într-o spirală și a înconjurat numerele prime. Au apărut linii diagonale. Mai târziu i-a arătat-o lui Martin Gardner, spre surprinderea lui Ulam, Gardner și-a publicat descoperirile în Scientific American. Suntem încă confuzi până astăzi.

Dar Ulam nu mâzgăla niște căsuțe sau bărci sau mașini ca un om normal. Nu. A scris numerele în spirală. Apoi încercuiește toate numerele prime. Apoi s-a uitat la ceea ce crease cu groaza răsărită a unui om care a văzut prea multe.
Deci de unde vine spirala? Începeți cu 1 la mijloc. Scrieți numărul într-o spirală spre exterior. Și apoi evidențiați toate numerele prime. Dacă desenați destul de lungi linii diagonale vor apărea.


Funcția primară are poziția inițială și direcțiile calculate, pentru a avea simetria diagramei.
ulam_prime_spiral <- function(
n = 51,
theme = c("Cosmic","Blueish","Classy","Psycho"),
show_nums = FALSE, # print values (n ≤ 21 only)
animate = FALSE,
speed = 1,
verbose = TRUE
) {
theme <- match.arg(theme)
#n must be odd so integers have a unique centre cell
if (n %% 2 == 0) { n <- n + 1L }
if (n < 5) stop("Size muste be > 5.")
total <- n^2
mid <- (n + 1L) / 2L
dr <- c( 0L, -1L, 0L, 1L) # row deltas: E N W S
dc <- c( 1L, 0L, -1L, 0L) # col deltas: E N W S
mat <- matrix(0L, n, n)
ord_r <- integer(total)
ord_c <- integer(total)
r <- mid;
cc <- mid
mat(r, cc) <- 1L
ord_r(1) <- r
ord_c(1) <- cc
d <- 1L # current direction index (1=E 2=N 3=W 4=S)
step <- 1L # current arm length
num <- 2L
while (num <= total) {
for (half in 1:2) { # each dir is twice
for (i in seq_len(step)) {
r <- r + dr(d)
cc <- cc + dc(d)
mat(r, cc) <- num
ord_r(num) <- r
ord_c(num) <- cc
num <- num + 1L
if (num > total) break
}
d <- (d %% 4L) + 1L # turn left: E→N→W→S→E
if (num > total) break
}
step <- step + 1L
}
și determinăm primul:
# Sieve of Eratosthenes
is_prime <- rep(TRUE, total)
is_prime(1) <- FALSE
p <- 2L
while (p * p <= total) {
if (is_prime(p))
is_prime(seq.int(p * p, total, p)) <- FALSE
p <- p + 1L
}
prime_mat <- matrix(is_prime(mat), n, n)
n_primes <- sum(prime_mat)
density <- 100 * n_primes / total
Pentru tipul de imagini (Classy, Psycho, Blueish și Cosmic), dacă decideți să creați o grilă mai mică de 21×21, puteți avea și numerele afișate. Și, desigur, diagonalele sunt și ele vizibile:


Verificați depozitul pentru actualizări viitoare!
Rămâi sănătos și fericit cu codificarea R!
