ruby won't print output - ruby

I'm trying to see if the user enters a prime number. I want it to print "PRIME" or "NOT PRIME" to screen:
prime = ""
puts "TYPE IN A NUMBER TO SEE IF IT'S PRIME: "
gets.chomp(prime).to_i
for divide_by in 2..(prime.to_i - 1)
if prime % divide_by == 0
puts "NOT PRIME!!!"
else
puts "PRIME!!!"
end
end
Should I use a while loop instead?

Your gets.chomp(prime).to_i is not doing anything significant. I don't understand the purpose of chomp here, and it is not assigning any variable. If you want to receive the input number as prime, you need to do prime = gets.to_i.
Once you do that, you do not need to do to_i again as in for divide_by in 2..(prime.to_i - 1).
Furthermore, your logic is flawed. If prime is not divisible by 2, is that enough to say "PRIME!!"? I don't think so.
And if you are wondering what type of loop to use, the for loop is rarely useful. You should use each.

Related

Code won't function properly without the Integer method for Ruby to properly identify whether my input is either greater or less than when compared

I am brand new to programming. I am going through the Learn Ruby course on Codecademy. It's taking me through a exercise on experimenting with else/if statements. I'm attempting to run code where you input two integers (n and y) and print a statement based on whether n > y, n < y, or n == y.
As an example, when I input n = 5 and y = 15, it would print out the statement "I'm getting printed because n is greater than y) despite that not being true. Some set of numbers would print the correct statement, some set of numbers (as the one above) always printed the incorrect statement. After about 30 minutes of trying to figure out why it wouldn't work, I attempted adding the Integer method to my code and it works as intended. I'm just trying to understand why it wouldn't work properly prior to that.
Here is my code before:
print "Enter an integer for x:"
n = gets.chomp
print "Enter an integer for y:"
y = gets.chomp
if n < y
print "I'm getting printed because #{n} is less than #{y}"
elsif n > y
print "I'm getting printed because #{n} is greater than #{y}"
else
print "I'm getting printed because #{n} is equal to #{y}"
end
Here is my code after adding the Integer method:
print "Enter an integer for n:"
n = Integer(gets.chomp)
print "Enter an integer for y:"
y = Integer(gets.chomp)
if n < y
print "I'm getting printed because #{n} is less than #{y}"
elsif n > y
print "I'm getting printed because #{n} is greater than #{y}"
else
print "I'm getting printed because #{n} is equal to #{y}"
end
After going back in the lessons, I noticed an example Codecademy provided where they use the Integer method, but they do not go into detail about it. Regardless, I still added it to my code in the same fashion they used it in their example, and now it works properly. Like I said above, I just want to understand why it wouldn't work before and where it was going wrong in my code before I go any further in my lessons.
gets returns the string entered by the user, including the newline character created by pressing enter. gets.chomp removes the newline character at the end of the string, but still leaves the input a string.
And strings are sorted and compared alphabetically. "aa" < "b" correct when comparing strings and in the same sense "11" < "2" is correct for strings containing numbers.
But Integer(gets.chomp) translates the user input from a string containing a number into an integer (an actual number). And therefore the comparison works as expected afterward.
Documentation of the methods in play:
Kernel#gets
String#chomp
Kernel#Integer

Understanding this Ruby program concerned with prime numbers

