How to add in a loop in ruby? - ruby

Just started learning about loops in ruby and I'm trying to figure out how to add a number to itself.. Like 1+1+1+1+1...
I've tried variations of
3.times() do
self.+(self)
end
But always get undefined method '+'.
I've done this too
number = 1
3.times() do
number = number.+(number)
end
Although it works, it isn't what I'm really trying to do since it's giving me 8, and I just wanted it to be 4 by adding 1+1 over and over. Also I want to be able to use any number not necessarily always 1.

Using times you can do it like:
number = 1
3.times do
number += number
end
puts number
#=> 3
number += number is just a shortcut for number = number + number

Perhaps having another variable to hold onto the sum could fix your issue. Right now, your number starts as 1. Then your loop runs 3 times and looks like the following:
(number = number.+(number))
Loop 1:
number = 1.+(1) ==> 2
number = 2.+(2) ==> 4
number = 4.+(4) ==> 8
Above youre actually multiplying the number by itself X.times
Instead, store the sum of the numbers in a separate variable like this:
sumOfNumbers = 0
numberToAdd = 1
3.times() do
sumOfNumbers = sumOfNumbers.+(numberToAdd)
end
or better yet
sumOfNumbers += numberToAdd

Related

Ruby prime number sum

I am trying to take the sum of the n first prime numbers. I found a way of showing the first 100, but I don't know how to get rid of 1 and how to make a sum with the numbers. I was thinking about storing them into an array, but I can not figure it out.
num = 1
last = 100
while (num <= last)
condition = true
x = 2
while (x <= num / 2)
if (num % x == 0)
condition = false
break
end
x = x + 1
end
primes = [] # Here
if condition
puts num.to_s
primes << num.to_s # Here
end
num = num + 1
end
puts primes.inject(:+) # Here
Based on what I understood from what you guys are saying I added these lines (the ones commented # Here). It still does not print the sum of them. What I meant with getting rid of 1 is that I know that 1 is not considered a prime number, and I do not get how to make it without 1. Thank you very much guys for your time and answers, and please understand that I am just starting to study this.
If you want to add a list of numbers together you can use the following:
list_of_prime_numbers.inject(0) {|total,prime| total + prime}
This will take the list of numbers, and add them one by one to an accumulator (total) that was injected into the loop (.inject(0)), add it to the current number (prime) and then return the total which then becomes the value of total in the next iteration.
I'm not quite sure what you mean by:
I don't know how to get rid of 1
but if you mean to not use the first number (which is 1 in a list of primes starting from 0)
then you could do:
list_of_prime_numbers[1...list_of_prime_numbers.length].
inject(0) {|total,prime| total + prime}
Which would only get all the numbers except the first up to but not including the length of the array
and as for getting the number into the array you could push it into the array like so:
list_of_prime_numbers << prime_number
You can make use of Prime Enumerable in ruby
require 'prime'
((1..100).select { |number| Prime.prime?(number) }).inject(:+)
OR
Prime.each(100).inject(:+)
Hope this helps.

Combining rand() numbers

I'm attempting to combine a few random numbers. The numbers are supposed to represent a dice.
For example, I want to roll the dice 5 times and I get the following results:
4 2 1 4 6.
These are all individual numbers but what I want to do is combine it together as 42146.
This might be a very simple question so I apologize for that but I'm still new to Ruby.
I'm generating numbers between [1,6] through this:
number = 1 + rand(6)
1.upto(5).map { rand(1..6) }.join.to_i
1.upto(5) will give you an Enumerator for 5 elements
map { rand(1..6) } will map a random number between 1 and 6 to each of the above elements
join will concatenate all elements of what you got so far
to_i will transform the above result from string to integer
Although all the answers are correct, there is one more option:
dice = 0
5.times do
dice = dice * 10 + rand(1..6)
end
puts dice
Demo: http://ideone.com/WfagFT
This time you treat everything as integers. Everytime (5 rolls) you take the result variable, multiply it by 10 and then add new random number at the end of it. There's no need to use anything else for that.
Of course if you need it, this code can be also written as one-liner and do exactly the same as above:
p #dice if 5.times { #dice = #dice.to_i * 10 + rand(1..6) }
5.times.inject(0){|n, _| n * 10 + 1 + rand(6)}
p Array.new(5){1 + rand(6)}.join # => "53325"

Using for-loop to add numbers together

If I randomly put in two numbers (first number is smaller), how do I use a for-loop to add all the numbers between and itself?
ex:
first number: 3
second number: 5
the computer should give an answer of '12'.
How do I do that using a for-loop?
In Ruby we seldom use a for loop because it leaves litter behind. Instead, you can very simply do what you want using inject:
(3..5).inject(:+) # => 12
This is using some of the deeper Ruby magic (:+), which is a symbol for the + method and is passed into inject. How it works is a different question and is something you'll need to learn later.
Don't insist on doing something in a language using a particular construct you learned in another language. That will often force non-idiomatic code and will keep you from learning how to do it as other programmers in that language would do it. That creates maintenance issues and makes you less desirable in the workplace.
Simple for loop across the range you defined:
puts "Enter first number: "
first = gets.to_i
puts "Enter second number: "
second = gets.to_i
total = 0
for i in (first..second) do
total += i
end
puts total
Note that if you don't enter a valid number, it will converted to 0. Also this assumes the second number is larger than the first.
In Rails, or in plain-vanilla Ruby with ActiveSupport, you can do something even simpler than a for loop, or than what other people wrote.
(first_num..second_num).sum
This is shorthand for sum in Ruby:
sum = 0
(first_num..second_num).each { |num| sum += num }
first, second = [3,5]
for x in (0..0) do
p (first + second)*(second - first + 1) / 2
end
I know you said for loop, but why not use what Ruby gives you?
> a = 3
> b = 5
> a.upto(b).inject(0) {|m,o| m += o}
=> 12
If you insist on a for loop...
> m = 0
=> 0
> for i in 3..5
* m += i
* end
=> 3..5
> m
=> 12
Since Ruby 2.4 you directly call sum on an Enumerable.
For Example [1, 2, 3].sum #=> 6
In Ruby it's very rare to see a for loop. In this instance a more idiomatic method would be upto:
x = 3
y = 5
total = 0
x.upto(y) do |n|
total += n
end
puts total
# => 12
Another method would be to use reduce:
total = x.upto(y).reduce do |sum, n|
sum += n
end
...which can be shortened to this:
total = x.upto(y).reduce(&:+)

Comparing two Integers by their divisibility

For instance:
8 > 10 = true, since 8 is divisible by 2 three times and 10 only once.
How can I compare two integers from any range of numbers? Are the modulo and divide operator capable of doing this task?
Use binary caculate to judge it
def devided_by_two(i)
return i.to_s(2).match(/0*$/).to_s.count('0')
end
To make integer divisibility by 2, just transcode it to binary and judge how many zero from end of banary number. The code I provide can be more simple I think.
Yes, they are capable. A number is even if, when you divide it by two, the remainder is zero.
Hence, you can use a loop to continuously divide by two until you get an odd number, keeping a count of how many times you did it.
The (pseudo-code) function for assigning a "divisibility by two, continuously" value to a number would be something like:
def howManyDivByTwo(x):
count = 0
while x % 2 == 0:
count = count + 1
x = x / 2 # make sure integer division
return count
That shouldn't be too hard to turn into Ruby (or any procedural-type language, really), such as:
def howManyDivByTwo(x)
count = 0
while x % 2 == 0
count = count + 1
x = x / 2
end
return count
end
print howManyDivByTwo(4), "\n"
print howManyDivByTwo(10), "\n"
print howManyDivByTwo(11), "\n"
print howManyDivByTwo(65536), "\n"
This outputs the correct:
2
1
0
16
Astute readers will have noticed there's an edge case in that function, you probably don't want to try passing zero to it. If it was production code, you'd need to catch that and act intelligently since you can divide zero by two until the cows come home, without ever reaching an odd number.
What value you return for zero depends on needs you haven't specified in detail. Theoretically (mathematically), you should return infinity but I'll leave that up to you.
Notice that you will likely mess up much of your code if you redefine such basic method. Knowing that, this is how it's done:
class Integer
def <=> other
me = self
return 0 if me.zero? and other.zero?
return -1 if other.zero?
return 1 if me.zero?
while me.even? and other.even?
me /= 2
other /= 2
end
return 0 if me.odd? and other.odd?
return -1 if me.odd?
return 1 if other.odd? # This condition is redundant, but is here for symmetry.
end
end

best way to rewind a variable at 1?

I have an array with 12 entries.
When doing 12+1, I want to get the entry 1 of the array
When doing 12+4, I want to get the entry 4 of the array
etc...
I'm done with
cases_to_increment.each do |k|
if k > 12
k = k-12
end
self.inc(:"case#{k}", 1)
end
I found a solution with modulo
k = 13%12 = 1
k = 16%12 = 4
I like the modulo way but 12%12 return 0 and I need only numbers between 1..12
There is a way to do that without condition ?
You almost had the solution there yourself. Instead of a simple modulo, try:
index = (number % 12) + 1
Edit: njzk2 is correct, modulo is a very expensive function if you are using it with a value that is not a power of two. If, however, your total number of elements (the number you are modulo-ing with) is a power of 2, the calculation is essentially free.

Resources