Mici funcții R inutile-utile – Ulam Prime Spiral

URMĂREȘTE-NE
16,065FaniÎmi place
1,142CititoriConectați-vă

(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.

Spirală primă Ulam (sau spirală Ulam scurtă) cu dimensiuni de 150 x 150 și un total de 2547 de numere prime (acoperire de 11,2 %).

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!

Dominic Botezariu
Dominic Botezariuhttps://www.noobz.ro/
Creator de site și redactor-șef.

Cele mai noi știri

Pe același subiect

LĂSAȚI UN MESAJ

Vă rugăm să introduceți comentariul dvs.!
Introduceți aici numele dvs.