This is a program that came from a textbook:
# Initialize our counter
i = 1
# i: [0, 100]
while (i <= 100)
# Initialize prime flag
prime_flag = true
j = 2
# Test divisibility of i from [0, i/2]
while (j <= i / 2)
# puts " i ==> " to i.to_s + " j ==> " + j.to_s
if (i % j == 0)
prime_flag = false
# break
end
j = j + 1
end
# We found a prime!
if prime_flag
puts "Prime ==> " + i.to_s
end
# Increment the counter
i += 1
end
The while (j <= i / 2) introduces a new loop. What if we are trying to find prime numbers. Why is this written? Prime numbers don't have square roots. What is the purpose of j being <= i / 2? I do not understand why j is introduced.
You are correct that you should be only checking numbers <= floor(sqrt(i)). The above code is unnecessarily checking numbers from ceil(sqrt(i)) through i/2. It would give the correct answer, however.
In addition, this is not very Ruby-like code. It's terrible and the author should feel terrible (unless they intended to show you something bad in order for you to be amazed when you see how you can write it better!).
Here's the same code done in a more Ruby-like manner. Note that prime? can definitely be a one-liner, but I split things on to more lines readability in the context of the question:
def prime?(i) # Define a function that takes 1 parameter `i`
MAX_NUM_TO_CHECK = Math.sqrt(i) # No need to check numbers greater than sqrt(i)
(2..MAX_NUM_TO_CHECK).all? do |j| # Return `true` if the following line is true for
# all numbers [2,MAX_NUM_TO_CHECK]
i % j != 0 # true if `i` is evenly not divisible by `j`. Any
# input that evaluates to false here is not prime.
end
end
# Test primality of numbers [1,100]
(1..100).each {|n| puts "Prime ==> #{n}" if prime? n}
I think the biggest differences between your book and this code are:
The algorithm is different in that we do not check all values, but rather limit the checks to <= sqrt(i). We also stop checking once we know a number is not prime.
We iterate over Ranges rather than keeping counters. This is slightly higher level and easier to read once you get the syntax.
I split the code into two parts, a function that calculates whether a parameter is prime or not, and then we iterate over a Range of inputs (1..100). This seems like a good division of functionality to me, helping readability.
Some language features used here not in your example:
If statements can go after expressions, and the expression is only evaluated if the predicate (the thing after the if) evaluates to true. This can make some statements more readable.
A range is written (x..y) and allows you to quickly describe a series of values that you can iterate over without keeping counters.
Code inside
do |param1, ..., paramN| <CODE>; end
or
{|param1, ..., paramN| <CODE>}
is called a block. It's an anonymous function (a function passed in as a parameter to another function/method). We use this with all? and each here.
each is used to run a block of code on each element of a collection, ignoring the return value
all? can be used to determine whether a block returns true for every item in a collection.
If you're not familiar with passing code into functions, this is probably a little confusing. It allows you to execute different code based on your needs. For example, each runs the yielded block for every item in the collection.You could do anything in that block without changing the definition of each... you just yield it a block and it runs that block with the proper parameters. Here is a good blog post to get you started on how this works and what else you can use it for.

Displaying factors of a number prompted by a user

I am trying to create a program that prompts a user to input a number and then checks if its a prime number. I am also trying to get it to display the factors if it isn't a prime number.
I managed to create the first part of the program, but I am struggling with the last part.
def prime(n)
is_prime = true
for i in 2..n-1
if n % i == 0
is_prime = false
end
end
if is_prime
puts "#{n} is a prime number"
else
puts "#{n} is not a prime number =>"
end
end
prime(n)
At this step:
puts "#{n} is not a prime number =>"
I want to incorporate the displaying of factors, let's say the number is 8
8 is not a prime number => 1, 2, 4, 8
Any help or advice would be greatly appreciated!
Try this code:
def factors(n)
(1..n/2).select{|e| (n%e).zero?}.push(n)
end
factors(8) => [1,2,4,8]
and your last step will look as:
puts "#{n} is not a prime number =>#{factors(n).join(',')}"
By the way: for check if number is prime, advice to use Sieve of Eratosthenes.

Ruby - Accessing an Array from Inside a Function

Ruby Newb here. I'm trying to write a program that accepts user input, compares it with numbers in an array, and if there's a match, adds it to another number passed to the function. Like so:
numbers = [1, 2, 3, 4, 5]
def add(start_num, list)
print "What number will you add?> "
number = gets.chomp
if list.index(number) != nil
start_num = start_num.to_i
number = number.to_i
sum = start_num + number
puts "Your sum is #{sum}."
else
puts "Not an acceptable number."
end
end
add(10, numbers)
Every time it gets to the point where it compares list.index(number) to nil, it apparently doesn't pass, and spits out "Not an acceptable answer." So, for some reason, even if the user-input number matches a number from the numbers array, apparently the index is still equal to nil.
Anybody have a clue how I can make the test pass?
Just convert the string to number as
number = gets.chomp.to_i
In your code, you were searching inside the list the number, which is basically string. That's the reason your if condition always evaluated as falsy. BTW,
number = gets.to_i
Will work too.
get.chomp is a string I think try to transform it in a number with gets.chomp.to_i
From one newb to another (I know it can be hard, lol), here are some suggestions to clean up you code a little (I'm sure there are even cleaner versions but here's a start)
numbers = [1, 2, 3, 4, 5]
def add(start_num, list)
print "What number will you add?> " #using puts will give the user a new line
number = gets.chomp #to_i is best placed here, gets.chomp ALWAYS returns a string
if list.index(number) != nil #include? is cleaner and more readable
start_num = start_num.to_i #an integer defined in an argument stays an integer, therefor no need for this line
number = number.to_i #no need for this line if you define it above
sum = start_num + number
puts "Your sum is #{sum}."
else
puts "Not an acceptable number."
end
end
add(10, numbers)
In fact, you can use a terany to shorten your if statement...so here is your code, the cleaner version:
numbers = [1, 2, 3, 4, 5]
def add(start_num, list)
puts "What number will you add?"
number = gets.chomp.to_i
sum = start_num + number
list.include?(number) ? puts("Your sum is #{sum}.") : puts("Not an acceptable number.")
end
add(10, numbers)
less code is more;)

