So i have the following 2 program:
1st program, which works as intended( Ex: input 7, output Number is prime
puts "Enter a positive number: "
number = gets.chomp.to_i
prime = true
i = 2
while i <= number/2
if number % i == 0
prime = false
end
i += 1
end
if prime == true
puts "Number is prime"
else
puts "Number is not prime"
end
2nd program, which is basically the same, just added the user the ability to check for prime numbers in a range. This program only shows 2 and 3 as prime numbers(if input is 10, for example)
puts "Enter a positive number: "
range = gets.chomp.to_i
prime = true
i = 2
number = 2
while number <= range
while i <= number/2
if number % i == 0
prime = false
end
i += 1
end
if prime == true
puts "#{number} is prime"
else
puts "#{number} is not prime"
end
number += 1
end
I think the problem is with the way im incrementing, since i can't use a for, but i tried debugging and i just don't get it, it should print out 5 and 7 aswell, if i input 10 as my range of numbers.
Related
i am currently studying ruby and your help would be much appreciated.
i am trying to display the below results in my terminal:
1
2
3 i am divisible by 3
4
5 i am divisible by 5
6 i am divisible by 3
7
8
9 i am divisible by 3
10 i am divisible by 5
11
12 i am divisible by 3
13
14
15 i am divisible by 3 and 5
16
17
18 i am divisible by 3
19
20 i am divisible by 5
i am unsure how to go about. I wrote the below code in my divisible.rb:
def count
numbers = (1..20)
numbers.each do |number|
if number % 1 == 1
puts "#{number}"
elsif number % 3 == 0
puts "#{number} i am divisible by 3"
elsif number % 5 == 0
puts "#{number} i am divisible by 5"
elsif number % 3 == 0 && number % 5 == 0
puts "#{number} i am divisible by 3 & 5"
end
end
end
but it outputs the below in the terminal:
irb(main):001:0> count
3 i am divisible by 3
5 i am divisible by 5
6 i am divisible by 3
9 i am divisible by 3
10 i am divisible by 5
12 i am divisible by 3
15 i am divisible by 3
18 i am divisible by 3
20 i am divisible by 5
=> 1..20
could one please kindly advise me on the right path
There are 3 steps to fix it
Remove 1st if statement,
You should move this: elsif number % 3 == 0 && number % 5 == 0 to 1st step
Add else puts number
it should look like:
def count
numbers = (1..20)
numbers.each do |number|
if number % 3 == 0 && number % 5 == 0
puts "#{number} i am divisible by 3 & 5"
elsif number % 3 == 0
puts "#{number} i am divisible by 3"
elsif number % 5 == 0
puts "#{number} i am divisible by 5"
else
puts number
end
end
end
UPD
Let's add an explanation about these steps:
1st and 3rd steps:
Dividing by 1 always will return 0 as a result, so the first reason is a mistake in logic and the second one is as now we know that this always is 0 we don't need to check it one more time.
2nd step:
When we check for example 3 with elsif number % 3 == 0 it will return true, so next if-statements wouldn't be checked, to fix it we should first add checking for number % 3 == 0 && number % 5 == 0
Thanks to #3limin4t0r, you are right it's always better to explain.
Just for fun, you could use the Prime class from standard lib, this way:
require 'prime'
(0..30).each do |number|
if [0, 1].include? number
puts number
next
end
if Prime.prime?(number)
puts "#{number} is prime"
else
divisors = Prime.prime_division(number).map(&:first)
puts "#{number} is divisible by " + divisors.join(" and ") if divisors.size > 1
end
end
I am asking the user to input a number and evaluate that number to see if it's divisible by 3.
this is my code
positive_integer = gets.chomp
if positive_integer % 3 == 0
puts "#{positive_integer} is divisible by 3"
elsif
puts "#{positive_integer} is not divisible by 3"
end
But for some reason when I input 9, 30, or any number that IS divisible by three I get "#{positive_integer} is not divisible by 3" output.
What am I doing wrong
your variable positive_integer is a string. convert it into integer by
positive_integer = gets.chomp.to_i
I wrote a simple script to sum all digits of positive integer input until 1 digit is left ( for example for input 12345 result is 6 because 1+2+3+4+5 = 15 and 1+5 = 6). It works but is it better way to do that? ( more correct?)
here is a code:
def sum(n)
string=n.to_s
while string.length > 1 do
result=string.chars.inject { |sum,n| sum = sum.to_i + n.to_i}
string=result.to_s
end
puts "Sum of digits is " + string
end
begin
p "please enter a positive integer number:"
number = Integer(gets.chomp)
while number<0
p "Number must be positive!Enter again:"
number = Integer(gets.chomp)
end
rescue
p "You didnt enter integer!:"
retry
end
sum(number)
According to Wikipedia, the formula is:
dr(n) = 1 + ((n − 1) mod 9)
So it boils down to:
def sum(n)
1 + (n - 1) % 9
end
To account for 0, you can add return 0 if n.zero?
You could use divmod (quotient and modulus) to calculate the digit sum without converting to / from string. Something like this should work:
def sum(number)
result = 0
while number > 0 do
number, digit = number.divmod(10)
result += digit
if number == 0 && result >= 10
number = result
result = 0
end
end
result
end
sum(12345) #=> 6
The line
number, digit = number.divmod(10)
basically strips off the last digit:
12345.divmod(10) #=> [1234, 5]
1234 becomes the new number and 5 is being added to result. If number eventually becomes zero and result is equal or greater than 10 (i.e. more than one digit), result becomes the new number (e.g. 15) and the loops starts over. If result is below 10 (i.e. one digit), the loop exits and result is returned.
Short recursive version:
def sum_of_digits(digits)
sum = digits.chars.map(&:to_i).reduce(&:+).to_s
sum.size > 1 ? sum_of_digits(sum) : sum
end
p sum_of_digits('12345') #=> "6"
Single call version:
def sum_of_digits(digits)
digits = digits.chars.map(&:to_i).reduce(&:+).to_s until digits.size == 1
return digits
end
It's looking good to me. You might do things a little more conscise like use map to turn every char into an integer.
def sum(n)
string=n.to_s
while string.length > 1 do
result = string.chars.map(&:to_i).inject(&:+)
string = result.to_s
end
puts "Sum of digits is " + string
end
You could also use .digits, so you don't have to convert the input into a string.
def digital_root(n)
while n.digits.count > 1
array = n.digits
n = array.sum
end
return n
end
App Academy's practice test says their chosen way of finding if an input is a power of 2 is to keep dividing it by 2 on a loop and check whether the end result is 1 or 0 (after having tested for the numbers 1 and 0 as inputs), which makes sense, but why won't this way work?
def try
gets(num)
counter = 0
go = 2 ** counter
if num % go == 0
return true
else
counter = counter + 1
end
return false
end
I can't figure out why this won't work, unless the counter isn't working.
There are a number of problems with your code.
First of all, there is no loop and your counter will reset to zero each time if you intend to use the method in a loop, because of counter = 0.
counter = 0; go = 2 ** counter basically means go = 2 ** 0 which is 1. Therefore num % 1 will always be 0
You actually need to divide the number and change it in the process. 12 % 4 will return 0 but you don't know by that if 12 is a power of 2.
IO#gets returns a string and takes a separator as an argument, so you need to use num = gets.to_i to actually get a number in the variable num. You are giving num to gets as an argument, this does not do what you want.
Try:
# Check if num is a power of 2
#
# #param num [Integer] number to check
# #return [Boolean] true if power of 2, false otherwise
def power_of_2(num)
while num > 1 # runs as long as num is larger than 1
return false if (num % 2) == 1 # if number is odd it's not a power of 2
num /= 2 # divides num by 2 on each run
end
true # if num reached 1 without returning false, it's a power of 2
end
I add some checks for your code. Note, that gets(num) returns a String. Your code is fine, but not for Ruby. Ruby hates type-cross-transform like Perl does.
def try(num = 0)
# here we assure that num is number
unless (num.is_a?(Integer))
puts "oh!"
return false
end
counter = 0
go = 2 ** counter
if num % go == 0
return true
else
counter = counter + 1
end
return false
end
The general problem is "how string could use '%' operator with number?"
Try some code in the interpretator (irb):
"5" % 2
or
"5" % 0
This code is not working. I'm trying to code the Collatz conjecture but the code only seems to run once for the input 8. It prints out 4, 1 ,1 and so that shows it only runs for one step. The else block is never executed either. Can someone tell me what's wrong with this Ruby code? I have no idea why it's not working the way it's supposed to.
class Collatz
def collatz(number)
if number == 1
return 0
end
steps = 0
while number > 1 do
if number % 2 == 0
number = number / 2
puts number
steps = steps + 1
puts steps
else
number = (number * 3) + 1
puts number
steps = steps + 1
puts steps
end
return steps
end
end
steps = Collatz.new.collatz(8)
puts steps
end
You have a return statement that's terminating execution after the first iteration of the while loop.
Try
class Collatz
def collatz(number)
return 0 if number == 1
steps = 0
while number > 1 do
if number % 2 == 0
puts number /= 2
puts steps += 1
else
number = (number * 3) + 1
puts number
puts steps += 1
end
end
return steps
end
end
steps = Collatz.new.collatz(8)
puts steps
which returns 3 and prints
4
1
2
2
1
3
[Finished in 0.4s]
And if you want to make your code a little cleaner and more idiomatic, you could refactor it as follows:
class Collatz
def collatz(number)
return 0 if number == 1
steps = 0
while number > 1
number = number.even? ? number / 2 : (number * 3) + 1
puts number, steps += 1
end
steps
end
end
steps = Collatz.new.collatz(8)
#4
#1
#2
#2
#1
#3
#=> 3
Let's properly indent your code and see if we can find the problem:
class Collatz
def collatz(number)
if number == 1
return 0
end
steps = 0
while number > 1 do
if number % 2 == 0
number = number / 2
puts number
steps = steps + 1
puts steps
else
number = (number * 3) + 1
puts number
steps = steps + 1
puts steps
end
return steps
end
end
steps = Collatz.new.collatz(8)
puts steps
end
Look at that — the return is in your while-loop, so it returns at the end of the first iteration. It looks like you actually wanted to end your while loop on the line above that.
This one of the reasons why coding style is really important. It can trick you into thinking your code means something it doesn't.