How to calculate factorial in ruby [duplicate] - ruby

This question already has answers here:
Ruby factorial function
(20 answers)
Closed 8 years ago.
QUESTION :
Input:
4 # number of input
1
2
4
3
Output:
1
2
24
6
CANNOT GET DESIRED OUTPUT
My code:
num = Integer(gets.chomp)
k = []
for i in 1..num
k[i] = Integer(gets.chomp)
end
k.each do |w|
for i in 1..w
w.to_i = w*i
end
puts w
end

To get factorial of n
(1..n).inject :*
To take care of zero
(1..n).inject(1, :*)

you can try like:
input = Integer(gets.chomp)
ans = 1
for i in 1..input
ans = ans*i
end
print(ans)

Related

How to multiply integer digits between them?

I want to my n to multiply with next number for example if n=99 i want it to 9*9 and then return a result, and then i want the result (9*9 = 81 then 8*1 = 8) to multiply until it becomes 1 digit.
Here's my code:
def persistence(n)
if n <= 9
puts n
else
n.to_s.each_char do |a|
a.to_i * a.to_i unless n < 9
puts a.to_i
end
end
end
and i want it to return this:
persistence(39) # returns 3, because 3*9=27, 2*7=14, 1*4=4
# and 4 has only one digit
persistence(999) # returns 4, because 9*9*9=729, 7*2*9=126,
# 1*2*6=12, and finally 1*2=2
persistence(4) # returns 0, because 4 is already a one-digit number
def persistence(n)
i = 0
while n.to_s.length != 1
n = n.to_s.each_char.map(&:to_i).reduce(:*)
i +=1
end
i
end
persistence(39) #=> 3
persistence(999) #=> 4
Other version:
def p(n, acc)
return acc if n <= 9
p(n.to_s.each_char.map(&:to_i).reduce(:*), acc+1)
end
def persistence(n)
p(n, 0)
end
I will leave the breaking down of method and understanding what's happening and what is the difference b/w two variations to you. Will love to see your comment explaining it.
def persistence(n)
0.step.each do |i|
break i if n < 10
n = n.digits.reduce(:*)
end
end
persistence 4 #=> 0
persistence 39 #=> 3
persistence 999 #=> 4
persistence 123456789123456789 #=> 2
Regarding the last result, note that 2*5*2*5 #=> 100.

Is it better way to do that?

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

Ruby code that doesn't work [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
This is an Euler Project Number 1.
sum = 0
array = []
for num in 1...1000
if num % 3 === 0
sum = sum + num
array.push(num)
end
if num % 5 === 0
sum = sum + num
array.push(num)
end
end
#puts array
puts sum
When I run the program with 10 as the range, I get the correct input, but when I use 1000, my answer is 266333, whereas the correct answer is 266138 according to the answer cheat. Can you tell me what I did wrong?
you need an elsif instead of two if statements. Currently you have some numbers which are divisible by both 3 AND 5, that are being added to the total sum twice.
for num in 1...1000
if num % 3 === 0
sum = sum + num
array.push(num)
elsif num % 5 === 0
sum = sum + num
array.push(num)
end
end
or a better way:
for num in 1...1000
if num % 3 == 0 || num % 5 == 0
sum = sum + num
array.push(num)
end
end

How does yield work with a block in Ruby? [duplicate]

This question already has answers here:
Blocks and yields in Ruby
(10 answers)
Closed 8 years ago.
I'm trying to understand how yield works in Ruby?
def ablock
i = 1
j = 2
yield(i, j, 3, 4)
end
ablock do |x| puts x
end
This gives me an output of -
1
2
3
4
But,
def ablock
i = 1
j = 2
yield(i, j, 3, 4)
end
ablock do |x,y| puts x, y
end
Gives me only
1
2
as the output. Why don't 3 & 4 print?
The answer is pretty simple. You have defined your block method correctly but when you go to give it a code block you only give it one variable to hold 4 objects. Instead, try giving it a variable for each object you are yielding!
def ablock
i=1
j=2
yield(i,j,3,4)
end
ablock do |i,j,k,l|
puts i
puts j
puts k
puts l
end
If you would only like to use one variable in your code block you have to do multiple yield statements(one for each object).
def ablock
i=1
j=2
yield(i)
yield(j)
yield(3)
yield(4)
end
ablock do |i|
puts i
end
Happy coding!

Difference between || and ||=? [duplicate]

This question already has answers here:
What does ||= (or-equals) mean in Ruby?
(23 answers)
What does the "||=" operand stand for in ruby [duplicate]
(1 answer)
Closed 9 years ago.
I am new to Ruby.
What is the difference between || and ||=?
>> a = 6 || 4
=> 6
>> a ||= 6
=> 6
Sounds like they are the same.
||= will set the left-hand value to the right hand value only if the left-hand value is falsey.
In this case, both 6 and 4 are truthy, so a = 6 || 4 will set a to the first truthy value, which is 6.
a ||= 6 will set a to 6 only if a is falsey. That is, if it's nil or false.
a = nil
a ||= 6
a ||= 4
a # => 6
x ||= y means assigning y to x if x is null or undefined or false ; it is a shortcut to x = y unless x.
With Ruby short-circuit operator || the right operand is not evaluated if the left operand is truthy.
Now some quick examples on my above lines on ||= :
when x is undefined and n is nil:
with unless
y = 2
x = y unless x
x # => 2
n = nil
m = 2
n = m unless n
m # => 2
with =||
y = 2
x ||= y
x # => 2
n = nil
m = 2
n ||= m
m # => 2
a ||= 6 only assigns 6 if it wasn't already assigned. ( actually, falsey, as Chris said)
a = 4
a ||= 6
=> 4
a = 4 || 6
=> 4
You can expand a ||= 6 as
a || a = 6
So you can see that it use a if a is not nil or false, otherwise it will assign value to a and return that value. This is commonly used for memoization of values.
Update
Thanks to the first comment for pointing out the true expansion of the ||= (or equal) operator. I learned something new and found this interesting post that talks about it. http://dablog.rubypal.com/2008/3/25/a-short-circuit-edge-case
Both expressions a = 6 || 4 and a ||= 6 return the same result but the difference is that ||= assigns value to variable if this variable is nil or false.

Resources