Ruby – determinați dacă un număr este un număr prim (Programare, Ruby)

Jaco Pretorius a intrebat.

Am trecut prin problemele de pe Proiectul Euler pentru a mă învăța programare în Ruby. Știu că există o funcție încorporată pentru a face acest lucru, dar evit funcțiile încorporate pentru a mă ajuta să învăț.

Așadar, trebuie să scriu o metodă pentru a determina dacă un număr este un prim. Prima metodă funcționează, dar a doua nu. Poate cineva să explice de ce?

 def is_prime n
  for d in 2..(n - 1)
   if (n % d) == 0
    return false
   end
  end

  true
 end

 def is_prime2 n
  foundDivider = false
   for d in 2..(n - 1)
    foundDivider = ((n % d) == 0) or foundDivider
   end
  not foundDivider
 end

Comentarii

  • Acesta nu este un răspuns la întrebarea ta… dar de ce verifici toate aceste numere după ce ai constatat că nu este un număr prim? Ați deja un răspuns definitiv la întrebarea ta. –  > Por Donal Fellows.
  • Da, mi-am dat seama de asta – dar am făcut-o în acest fel pentru a mă asigura că știu cum funcționează operatorii booleeni în Ruby –  > Por Jaco Pretorius.
  • Un algoritm mai eficient poate fi dezvoltat cu următoarea abordare: nu iterați peste numerele pare (nu doar săriți peste ele) și reduceți bucla la 5-10% din dimensiunea originală. Detaliile sunt aici: stackoverflow.com/questions/26792960/… –  > Por Anatoly.
13 răspunsuri
Chris Schmich

Se datorează faptului că = are o precedență mai mare decât or. Consultați Tabelul de precedență a operatorilor din Ruby de mai jos (de la cea mai mare la cea mai mică precedență):