How can I test if a value is a prime number in Ruby? Both the easy and the hard way?

I am trying to create a program that will test whether a value is prime, but I don't know how. This is my code:
class DetermineIfPrime
def initialize (nth_value)
#nth_value = nth_value
primetest
end
def primetest
if Prime.prime?(#nth_value)
puts ("#{#nth_value} is prime")
else
puts ("This is not a prime number.")
end
rescue Exception
puts ("#{$!.class}")
puts ("#{$!}")
end
end
And every time I run that it returns this.
NameError
uninitialized constant DetermineIfPrime::Prime
I tried other ways to do the job, but I think this is the closest I can get.
I also tried this:
class DetermineIfPrime
def initialize (nth_value)
#nth_value = nth_value
primetest
end
def primetest
for test_value in [2, 3, 5, 7, 9, 11, 13] do
if (#nth_value % test_value) == 0
puts ("#{#nth_value} is not divisible by #{test_value}")
else
puts ("This is not a prime number since this is divisible by #{test_value}")
break
end
end
end
end
Or am I just doing something wrong?
Ruby has built in method to check if number is prime or not.
require 'prime'
Prime.prime?(2) #=> true
Prime.prime?(4) #=> false
def is_prime?(num)
return false if num <= 1
Math.sqrt(num).to_i.downto(2).each {|i| return false if num % i == 0}
true
end
First, we check for 0 and 1, as they're not prime. Then we basically just check every number less than num to see if it divides. However, as explained here, for every factor greater than the square root of num, there's one that's less, so we only look between 2 and the square root.
Update
def is_prime?(num)
return if num <= 1
(2..Math.sqrt(num)).none? { |i| (num % i).zero? }
end
The error you are getting is because you haven't required Primein your code, You need to do require Prime in your file.
One cool way I found here, to check whether a number is prime or not is following:
class Fixnum
def prime?
('1' * self) !~ /^1?$|^(11+?)\1+$/
end
end
10.prime?
From an algorithmic standpoint, checking if a number is prime can be done by checking all numbers up to and including (rounding down to previous integer) said number's square root.
For example, checking if 100 is prime involves checking everything up to 10.
Checking 99 means only going to 9.
** Another way to think about it **
Each factor has a pair (3 is a factor of 36, and 3's pair is 12).
The pair is on the other side of the square root (square root of 6 is 36, 3 < 6, 12 > 6).
So by checking everything until the square root (and not going over) ensures you check all possible factors.
You can make it quicker by having a list of prime numbers to compare, as you are doing. If you have a maximum limit that's reasonably small, you could just have a list of primes and do a direct lookup to see if that number is prime.
def is_prime?(num)
Math.sqrt(num).floor.downto(2).each {|i| return false if num % i == 0}
true
end
lol sorry for resurrecting a super old questions, but it's the first one that came up in google.
Basically, it loops through possible divisors, using the square root as the max number to check to save time on very large numbers.
In response to your question, while you can approach the problem by using Ruby's Prime I am going to write code to answer it on its own.
Consider that all you need to do is determine a factor that is smaller than the integer's square root. Any number larger than the integer's square root as a factor requires a second factor to render the number as the product. (e.g. square root of 15 is approx 3.8 so if you find 5 as a factor it is only a factor with the factor pair 3 and 5!!)
def isPrime?(num)
(2..Math.sqrt(num)).each { |i| return false if num % i == 0}
true
end
Hope that helps!!
(To first answer the question: yes, you are doing something wrong. As BLUEPIXY mentions, you need to put require 'prime' somewhere above the line that calls Prime.prime?. Typically on line 1.)
Now, a lot of answers have been given that don't use Prime.prime?, and I thought it might be interesting to benchmark some of them, along with a possible improvement of my own that I had in mind.
###TL;DR
I benchmarked several solutions, including a couple of my own; using a while loop and skipping even numbers performs best.
Methods tested
Here are the methods I used from the answers:
require 'prime'
def prime1?(num)
return if num <= 1
(2..Math.sqrt(num)).none? { |i| (num % i).zero? }
end
def prime2?(num)
return false if num <= 1
Math.sqrt(num).to_i.downto(2) {|i| return false if num % i == 0}
true
end
def prime3?(num)
Prime.prime?(num)
end
def prime4?(num)
('1' * num) !~ /^1?$|^(11+?)\1+$/
end
prime1? is AndreiMotinga's updated version. prime2? is his original version (with the superfluous each method removed). prime3? is Reboot's, using prime library. prime4? is Saurabh's regex version (minus the Fixnum monkey-patch).
A couple more methods to test
The improvement I had in mind was to leverage the fact that even numbers can't be prime, and leave them out of the iteration loop. So, this method uses the #step method to iterate over only odd numbers, starting with 3:
def prime5?(num)
return true if num == 2
return false if num <= 1 || num.even?
3.step(Math.sqrt(num).floor, 2) { |i| return false if (num % i).zero? }
true
end
I thought as well that it might be interesting to see how a "primitive" implementation of the same algorithm, using a while loop, might perform. So, here's one:
def prime6?(num)
return true if num == 2
return false if num <= 1 || num.even?
i = 3
top = Math.sqrt(num).floor
loop do
return false if (num % i).zero?
i += 2
break if i > top
end
true
end
Benchmarks
I did a simple benchmark on each of these, timing a call to each method with the prime number 67,280,421,310,721. For example:
start = Time.now
prime1? 67280421310721
puts "prime1? #{Time.now - start}"
start = Time.now
prime2? 67280421310721
puts "prime2? #{Time.now - start}"
# etc.
As I suspected I would have to do, I canceled prime4? after about 60 seconds. Presumably, it takes quite a bit longer than 60 seconds to assign north of 6.7 trillion '1''s to memory, and then apply a regex filter to the result — assuming it's possible on a given machine to allocate the necessary memory in the first place. (On mine, it would seem that there isn't: I went into irb, put in '1' * 67280421310721, made and ate dinner, came back to the computer, and found Killed: 9 as the response. That looks like a SignalException raised when the process got killed.)
The other results are:
prime1? 3.085434
prime2? 1.149405
prime3? 1.236517
prime5? 0.748564
prime6? 0.377235
Some (tentative) conclusions
I suppose that isn't really surprising that the primitive solution with the while loop is fastest, since it's probably closer than the others to what's going on under the hood. It is a bit surprising that it's three times faster than Prime.prime?, though. (After looking at the source code in the doc it is less so. There are lots of bells and whistles in the Prime object.)
AndreiMotinga's updated version is nearly three times as slow as his original, which suggests that the #none? method isn't much of a performer, at least in this context.
Finally, the regex version might be cool, but it certainly doesn't appear to have much practical value, and using it in a monkey-patch of a core class looks like something to avoid entirely.
If you are going to use any Prime functions you must include the Prime library. This problem can be solved without the use of the prime library however.
def isPrime?(num)
(2..Math.sqrt(num)).each { |i|
if num % i == 0 && i < num
return false
end
}
true
end
Something like this would work.
Try this
def prime?(num)
2.upto(Math.sqrt(num).ceil) do |i|
break if num%i==0
return true if i==Math.sqrt(num).ceil
end
return false
end
So most of the answers here are doing the same thing in slightly different ways which is one of the cool things about Ruby, but I'm a pretty new student (which is why I was looking this up in the first place) and so here's my version with comment explanations in the code:
def isprime n # starting with 2 because testing for a prime means you don't want to test division by 1
2.upto(Math.sqrt(n)) do |x| # testing up to the square root of the number because going past there is excessive
if n % x == 0
# n is the number being called from the program
# x is the number we're dividing by, counting from 2 up to the square root of the number
return false # this means the number is not prime
else
return true # this means the number is prime
end
end
end

Resources