How do I total the random numbers generated in ruby - ruby

I have the code, that will generate random numbers, unless the generated random number is 0. When the result is 0, the loop breaks.
So when the loop breaks, I want a code, that keeps adding the random numbers that kept generated and display it at the last. Can I do that in ruby?
def batting
loop do
runs = [0,1,2,3,4,5,6]
myruns = runs.shuffle.first
Newscore =
puts "Press W to hit a shot"
user_input = gets.chomp
while user_input.include? "W"
puts myruns
until myruns == 0
break
Score = Score + myruns
break
This is throwing Dynamic Constant assignment error at Score = Score + myruns which I basically think, its wrong, since the myruns keep changing at every generated event?
So, I would want to create a new variable, that would store the total of all the random numbers generated until the generated random number is 0.
Could anyone help?

May be you are looking for something like this ?
def batting
runs = [0,1,2,3,4,5,6]
final_score = 0
puts "Press W to hit a shot"
user_input = gets.chomp
while user_input.include? "W"
myruns = runs.sample
if myruns != 0
final_score += myruns
else
break
end
puts "myruns=#{myruns}","final_score=#{final_score}"
puts "Press W to hit a shot"
user_input = gets.chomp
end
puts "myruns=#{myruns}","final_score=#{final_score}"
end

You can do something like this:
def batting
loop.with_object([]) do |_,obj|
x = rand 7
x == 0 ? raise(StopIteration) : obj << x
end.sum
end
batting #=> 33
batting #=> 0
batting #=> 18
Using loop this continually creates random numbers from 0 - 6 with rand 7. We use a ternary operator to stop the loop with StopIteration if x == 0, otherwise we push x into the obj array (which is initially []). Finally we sum the obj array.
Key methods: loop, Enumerable#with_object, rand, Array#sum

Related

Measuring the time to sort each item using bubblesort

I wanted to add a timer which would count the time of sorting the five highest numbers with detailing each one individually, that is, the timer starts counting when sorting starts, then saves the time of sorting the first highest number, then resets and counts the time of the second highest number until the first five numbers are counted.
Here is my code, I don't know how to place timer so it will count what I want
def bubble_sort(tablica)
n = tablica.length
liczba_max = tablica.max(5){ |a, b| a<=>b}
loop do
zamienione = false
(n-1).times do |i|
if tablica[i] > tablica[i+1]
tablica[i], tablica[i+1] = tablica[i+1], tablica[i]
zamienione = true
end
end
break if not zamienione
end
puts "Sorted array:"
tablica
end
puts "size of array:"
ilosc_liczb = gets.chomp()
i = 0
liczba = Array.new(ilosc_liczb.to_i)
puts "Unsorted array:"
while i < ilosc_liczb.to_i
nubmers = Random.new_seed
liczba[i] = nubmers
puts liczba[i]
i += 1
end
puts bubble_sort(liczba)
puts "5th number"
puts liczba[-5]
Please help me

Ruby while loop

Writing a ruby while loop that take integers as an input and stores them in an array
when a certain integer is entered (-1) the loop should stop and print out the array.
When -1 is entered the loop stops but there is no output.
puts " Enter a number"
x = -1.to_i
number = ' '
numbers = []
while number != x
number = gets.chomp
numbers.push(number)
end
puts
numbers.pop
p numbers
The loop will never stop gets.chomp returns a String so the loop will go on for ever because:
"-1" != -1
#=> true
Try changing this to:
while number != x
number = gets.chomp.to_i
numbers.push(number)
end

How do you pass a range of values as arguments to a method?

I am calling a method I created and trying to pass a range of values as the arguments.
My code:
def prime_numbers (x)
i = 1
count = 0
until i > x
if x % i == 0
count += 1
end
i += 1
end
if count > 2
puts "count is: " + count.to_s
p x.to_s + " is not prime."
p false
elsif count == 2
puts "count is: " + count.to_s
p x.to_s + " is prime."
p true
end
end
prime_numbers (5)
puts
prime_numbers (25)
puts
prime_numbers (31)
puts
prime_numbers (1..100) #This is the one I care about that is throwing an error
Desired output:
count is: 2
"5 is prime."
true
count is: 3
"25 is not prime."
false
count is: 2
"31 is prime."
true
This would be desired for all the numbers within the range.
What I think I've done incorrectly or may still need to do:
I could use an array and somehow incorporate blocks to do all of this.
I'm missing something very simple in my syntax
Syntax in my parameter list needs to be changed
Thank you in advance for your time answering this.
Your method is named prime_numbers, but that is not exactly what it does. It is hard to come up with a good name: it does too much. That said, you could call it for every number in a range like this :
(1..100).each{|n| prime_numbers(n) }
In order to pass an array, you should define a method in a way that it can process an array.
In your code from what I can see is you are getting a parameter x and then applying an operator > to that which in case of a range will throw an error.
When (1..100) is passed as an argument x becomes an array what you might wanna do is something like this
def prime_numbers (x)
y = x.class == Range ? x : [x] # to make sure you have an array
y.each do |number|
...... you code here
end
end
PS you would want to replace number in the above example. Or you could rename your parameter x