[ ] [ ]=
**
! ~ + -
* / %
+ -
>> <<
&
^ |
<= < > >=
<=> == === != =~ !~
&&
||
.. ...
? :
= %= { /= -= += |= &= >>= <<= *= &&= ||= **=
defined?
not
or and
if unless while until
begin/end

Linia problematică este analizată ca…

(foundDivider = ((n % d) == 0)) or foundDivider

…ceea ce cu siguranță nu este ceea ce ați vrut să spuneți. Există două soluții posibile:

Forțați precedența să fie cea pe care o doriți cu adevărat…

foundDivider = (((n % d) == 0) or foundDivider)

… sau folosiți || care are o precedență mai mare decât =:

foundDivider = ((n % d) == 0) || foundDivider

Comentarii

  • Acesta este motivul pentru care iubesc StackOverflow. Mulțumesc foarte mult –  > Por Jaco Pretorius.
  • Frumos. Am găsit întrebarea și răspunsul utile! Și eu parcurg Proiectul Euler pentru a învăța Ruby. O sugestie de îmbunătățire a performanței pe care o am este să schimbăm intervalul din 2..(n-1) în 2..(Math.sqrt(n)); reduce semnificativ numărul de iterații. –  > Por Prakash Murthy.
  • scrierea foundDivider ||= ((n%d) == 0) va fi mai bună. –  > Por Deepender Singla.
miksiii

Ruby vine cu clase predefinite, cum ar fi Prime. Tot ce trebuie să faceți este să solicitați clasa respectivă în proiectul dumneavoastră.

require 'prime'

Apoi, puteți utiliza unele dintre metodele Prime, cum ar fi first pentru a obține primele x elemente prime:

Prime.first(5) # Ret => [2, 3, 5, 6, 11]

Sau puteți face ceva de genul acesta:

Prime.each(100) do |prime|
  p prime # Ret => [2, 3, 5, 7, 11, ..., 97]
end

Sper să vă fie de folos.

Darkmouse
def prime(n)
  return false if n < 2

  (2..n/2).none?{|i| n % i == 0}
end

Un număr prim este orice număr care nu are alți divizori pozitivi în afară de el însuși și de 1.

Manish Shrivastava

Găsiți numere prime din buclă:

def get_prime_no_upto(number)
  pre = [1]
  start = 2
  primes = (start..number).to_a
  (start..number).each do |no|
    (start..no).each do |num|
      if ( no % num  == 0) && num != no
        primes.delete(no)
        break
      end
    end
  end
  pre + primes
end

și folosiți-l ca mai jos:

puts get_prime_no_upto(100)

Noroc!

Saleh Rastani
def prime? n
  (2..Math.sqrt(n)).none? {|f| n % f == 0}
end

Intervalul de factori ar trebui să înceapă la 2 și să se termine la rădăcina pătrată a lui n, deoarece fiecare număr este divizibil cu unu și niciun număr nu este divizibil cu două numere mai mari decât rădăcina sa pătrată.

Explicație: Un număr non-prim este produsul a două numere.

n = f1 * f2

n este întotdeauna divizibil cu rădăcina sa pătrată, astfel încât atât f1 și f2 nu pot fi mai mari decât rădăcina pătrată a lui n, altfel f1 * f2 ar fi mai mare decât n. Prin urmare, cel puțin un factor este mai mic sau cel mult egal cu Math.sqrt(n). În cazul găsirii numerelor prime, este necesar să găsim doar un singur factor, astfel încât ar trebui să facem o buclă de la 2 până la rădăcina pătrată a lui n.

abonn

Iată codul care vă va solicita să introduceți un număr pentru verificarea numerelor prime:

puts "welcome to prime number check"
puts "enter number for check: "
  n = gets
  n = n.to_i

def prime(n)
  puts "That's not an integer." unless n.is_a? Integer
  is_prime = true
  for i in 2..n-1
    if n % i == 0
      is_prime = false
    end
  end
  if is_prime
    puts "#{n} is prime!"
  else
    puts "#{n} is not prime."
  end
end

prime(n)

Alberto

Bazat pe răspunsul lui Darmouse, dar incluzând cazuri limită

def prime? (n)
    if n <= 1
        false
    elsif n == 2
        true
    else 
        (2..n/2).none? { |i| n % i == 0}
    end
end

Jordan Poulton

FYI – re: DarkMouses metoda prime de mai sus – am găsit-o foarte utilă, dar există câteva erori (cred!) care trebuie explicate:

Ar trebui să fie paranteze în loc de paranteze pătrate… În caz contrar, veți obține o eroare de tip TypeError

Range can't be coerced into Fixnum (TypeError)

În al doilea rând, acele două puncte înainte de „false” ar cauza și ele o eroare. Este o sintaxă incorectă, din câte știu eu. Scapă de ea.

În cele din urmă, cred că ai înțeles greșit? Dacă corectați erorile pe care le-am menționat, se returnează true dacă nu este un prim, și false dacă este.

Poți renunța la operatorul ternar cu totul, cred, și să faci doar:

def prime?(n)
  (2..n/2).none?{|i| n % i == 0} 
end

Evident, nu acoperă cazurile limită (0,1,2), dar să nu împărțim firele de păr.

…Pentru cei cărora le place să se împartă în două, iată soluția mea completă la această problemă:

    def prime?(n)
      return false if n < 2
      (2..Math.sqrt(n)).none? {|num| length % num == 0}
    end

Sper că nu mi-a scăpat nimic 🙂

Ulysse BN

Acest lucru este un pic în afara subiectului conform detaliilor, dar corect pentru titlu : folosind integrarea bash în ruby ai putea face :

def is_prime n
    `factor #{n}`.split.count < 3
end

bash factor funcția returnează un număr plus toți factorii lui, deci dacă numărul este prim, se vor număra două cuvinte.

Acest lucru este util pentru cod golf numai.

Praetorian

Am încercat acest lucru și a funcționat:

def prime?(n)
  return false if n < 2 
  return true if n == 3 || n == 2 
    if (2...n-1).any?{|i| n % i == 0}
      false
    else
      true
    end
end

Arnold
def prime?(n)
  if n <= 1
  return false

  else (2..n-1).to_a.all? do |integer|
   n % integer != 0

   end
  end
end

Din laboratorul meu de prim? Am început prin a elimina toate numerele întregi mai mici sau egale cu 1.

Nsikan Sylvester
def prime(n)
    pn = [2]
    if n < 2
       return false

   else

     (2..n).each do |i|
       not_prime = false

        (2..Math.sqrt(i).ceil).each do |j|
           not_prime = true if i % j == 0    
        end
       pn.push(i) unless not_prime
    end

 end

return pn

end

p prime(30) dă

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

sounish nath

** PENTRU O METODĂ SIMPLĂ DE PRESCURTARE**MAI ÎNTÂI INSTALAȚI PRIME GEM

require 'prime'
`p prime.first(20)`

Acum salvați acel fișier cu numele dorit, acesta va genera primele 20 de numere prime în mod automat!!! 🙂

Tags: