I know similar questions have been asked before but they all seem so over complicated and I don't think i'm that far off, so was wondering if anyone knows how to tweak my code to get it to work. My goal is to save all prime numbers of a range into an array and then print that array. Below is my code so far
prime_array = []
(1...100).each do |num|
if Math.sqrt(num) % 2 == 0
prime_array.push(num)
end
end
prime_array
#=> [4, 16, 36, 64]
I've tried a few different options but have hit a wall and can't see what i need to do. I'm trying to keep it as simple as possible as I feel a lot of the answers out there a little over complicated. Thanks in advance.
Let's calculate the square root of 7 (a prime number) and 8 (a composite number):
Math.sqrt(7) #=> 2.6457513110645907
Math.sqrt(8) #=> 2.8284271247461903
This doesn't really help, does it? Apparently, you can't determine if a number is a prime number by calculating its square root.
Instead, you have to check the number's divisors. From Wikipedia:
A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.
Let's determine the divisors of 7: (using the modulo operator %)
7 % 1 #=> 0 <- 7 is divisible by 1
7 % 2 #=> 1
7 % 3 #=> 1
7 % 4 #=> 3
7 % 5 #=> 2
7 % 6 #=> 1
7 % 7 #=> 0 <- 7 is divisible by 7
This satisfies the above definition - 7 is a prime number.
Now, let's determine the divisors of 8:
8 % 1 #=> 0 <- 8 is divisible by 1
8 % 2 #=> 0 <- 8 is divisible by 2
8 % 3 #=> 2
8 % 4 #=> 0 <- 8 is divisible by 4
8 % 5 #=> 3
8 % 6 #=> 2
8 % 7 #=> 1
8 % 8 #=> 0 <- 8 is divisible by 8
8 has two additional divisors 2 and 4. Therefore, 8 is not a prime number.
In Ruby, you could use select to find the divisors:
(1..7).select { |d| 7 % d == 0 } #=> [1, 7]
(1..8).select { |d| 8 % d == 0 } #=> [1, 2, 4, 8]
Finally, here's a variant of your Ruby code that checks if a given number num has exactly two divisors, 1 and num itself:
prime_array = []
(1...100).each do |num|
if (1..num).select { |d| num % d == 0 } == [1, num]
prime_array.push(num)
end
end
prime_array
#=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
The above code can be optimized. I leave that to you.
Method that returns prime numbers in an array in ruby
def is_prime?(number)
return false if number <2
(2..Integer.sqrt(number)).each do |divisor|
return false if number % divisor == 0
end
return number
end
def read_array(array)
primes = []
array.each do |num|
primes << num if is_prime?(num)
end
return primes
end
Related
I was just curious as to how to change a number from number base m to another base n with a Ruby program, not a gem. Has anyone done this and would like to share their thoughts or ideas? Just thought it would be fun to try out a program like this :)
I've done it for bin to dec, dec to bin, dex to hex, hex to dec, but would want to know how to do it from m to n.
def bin2dec(num)
sum = 0
i = 0
while i < num.length
sum += 2 ** i * num[num.length - i - 1].to_i
i += 1
end
return sum
end
bin = gets.chomp
out = bin2dec(bin)
print out
def dec2bin(dec)
out = ""
num = dec
while num != 0
out = "#{num % 2}" + out
num = num / 2
end
return out
end
dec = gets.to_i
print dec2bin(dec)
These functions are built in.
To convert "EFFE" from base 16 (hex) to base 8 (octal)...
"EFFE".to_i(16).to_s(8)
# => "167776"
To put this in a method...
def convert_base(string, from_base, to_base)
string.to_i(from_base).to_s(to_base)
end
If you want a method which converts any positive base to any other positive base, start looking at Integer#digits. It takes an argument (10 by default), but nothing stops you from getting a number in base 543.
For 11 <= n <= 36, Ruby has a convention that allows integers to be expressed in base n with the 10 digits 0-9 and the first n-10 characters of the alphabet. It is for that reason that we obtain the following results:
1270.to_s(36) #=> "za"
"za".to_i(36) #=> 1270
1270.to_s(37) #=> ArgumentError (invalid radix 37)
"za".to_i(37) #=> ArgumentError (invalid radix 37)
Ruby's representation of integers, however, is just a convention.
I will only deal with non-negative integers and will refer to them as "numbers". Negative integers can be negated, converted to a number of a different base and then that number negated.
We could express numbers of any base as arrays of digits, where each digit is expressed as a base 10 integer. For example, we could write:
46 in base 10 as [4, 6]
za in base 36 as [36, 10]
a two-digit base N number as [n, m], where n and m are both between 0 and N-1.
We can write a method to convert a base 10 number to this array representation:
def base10_to_base_n(n10, radix)
arr = []
while n10 > 0
n10, rem = n10.divmod(radix)
arr << rem
end
arr.reverse
end
base10_to_base_n(123, 10)
#=> [1, 2, 3]
base10_to_base_n(131, 2)
#=> [1, 0, 0, 0, 0, 0, 1, 1]
abase10_to_base_n(1234, 16)
#=> [4, 13, 2]
base10_to_base_n(9234, 99)
#=> [93, 27]
Note that, in the third example:
4*(16**2) + 13*(16**1) + 2*(16**0) #=> 9234
Next we create a method that does the reverse: converts a number in a given base, described as an array of digits (the argument base_n) to a base 10 number.
def base_n_to_base_10(base_n, radix)
pow = 1
arr = base_n.reverse
base_n.reverse.reduce do |n10, digit|
pow *= radix
n10 + digit*pow
end
end
base_n_to_base_10([1, 2, 3], 10)
#=> 123
base_n_to_base_10([1, 0, 0, 0, 0, 0, 1, 1], 2)
#=> 131
base_n_to_base_10([4, 13, 2], 16)
#=> 1234
base_n_to_base_10([93, 27], 99)
#=> 9234
As expected, if
radix = 87
n10 = 6257
base87 = base10_to_base_n(n10, radix)
#=> [71, 80]
then:
base_n_to_base_10(base10_to_base_n(n10, radix), radix)
#=> 6257
base10_to_base_n(base_n_to_base_10(base87, radix), radix)
#=> [71, 80]
If you wanted to do it without the built-in methods...
def convert_base(string, from_base, to_base)
characters = (0..9).to_a + ('A'..'Z').to_a
string = string.to_s.upcase.gsub(/[^0-9A-Z]/i, '') # remove non alphanumeric
digits = string.split('')
decimal_value = digits.inject(0){|sum, digit| (sum * from_base) + characters.find_index(digit) }
result = []
while decimal_value > 0
result << characters[decimal_value % to_base]
decimal_value = decimal_value / to_base
end
result = result.join.reverse
return result if result.length > 0
'0'
end
convert_base('effe', 16, 8)
# => "167776"
I am trying to get the first num factorials.
For example if num is 6 then we would want the first 6 factorials: 1,1,2,6,24,120
Below is my current solution. It always returns an extra factorial. So if num is 6 it returns 7 factorials.
def factorials_rec(num)
return [1] if num == 1
arr = factorials_rec(num-1)
arr << num * arr.last
end
Result [1, 1, 2, 6, 24, 120, 720]
Desired result [1, 1, 2, 6, 24, 120]
I only want 6 factorials but 7 are being returned.
Using recursion, how can I adjust this function to return the desired number of factorials.
I have tried
base case = return [1,1] if num == 2, etc..
arr << num * arr.last unless arr.length >= num, etc...
Try fixing the last line to:
arr << (num-1) * arr.last
I am trying to find the sum of all multiples of 3 or 5 below 10
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
result = 0
numbers.each do |number|
if number % 3 == 0 or number % 5 == 0
result += number
end
print result
end
I receive this: 0033814141423, but I expect 23, as it's the sum of 3, 5, 6, 9.
Your print statement is inside the loop. It should be moved outside.
numbers = [1,2,3,4,5,6,7,8,9]
result = 0
numbers.each do |number|
if number % 3 == 0 or number % 5 == 0
result += number
end
end
print result
A proper indentation will also help you to catch these errors. Moreover, you should use p to print out an information, not print.
With p each output would have been done on a new line. That would probably be an hint to understand the issue.
This is also a possible alternative using Enumerable#inject with an accumulator.
numbers = [1,2,3,4,5,6,7,8,9]
numbers.inject(0) do |acc, number|
acc + case
when number % 3 == 0 then number
when number % 5 == 0 then number
else 0
end
end
And a more compact form
numbers = [1,2,3,4,5,6,7,8,9]
numbers.lazy.select { |n| n % 3 == 0 || n % 5 == 0 }.inject(:+)
You may use Array#select method.
result = 0
[1,2,3,4,5,6,7,8,9].select{|i| i % 3 == 0 || i % 5 == 0}.each do |num|
result += num
end
or more shortly with inject.
[1,2,3,4,5,6,7,8,9].select{|i| i % 3 == 0 || i % 5 == 0}.inject(:+)
Well, what I did was something like this:
(1...10).to_a.select{|i| i%3==0 or i%5==0}.sum
I'm writing a method - prime_numbers - that, when passed a number n, returns an n number of primes. It should not rely on Ruby's Prime class. It should behave like so:
prime_numbers 3
=> [2, 3, 5]
prime_numbers 5
=> [2, 3, 5, 7, 11]
My first attempt at this method is as follows:
def prime_numbers(n)
primes = []
i = 2
while primes.length < n do
divisors = (2..9).to_a.select { |x| x != i }
primes << i if divisors.all? { |x| i % x != 0 }
i += 1
end
primes
end
Edit: As pointed out, the current method is at fault by being limited to take into account divisors only up to 9. As a result, any perfect square composed of two equal primes greater than 9 is treated as a prime itself.
If anyone has input or tips they can share on better ways to approach this, it would be greatly appreciated.
Note that if the number is composite it must have a divisor less than or equal to $\sqrt{n}$. So you really only have to check up to $sqrt{n}$ to find a divisor.
Got a good idea for your implementation:
#primes = []
def prime_numbers(n)
i = 2
while #primes.size < n do
#primes << i if is_prime?(i)
i += 1
end
#primes
end
def is_prime?(n)
#primes.each { |prime| return false if n % prime == 0 }
true
end
This is based on the idea that non-prime numbers have prime factors :)
In Ruby 1.9 there is a Prime class you can use to generate prime numbers, or to test if a number is prime:
require 'prime'
Prime.take(10) #=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
Prime.take_while {|p| p < 10 } #=> [2, 3, 5, 7]
Prime.prime?(19) #=> true
Prime implements the each method and includes the Enumerable module, so you can do all sorts of fun stuff like filtering, mapping, and so on.
The goal is to see how insertion sort finds and inserts a number into a pre-sorted array. I'm supposed to pop the last number from the array and insert it into its correct chronological place in the array.
The code seems to work for the first example, but not the second. In the second example the correct answer seems to come in the fourth iteration even though there are integers in the array.
It feels like I need to break or return and stop looping somewhere, but I'm not sure where.
def insertionSort( ar)
count = ar.count
value = ar.pop
p ar << value if value >= ar.last
reversed = ar.reverse
ar.count.times do |index|
reversed.unshift(reversed.first) if reversed.count < count
if reversed[index + 1] > value
reversed[index] = reversed[index+1]
else
reversed[index] = value
end
puts reversed.reverse.join(' ')
end
end
ar = [2, 4, 6, 8, 3]
insertionSort( ar )
#=> 2 4 6 8 8
#=> 2 4 6 6 8
#=> 2 4 4 6 8
#=> 2 3 4 6 8
negatives = [-3, -6, 7, 8, 9, 5]
insertionSort( negatives )
#=> -3 -6 7 8 9 9
#=> -3 -6 7 8 8 9
#=> -3 -6 7 7 8 9
#=> -3 -6 5 7 8 9
#=> -3 5 5 7 8 9
I figured it out. I needed a break and a puts on the else statement.
def insertionSort( ar)
count = ar.count
value = ar.pop
p ar << value if value >= ar.last
reversed = ar.reverse
ar.count.times do |index|
reversed.unshift(reversed.first) if reversed.count < count
if reversed[index + 1] > value
reversed[index] = reversed[index+1]
puts reversed.reverse.join(' ')
elsif reversed[index + 1] == value
reversed.slice!(index)
puts reversed.reverse.join(' ')
break
else
reversed[index] = value
puts reversed.reverse.join(' ')
break
end
end
end
ar = [2, 4, 6, 8, 3]
insertionSort( ar )
negatives = [-3, -6, 7, 8, 9, 5]
insertionSort( negatives )