The following is a method I wrote to calculate a value in the Fibonacci sequence:
def fib(n)
if n == 0
return 0
end
if n == 1
return 1
end
if n >= 2
return fib(n-1) + (fib(n-2))
end
end
It works uptil n = 14, but after that I get a message saying the program is taking too long to respond (I'm using repl.it). Anyone know why this is happening?
Naive fibonacci makes a lot of repeat calculations - in fib(14) fib(4) is calculated many times.
You can add memoization to your algorithm to make it a lot faster:
def fib(n, memo = {})
if n == 0 || n == 1
return n
end
memo[n] ||= fib(n-1, memo) + fib(n-2, memo)
end
fib 14
# => 377
fib 24
# => 46368
fib 124
# => 36726740705505779255899443
As others have pointed out, your implementation's run time grows exponentially in n. There are much cleaner implementations.
Constructive [O(n) run time, O(1) storage]:
def fib(n)
raise "fib not defined for negative numbers" if n < 0
new, old = 1, 0
n.times {new, old = new + old, new}
old
end
Memoized recursion [O(n) run time, O(n) storage]:
def fib_memo(n, memo)
memo[n] ||= fib_memo(n-1, memo) + fib_memo(n-2, memo)
end
def fib(n)
raise "fib not defined for negative numbers" if n < 0
fib_memo(n, [0, 1])
end
Recursive powers of a matrix multiplication using squared halving of the power for when you just gotta know really big factorials like 1_000_000.fib [O(log n) run time and storage (on stack)]:
def matrix_fib(n)
if n == 1
[0,1]
else
f = matrix_fib(n/2)
c = f[0] * f[0] + f[1] * f[1]
d = f[1] * (f[1] + 2 * f[0])
n.even? ? [c,d] : [d,c+d]
end
end
def fib(n)
raise "fib not defined for negative numbers" if n < 0
n.zero? ? n : matrix_fib(n)[1]
end
Your program has exponential runtime due to the recursion you use.
Expanding only the recursive calls a few levels to show you why:
fib(14) = fib(13) + fib(12)
= (fib(12) + fib(11)) + (fib(11) + fib (10))
= (((fib(11) + fib(10)) + (fib(10) + fib(9))) (((fib(10) + fib(9)) + (fib(9) + fib(8)))
= ... //a ton more calls
The terrible runtime might be causing your program to hang, as increasing fib(n) by 1 means you have a TON more recursive calls
your program overflows as Kevin L explained.
instead, you can use an iterative algorithm like this:
def fib (n)
return 0 if n == 0
return 1 if n == 1 or n == 2
x = 0
y = 1
(2..n).each do
z = (x + y)
x = y
y = z
end
return y
end
(0..14).map { |n| fib(n) }
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]
I tried comparing the run time of two fibonacci methods on repl.it
require 'benchmark'
def fib_memo(n, memo = {})
if n == 0 || n == 1
return n
end
memo[n] ||= fib_memo(n-1, memo) + fib_memo(n-2, memo)
end
def fib_naive(n)
if n == 0 || n == 1
return n
end
fib_naive(n-1) + fib_naive(n-2)
end
def time(&block)
puts Benchmark.measure(&block)
end
time {fib_memo(14)}
time {fib_naive(14)}
Output
0.000000 0.000000 0.000000 ( 0.000008)
0.000000 0.000000 0.000000 ( 0.000099)
As you can see, the runtime is quite different. As #Uri Agassi suggested, use memoization. The concept is explained quite well here https://stackoverflow.com/a/1988826/5256509
Related
I have solved a Codewars kata, but I can not submit it because my code takes too long. A lot of people had this problem, but we can not see the solution. The problem is, that generating the prime numbers takes too long (more than 12s) (I generate the primes with a method).
In my computer, I can require the class Prime, and this solves the problem. But in Codewar one can not require the class Prime, therefore, my method of generating prime numbers is too slow.
Any help?
require "pry"
def primeFactors(n)
start_time = Time.now
puts start_time
# find prime numbers smaller than n
nums = (2..(n-1)).to_a
odd_nums = nums.select { |num| num.odd? }
primes = odd_nums.select do |num|
is_prime(num)
end
end_time = Time.now
duration = end_time - start_time
puts end_time
# divide until mod is 1
dividend = n
res_primes = []
while dividend > 1
primes.each do |prime| # prime divisor
new_dividend = dividend.to_f / prime
remainder = dividend % prime
if remainder.zero?
dividend = new_dividend
res_primes << prime
break
end
end
end
freqs = {}
res_primes.each do |res_prime|
freqs[res_prime] = res_primes.count(res_prime)
end
res_string = []
freqs.keys.each do |key|
if freqs[key] == 1
res_string << "(#{key})"
else
res_string << "(#{key}**#{freqs[key]})"
end
end
res_string.join
end
def is_prime(n)
(2..n/2).none?{|i| n % i == 0}
end
Well for starters you really only need to test to Math.sqrt(n).to_i + 1 that should help for larger n values.
This is because if a factor exists where n = a * b then either
If a == b == sqrt(n) # Basically the defn of sqrt
or
If a != b; a < sqrt(n); b > sqrt(n)
If both a and b are less than sqrt(n) then a * b < n
and
If both a and b are greater than sqrt(n) the a * b > n
Secondly, and this is more complex, you only need to test prime numbers to that limit. I could envision a scheme where primes are cached.
Hope this helps.
The more advanced option might look like this:
# Is this number a prime?
module PrimeChecker
#prime_cache = [2,3]
def self.prime?(n)
search_limit = Math.sqrt(n).to_i + 1
last_cache = #prime_cache[-1]
while last_cache < search_limit do
last_cache += 2
#prime_cache << last_cache if PrimeChecker.prime?(last_cache)
end
#prime_cache.each do |pn|
return true if pn > search_limit
return false if (n % pn) == 0
end
true
end
end
# Sample run
#
# 31 mysh>%=PrimeChecker.prime?(1_000_000_000_000)
# false
# Elapsed execution time = 1.592 seconds.
#
This running on an elderly machine with a slow CORE 2 Duo processor.
Im learning Ruby and currently this is my exercise:
Using any pair of numbers, prove integer n is a Perfect Power. If there are no pairs, return nil.
In mathematics, a perfect power is a positive integer that can be expressed as an integer power of another positive integer. More formally, n is a perfect power if there exist natural numbers m > 1, and k > 1 such that mk = n
Currently this is my code:
def pp(n)
# [m,k] m^k
idx1=2
while idx1 <n
idx2=2
while idx2<n
if idx1**idx2 == n
ans = [idx1,idx2]
break
end
idx2 +=1
end
idx1 +=1
end
return ans
end
I would like to write this such that for a given random huge number my repl.it does not time out.
Thank you in advance!
###Edit###
There is a mention(How to make perfect power algorithm more efficient?) of this problem in the context of Python. As much as I tried to understand it and translate the syntax, I could not. I hope that asking this question will also help those studying Ruby as much as it has helped me.
You could use the prime factorization:
require 'prime'
def pp(n)
pd = n.prime_division
k = pd.map(&:last).reduce(&:gcd)
return if k < 2
m = pd.map { |p, e| p**(e / k) }.reduce(:*)
[m, k]
end
For example for n = 216 you get [[2, 3], [3, 3]], meaning 216 = 23⋅33. Then find the greatest common divisor of the exponents, which is the greatest possible exponent k. If it's less than 2, you lose. Otherwise, compute the base m from the pieces.
Yours takes my PC about 4.1 seconds to check the numbers from 2 to 200. Mine takes about 0.0005 seconds for that, and takes about 2.9 seconds to check the numbers 2 to 400000.
Wanna solve really large numbers like this instantaneously? With a much shorter solution?
pp(908485319620418693071190220095272672648773093786320077783229)
=> [29, 41]
Then read on :-). It'll be a little journey...
Let's first just make your code nicer without changing the logic at all. Just rename your variables to m and k and loop with each:
def pp1(n)
ans = nil
(2...n).each do |m|
(2...n).each do |k|
if m**k == n
ans = [m, k]
break
end
end
end
ans
end
Now checking n up to 200 takes me about 4.1 seconds (same as your original):
> require 'benchmark'
> puts Benchmark.measure { (1..200).each { |n| pp1(n) } }
4.219000 0.000000 4.219000 ( 4.210381)
First optimization: If we find a solution, return it right away!
def pp2(n)
(2...n).each do |m|
(2...n).each do |k|
if m**k == n
return [m, k]
end
end
end
nil
end
Sadly it still takes 3.9 seconds for the test. Next optimization: If mk is already too large, let's not try even larger k!
def pp3(n)
(2...n).each do |m|
(2...n).each do |k|
break if m**k > n
if m**k == n
return [m, k]
end
end
end
nil
end
Now it's so fast that I can run the test 1000 times in about the same time:
> puts Benchmark.measure { 1000.times { (1..200).each { |n| pp3(n) } } }
4.125000 0.000000 4.125000 ( 4.119359)
Let's instead go up to n = 5000:
> puts Benchmark.measure { (1..5000).each { |n| pp3(n) } }
2.547000 0.000000 2.547000 ( 2.568752)
Now instead of computing m**k so much, let's use a new variable that we can update more cheaply:
def pp4(n)
(2...n).each do |m|
mpowk = m
(2...n).each do |k|
mpowk *= m
break if mpowk > n
if mpowk == n
return [m, k]
end
end
end
nil
end
Sadly, this almost didn't make it faster at all. But there's another optimization: When mk is too large, then not only can we forget trying this m with even larger k. If it was too large for k=2, i.e., m2 is already too large, then we don't need to try even larger m, either. We can stop the whole search. Let's try that:
def pp5(n)
(2...n).each do |m|
mpowk = m
(2...n).each do |k|
mpowk *= m
if mpowk > n
return if k == 2
break
end
if mpowk == n
return [m, k]
end
end
end
nil
end
This now does the 5000-test in about 0.07 seconds! We can even check all numbers up to 100000 in 6 seconds:
> puts Benchmark.measure { (1..100000).each { |n| pp5(n) } }
5.891000 0.000000 5.891000 ( 5.927859)
Anyway, let's look at the big picture. We're trying m = 2.. and for each m we try to find a k so that m**k == n. Hey, math has a solution for that! We can compute k as k=logm(n). Let's do it:
def pp6(n)
(2...n).each do |m|
k = Math.log(n, m).round
return if k < 2
return [m, k] if m**k == n
end
nil
end
Measure again:
> puts Benchmark.measure { (1..100000).each { |n| pp6(n) } }
28.797000 0.000000 28.797000 ( 28.797254)
Hmm, slower. Ok, another idea: Let the outer loop be for k instead of m. Now for given n and k, how do we find m such that mk = n? Take the k-th root!
def pp7(n)
(2...n).each do |k|
m = (n**(1.0 / k)).round
return if m < 2
return [m, k] if m**k == n
end
nil
end
Measure again:
> puts Benchmark.measure { (1..100000).each { |n| pp7(n) } }
0.828000 0.000000 0.828000 ( 0.836402)
Nice. How about 400000, which my factorization solution in my other answer solved in 2.9 seconds?
> puts Benchmark.measure { (1..400000).each { |n| pp(n) } }
3.891000 0.000000 3.891000 ( 3.884441)
Ok that's a bit slower. But... with this solution here we can solve really large numbers:
pp7(1000000035000000490000003430000012005000016807)
=> [1000000007, 5]
pp7(908485319620418693071190220095272672648773093786320077783229)
=> [29, 41]
> pp7(57248915047290578345908234051234692340579013460954153490523457)
=> nil
And all these result appears immediately. The factorization solution solves the 2941 case quickly as well, but for the 10000000075 case and the randomly-typed case at the end it's slow, because the factorization is slow.
P.S. Note that the logarithm and square root get us floating point numbers. That could lead to problems with very large numbers. For example:
irb(main):122:0> pp7(10**308 + 1)
=> nil
irb(main):123:0> pp7(10**309 + 1)
FloatDomainError: Infinity
from (irb):82:in `round'
from (irb):82:in `block in pp7'
from (irb):81:in `each'
from (irb):81:in `pp7'
from (irb):123
from C:/Ruby24/bin/irb.cmd:19:in `<main>'
In this case, that's because 10309 simply is too large for floats:
> (10**309).to_f
=> Infinity
Also, there could be accuracy problems with large enough numbers. Anyway, you can solve these issues by writing integer-versions for logarithm and root. But that's a whole other issue.
While trying to solve the "paths on a grid" problem, I have written the code
def paths(n, k)
p = (1..n+k).to_a
p.combination(n).to_a.size
end
The code works fine, for instance if n == 8 and k == 2 the code returns 45 which is the correct number of paths.
However the code is very slow when using larger numbers and I'm struggling to figure out how to quicken the process.
Rather than building the array of combinations just to count it, just write the function that defines the number of combinations. I'm sure there are also gems that include this and many other combinatorics functions.
Note that I am using the gem Distribution for the Math.factorial method, but that is another easy one to write. Given that, though, I'd suggest taking #stefan's answer, as it's less overhead.
def n_choose_k(n, k)
Math.factorial(n) / (Math.factorial(k) * Math.factorial(n - k))
end
n_choose_k(10, 8)
# => 45
Note that the n and k here refer to slightly different things than in your method, but I am keeping them as it is highly standard nomenclature in combinatorics for this function.
def combinations(n, k)
return 1 if k == 0 or k == n
(k + 1 .. n).reduce(:*) / (1 .. n - k).reduce(:*)
end
combinations(8, 2) #=> 28
Explanation about the math part
The original equation is
combinations(n, k) = n! / k!(n - k)!
Since n! / k! = (1 * 2 * ... * n) / (1 * 2 * ... * k), for any k <= n there is a (1 * 2 * ... * k) factor both in the numerator and in the denominator, so we can cancel this factor. This makes the equation become
combinations(n, k) = (k + 1) * (k + 2) * ... * (n) / (n - k)!
which is exactly what I did in my Ruby code.
The answers that suggest computing full factorials will generate lots of unnecessary overhead when working with big numbers. You should use the method below for calculating the binomial coefficient: n!/(k!(n-k)!)
def n_choose_k(n, k)
return 0 if k > n
result = 1
1.upto(k) do |d|
result *= n
result /= d
n -= 1
end
result
end
This will perform the minimum operations needed. Note that incrementing d while decrementing n guarantees that there will be no rounding errors. For example, {n, n+1} is guaranteed to have at least one element divisible by two, {n, n+1, n+2} is guaranteed to have at least one element divisible by three and so on.
Your code can be rewritten as:
def paths(x, y)
# Choice of x or y for the second parameter is arbitrary
n_choose_k(x + y, x)
end
puts paths(8, 2) # 45
puts paths(2, 8) # 45
I assume that n and k in the original version were meant to be dimensions so i labeled them x and y instead. There's no need to generate an array here.
Edit: Here is a benchmark script...
require 'distribution'
def puts_time
$stderr.puts 'Completed in %f seconds' % (Time.now - $start_time)
$start_time = Time.now
end
def n_choose_k(n, k)
return 0 if k > n
result = 1
1.upto(k) do |d|
result *= n
result /= d
n -= 1
end
result
end
def n_choose_k_distribution(n, k)
Math.factorial(n) / (Math.factorial(k) * Math.factorial(n - k))
end
def n_choose_k_inject(n, k)
(1..n).inject(:*) / ((1..k).inject(:*) * (1..n-k).inject(:*))
end
def benchmark(&callback)
100.upto(300) do |n|
25.upto(75) do |k|
callback.call(n, k)
end
end
end
$start_time = Time.now
puts 'Distribution gem...'
benchmark { |n, k| n_choose_k_distribution(n, k) }
puts_time
puts 'Inject method...'
benchmark { |n, k| n_choose_k_inject(n, k) }
puts_time
puts 'Answer...'
benchmark { |n, k| n_choose_k(n, k) }
puts_time
Output on my system is:
Distribution gem...
Completed in 1.141804 seconds
Inject method...
Completed in 1.106018 seconds
Answer...
Completed in 0.150989 seconds
Since you're interested in the count rather than the actual combination sets, you should do this with a choose function. The mathematical definition involves evaluating three different factorials, but there's a lot of cancellation going on so you can speed it up by using ranges to avoid the calculations that will be cancelled anyway.
class Integer
def choose(k)
fail 'k > n' if k > self
fail 'args must be positive' if k < 0 or self < 1
return 1 if k == n || k == 0
mm = [self - k, k].minmax
(mm[1]+1..self).reduce(:*) / (2..mm[0]).reduce(:*)
end
end
p 8.choose 6 # => 28
To solve your paths problem, you could then define
def paths(n, k)
(n + k).choose(k)
end
p paths(8, 2) # => 45
The reduce/inject versions are nice. But since speed seemed to be a bit of an issue, I'd suggest the n_choose_k versions from #google-fail.
It is quite insightful and suggests a ~10-fold speed increase.
I would suggest that the iteration use the Lesser of k and ( n - k ).
N-choose-K and N-choose-(N-K) produce the same result (the factors in the denominator are simply reversed). So something like a 52-choose-51 could be done in one iteration.
I usually do the following:
class Integer
def !
(2..self).reduce(1, :*)
end
def choose(k)
self.! / (k.! * (self-k).!)
end
end
Benchmarking:
k = 5
Benchmark.bm do |x|
[10, 100, 1000, 10000, 100000].each do |n|
x.report("#{n}") { n.choose(k) }
end
end
On my machine I get:
user system total real
10 0.000008 0.000001 0.000009 ( 0.000006)
100 0.000027 0.000003 0.000030 ( 0.000031)
1000 0.000798 0.000094 0.000892 ( 0.000893)
10000 0.045911 0.013201 0.059112 ( 0.059260)
100000 4.885310 0.229735 5.115045 ( 5.119902)
Not the fastest thing on the planet, but it's okay for my uses. If it ever becomes a problem, then I can think about optimizing
I am writing Pascal's triangle in Ruby, but keep getting the error message:
pascalsTriangle.rb:3:in 'triangle': undefined method `each' for
4:Fixnum (NoMethodError) from pascalsTriangle.rb:18
def triangle(n)
for r in n:
lst=[1]
term=1
k=0
(0..r+1).step(1){ |index|
term=term*(r-k+1)/k
lst.append(term)
k+=1
}
print lst
end
end
triangle(4)
Why code C style in Ruby? :-)
Breaking the problem down would allow you to concentrate on one problem at a time and iterators would make the code more readable. I'm using the binomial theorem to calculate the values in the triangle. If you don't need a super large value from the triangle, this will be fast enough.
Calculating the 1000th line took 2.9 seconds on my virtual linux:
# factorial method
def fact(n)
(1..n).reduce(:*)
end
# binomial theorem, n choose k
def binomial(n,k)
return 1 if n-k <= 0
return 1 if k <= 0
fact(n) / ( fact(k) * fact( n - k ) )
end
def triangle(nth_line)
(0..nth_line).map { |e| binomial(nth_line, e) }
end
p triangle(5)
the final source code:
def triangle(n)
(0..n).each{|r|
lst=[1]
term=1
k=1
(0..r-1).step(1){|index|
term=term*(r-k+1)/k
lst.push term
k+=1
}
p lst
}
end
triangle(4)
changes:
you have syntax error on for r in n:.
a logical error on k=0 that causes Division by zero.
(0..r+1) is changed to (0..r-1)
there is no append method for array. changed to push
p is used instead of print
Factorial(num), takes a number and return the factorial of it.
find_num(n, k), is the mathmatical formula of pascales triangle. !n/
!k * !(n - k) ---- '!' = factorial of number
Lastly pascale(num), this iterates a new row of the triangle by
maping the index numbers or (k) for each row of (n).
If you want to truly understand how this works comment out the
pascale, and simply run numbers through find_num((row number),
(index number)). Then compare to a picture of the triangle to see
the magic for your self
-
def find_num(n, k)
result = factorial(n) / (factorial(k) * factorial(n - k))
end
def pascale(num)
i = 0
scale = 75
while i <= num
new_arr = []
(0..i).map {|x| new_arr << find_num(i, x)}
p new_arr.to_s.rjust(50 + scale)
i += 1
scale += 1
end
def factorial(num)
if num == 0
return 1
else
num *= factorial(num - 1)
end
end
end
pascale(12)
I'm running through the problems on Project Euler to teach myself Ruby programming. I know there is a built-in function to do this, but I'm avoiding the built-in functions to help me learn.
So I have to write a method to determine if a number is a prime. The first method works, but the second doesn't. Can anyone explain why?
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
It's because = is of higher precedence than or. See Ruby's operator precedence table below (highest to lowest precedence):
[ ] [ ]=
**
! ~ + -
* / %
+ -
>> <<
&
^ |
<= < > >=
<=> == === != =~ !~
&&
||
.. ...
? :
= %= { /= -= += |= &= >>= <<= *= &&= ||= **=
defined?
not
or and
if unless while until
begin/end
The problematic line is being parsed as...
(foundDivider = ((n % d) == 0)) or foundDivider
...which is certainly not what you mean. There are two possible solutions:
Force the precedence to be what you really mean...
foundDivider = (((n % d) == 0) or foundDivider)
...or use the || operator instead, which has higher precedence than =:
foundDivider = ((n % d) == 0) || foundDivider
Ruby comes with predefined classes such as Prime. All you have to do is to require that class into your project.
require 'prime'
Than, you can use some of the Prime methods such as first to get first x prime elements:
Prime.first(5) # Ret => [2, 3, 5, 6, 11]
Or you could do something like this:
Prime.each(100) do |prime|
p prime # Ret => [2, 3, 5, 7, 11, ..., 97]
end
I hope you find this useful.
def prime(n)
return false if n < 2
(2..n/2).none?{|i| n % i == 0}
end
A prime number is any number that has no positive divisors other than itself and 1.
def prime? n
(2..Math.sqrt(n)).none? {|f| n % f == 0}
end
The range of factors should start at 2 and end at the square root of n because every number is divisible by one and no number is divisible by two numbers greater than its square root.
Explanation: A non-prime number is the product of two numbers.
n = f1 * f2
n is always divisible by its square root so both f1 and f2 cannot be greater than the square root of n, otherwise f1 * f2 would be greater than n. Therefore, at least one factor is less than or at most equal to Math.sqrt(n). In the case of finding prime numbers its only necessary to find one factor so we should loop from 2 to the square root of n.
Find prime numbers from loop:
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
and use it as below:
puts get_prime_no_upto(100)
Cheers!
Here is code that will prompt you to enter a number for prime check:
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)
Based on the answer by Darmouse but including edge cases
def prime? (n)
if n <= 1
false
elsif n == 2
true
else
(2..n/2).none? { |i| n % i == 0}
end
end
FYI - re: DarkMouses prime method above - I found it really helpful, but there are a few errors (I think!) that need explaining:
It should be parentheses rather than square brackets... Otherwise you get a TypeError
Range can't be coerced into Fixnum (TypeError)
Secondly, that first colon before 'false' would cause an error too. It's incorrect syntax, as far as I know. Get rid of it.
Lastly, I think you got it the wrong way round?? If you correct the errors I mentioned, it returns true if it ISN'T a prime, and false if it IS.
You can drop the ternary operator altogether I think, and just do:
def prime?(n)
(2..n/2).none?{|i| n % i == 0}
end
Obviously it doesn't cover the edge cases (0,1,2), but let's not split hairs.
...For those who enjoy hairsplitting, here is my full solution to this problem:
def prime?(n)
return false if n < 2
(2..Math.sqrt(n)).none? {|num| length % num == 0}
end
Hope I didn't miss anything :)
This is a little bit off topic according to the details, but correct for the title : using bash integration in ruby you could do :
def is_prime n
`factor #{n}`.split.count < 3
end
bash factor function returns a number plus all of his factors, so if the number is prime, there will be two words count.
This is usefull for code golf only.
I tried this and it worked:
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
def prime?(n)
if n <= 1
return false
else (2..n-1).to_a.all? do |integer|
n % integer != 0
end
end
end
From my prime? lab. Started with eliminating all integers less than or equal to 1.
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) gives
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
It will return true if the number is prime.
def prime_number(number)
(2..(number-1)).each do |value|
if (number % value) == 0
return false
end
return true
end
end
puts prime_number(4)
class Object
private
def prime? num
if (2..3).include? num
return true
else
!num.even? and num % 3 != 0 and num > 1
end
end
end
prime? 1
prime? 2
prime? 9
prime? 17
** FOR A SIMPLE SHORTED METHOD**
FIRST INSTALL PRIME GEM
require 'prime'
`p prime.first(20)`
Now save that file as your desired name, this will generate the first 20 prime numbers Automatically!! :-)