Odds of rolling two dice with equal outcomes seem more common than I pictured

After running this program several times i noticed that my y value is somewhere between 60-80 every single time.
I thought because 70^2 is 4900 that i would end up with my y value ending up around 1 each run through, but actually its about a 1 in 70 chance of the dice equaling each other.
So why is it that rolling 2 70 sided dice and having the results equal each other is not a 1/4900 chance, but rather a 1/70 chance? Heres the program...
x=0
y=0
while x < 4900
random = rand(70)
random2 = rand(70)
puts " "
puts random
puts random2
if random == random2
puts "the numbers matched"
y+=1
end
x+=1
if x == 4900
puts " "
puts y
end
end
There are 4900 possible outcomes (1,1), (1,2), (1,3) .. ,(70, 70)
There are 70 outcomes that are suitable for your condition - (1,1), (2,2) .. (70,70)
So, the probability is needed_outcomes/all_outcomes = 70/4900 = 1/70 ~= 0.0142858
In test program number of tests is not connected to number of outcomes. Larger number of tests tends to show more accurate results (through in this case we don't program at all, but there is ruby tag in the question).
So, we can try this:
x=0
total_matches = 0.0
N = 1000000
while x < N
random = rand(1..70)
random2 = rand(1..70)
total_matches += 1 if random == random2
x += 1
end
puts total_matches/N
It gives something around 0.0142.
If you wish to estimate the probability of two thrown 70-sided dice showing the same value (which we know to be (1.0/70).round(6) #=> 0.014286) by simulating throws, you can assume one die always shows the same given value and repeatedly throw the second die only, counting the number of times it shows the assumed value of the first die, and then divide the count by the number of throws. (See my comment on the question.)
Suppose each die has sides labelled 0, 1,...,69 and we assume the first die always shows a 0. We can then simulate as follows:
def simulate(nbr_throws)
nbr_throws.times.sum { rand(70) == 0 ? 1 : 0 }.fdiv(nbr_throws).round(6)
end
simulate( 100) #=> 0.01
simulate( 1_000) #=> 0.016
simulate( 10_000) #=> 0.0151
simulate( 100_000) #=> 0.01358
simulate( 1_000_000) #=> 0.014305
simulate( 10_000_000) #=> 0.014282
simulate(100_000_000) #=> 0.014284
See Kernel#rand and Integer#fdiv. More generally, if each die had n sides, change rand(70) to rand(n).

Comma assignment (why right go first?) i.e. n,m = 1, 2?

In the process of figuring out blocks and yields I came across these comma-separated assignments:
def fibit
n,m =1,1
loop do |variable|
yield n
n,m = m,n+m # this line
puts "n is #{n} m is #{m}"
end
end
fibit do |num|
puts "Next : #{num}"
break if num > 100
end
Why does the m get assigned first in this scenario?
Does the last one always go first? If so why?
This was also seen as only e has the value of 1 meaning e went first?
e,r=1
puts r
puts "-------"
puts e
Also, does anyone have an idea why the code-block versions just executes, where if I write the same code with no code block I actually need to call the method for it to run?
def fibit
n,m =1,1
loop do |variable|
puts "Next : #{n}"
break if n > 100
n,m = m,n+m
end
end
fibit
If I didn't have the last line it wouldn't run. Where in the first one I don't actually call the fibit method? Or is the block kicking it off?
m does not get assigned first. When using multiple assignments, all right hand side calculations are done before any assignment to the left hand side.
That's how this code works:
a = 1
b = 3
a, b = b, a
a
# => 3
b
# => 1
This would not be possible if the assignment was done serially, since you would get that both would be either equal 1 or 3.
To further prove my point, simply swap the assignment of n and m in your code, and you'll find that the result is the same:
def fibit
n,m =1,1
loop do |variable|
yield n
m,n = n+m,m # this line
puts "n is #{n} m is #{m}"
end
end
fibit do |num|
puts "Next : #{num}"
break if num > 100
end

Resources