Ruby shortest way to write rnd hex - ruby

What I have is a method used to generate random hex values. E.g 666 or FF7
However, I don't think it looks simple/elegant at all.. What I want is to make it more simple which perhaps will make my code shorter as well, but I don't know how. That is why I need tips or hints
Here is my code so far:
def random_values
random_values = Array.new
letters = ['A','B','C','D','E','F']
for i in 1..15
if i <= 9
random_values << i
else
random_values << letters[i-10]
end
end
return random_values.shuffle[0].to_s + random_values.shuffle[0].to_s + random_values.shuffle[0].to_s
end
As you probably see, I do not generate random numbers. I just shuffle the array containing the values I want, meaning all the numbers in the array are unique, which is not needed, but was the easiest solution for me when I wrote the code.
I am most concerned about the return line.. If only it was possible to write like:
return 3.times { random_values.shuffle[0] }
or
return random_values.shuffle[0].to_s *3
Thanks in advance!

def random_value
r = Random.new
((r.rand * 16)).to_i.to_s(16)
end
puts random_value + random_value + random_value
Or, after some quick research:
"%06x" % (rand * 0xffffff)
From Ruby, Generate a random hex color
Also, you shouldn't be looking for a more efficient solution per se. You seem to be looking for something more elegant, simple, and intuitive. (My solution is none of these, by the way. The searched one is.)

# For Ruby 1.9
require 'securerandom'
SecureRandom.hex(16)
# For Ruby 1.8 and above
require 'active_support/secure_random'
ActiveSupport::SecureRandom.hex(16)

Something like this?
(rand * MAX_VALUE).to_i.to_s(16)
Where MAX_VALUE is the upper bound for the numbers. You can also add some lower bound:
(MIN_VALUE + rand * (MAX_VALUE - MIN_VALUE)).to_i.to_s(16)
This will give you numbers in the range [MIN_VALUE,MAX_VALUE)

Related

ruby how could i make this factorization recursive till i end with a binary number?

i have this code, basically first i factorize for example the number 28 to:
[2,2,7]
and then i make a list of prime numbers and find the index of each factor in that list, so 2 is prime number with index 0 and 7 prime number with index 2 so it ends up like this:
[[0],[0],[2]]
with which another recursion would be:
[[0],[0],[[0]]]
which tranlated to binary would be:
1101101110111
but im stuck on this:
require 'prime'
def f(n)
Prime.prime_division(n).flat_map { |factor, power| [factor] * power }
end
n=rand(10000)
puts n
f=f (n)
require 'prime'
#list=Prime.take(10000)
g=[]
j=0
f.each do |j|
if j>10
i=f(#list.index(j))
g.push i
i=[]
else
g.push j
end
end
print g
You want to learn, so I won't do all the work for you.
Step 1
Please write those 3 methods :
def get_factors(integer)
# return an Array of Integers:
# get_factors(28) -> [2,2,7]
end
def get_factor_index(prime)
# return the index of prime in Prime.all :
# 2 -> 0
# 7 -> 2
end
def array_to_binary(nested_array)
# convert nested_array (with 0s in leaves) to binary
# [[0],[0],[[0]]] -> "1101101110111"
# Hint : Use Array#to_s, and then String#gsub 3 times to convert ',' to '', and '[' or ']' to 1
end
and come back once you're done. We'll work on the recursion.
Step 2
I modified a bit your answer just a bit. To make it clearer, I tried to use different names for variables and methods. Also, the last line of a method is returned automatically by Ruby. You don't need to define an extra variable. Methods could probably be written more efficiently but I didn't want you to not recognize your code.
Your get_factor_index does more than what I asked for BTW. I'm not sure we can use it like this :
require "prime"
def get_factors(integer)
Prime.prime_division(integer)
end
def nested_array(factors)
factors.flat_map { |factor, power| [factor] * power }
end
def get_factor_index(nested_array)
list=Prime.take(10000)
temp=[]
nested_array.each do |i|
p = list.index(i)
temp.push(p)
end
temp
end
def array_to_binary(array)
temp=array.to_s
temp=temp.gsub("[","1")
temp=temp.gsub("]","1")
temp=temp.gsub(",","")
temp.gsub(" ","")
end
Now, please write a method that uses all the above ones, converting 512 to "10000000001". I'm not sure it's the correct answer, but we'll work on that later.
Also, try this method on 20 (not 28!) and see what you get. Using the above methods, you could try to manually tailor a way to get [[0],[0],[2]]. It's not a problem if it just works for 20 at first.
If you're feeling adventurous, try to get [[0],[0],[[0]]] with the above methods.

Fibonacci number on a range (ruby)

Could someone give me a brief explanation as to why n+(n-1) doesn't work? Mathematically it does but i'm not sure how to tell ruby this is what i'm looking for? As the title suggests, the code is supposed to return a Fibonacci sequence.
startyear = []
(1..100).each do |n|
puts n+(n-1)
startyear.push(n)
end
n+(n-1) = 2n-1. Your code is simply displaying 2n-1 (1,3,5,7,..,199).
On the other hand, startyear.push(n) is pushing numbers (1,2,3,.,100) into the startyear array. I think you meant to do something like this.
startyear = [1,1]
(2..100).each do |n|
puts (new_num = startyear[n-1] + startyear[n-2])
startyear.push(new_num)
end
But again, I'm not 100% sure what the range stands for in your code, so I might be wrong.

How do I create an exponential distribution in Ruby with the distribution gem?

I need the mean to be 2, with starting at 1 up to 10,000 random numbers.
require 'distribution'
mean = 2
# generate a rng with exponential distribution
rng = Distribution::Exponential.rng(mean)
Well, I'm not much of a statistician, so I'm a little lost in the code here.
Can you tell me, then, is the first parameter to rng (it is named l) supposed to stand for "limit"?
If so, I don't really know, I'm getting the same sort of results that you must be getting, but again, I'm not a statistician or even a mathematician, I just like to code, so I am probably not of too much help.
EDIT: So, again, I dont really know what is going on or is supposed to be going on here. Here is what gives me a relatively close mean of 2 (I got this just by messing around with the l value):
require 'distribution'
rng=Distribution::Exponential.rng(0.5)
sum=0
1000.times { sum += rng.call }
sum /= 1000
puts sum
Seems to give a value generally between 1.9 and 2.1. Hope this helps :)
PRINT EACH VALUE:
require 'distribution'
rng = Distribution::Exponential.rng(0.5)
values = [] # we'll store each value in an array
# calculate the results
how_many = 1000 # let's store 1000 in a variable since we'll reuse the value
how_many.times { values << rng.call } # rng is now a Proc, so we use call to get our value
# print out the results
values.each_with_index { |v,i| puts "#{i+1}: #{v}" } # print each value one by one
puts
puts "Total sum: #{values.inject(&:+)}"
puts "Mean: #{values.inject(&:+)/how_many}"
Again, not sure if this is exactly "right" or what you're looking for, but it definitely seems to approach 2. Try a bigger number than 1000, like 100000.

Do something infinitely many times with an index

In more ruby way of doing project euler #2 , part of the code is
while((v = fib(i)) < 4_000_000)
s+=v if v%2==0
i+=1
end
Is there a way to change i += 1 into a more functional programming style construct?
The best I can think of is
Float::MAX.to_i.times do |i|
v = fib(i)
break unless v < 4_000_000
s += v if v%2==0
end
because you can't call .times on a floating point number.
Numeric.step has default parameters of infinity (the limit) and 1 (the step size).
1.step do |i|
#...
end
For fun, you might even want to try
1.step.size
There’s a predefined (in 1.9.2) constant Float::INFINITY, so you could write
1.upto(Float::INFINITY) do |i|
...
end
(You could also use Enumerator and take_while, turning the problem inside out to make it look more like Haskell or Python, but take_while is greedy and builds an array.)
Ruby 2.5 introduced the open-ended Range:
(1..).each do |i|
#...
end

Problem comprehending C-style ruby loops

I find the .each do hard to get to stick, so I was hoping for regular use of C for loop syntax which seems to not work, so I tried a while but still get errors.
I have tried this.
i = 0
while i < SampleCount
samples[i] = amplitude
amplitude *= -1
i++
end
I get complaints about the end statement here.
There are several problems with your code. Rather than just fixing the errors, I'd suggest it's better long-term for you to learn the Ruby way - it will save you time and energy later. In this case, it's
5.times do |i|
samples[i] = amplitude # assumes samples already exists and has 5 entries.
amplitude *= -1
end
If you insist on keeping a similar style, you can do this:
samples = []
i = 0
while i < sample_count
samples << amplitude # add new item to array.
amplitude *= -1
i += 1 # you can't use ++.
end
Note that SampleCount's initial capital letter, by Ruby convention, means a constant, which I'm guessing isn't what you really mean.
I agree with Peter that there are other (more idiomatic) ways to do this in Ruby, but just to be clear: the error message you saw misdirected you. There wasn't anything wrong with your while loop per se. The problem was i++ since there is no ++ operator in Ruby.
This would work just fine:
limit = 10
i = 0
while i < limit
puts i
i += 1
end
Again, I'm not recommending it, but if you're just learning the language, it may help to know where the problem really was.
Ruby has a lot of built-in ways to iterate other than for or while (which tend to be seen less often, as far as I can tell). A few other examples:
(1..10).each do |x| # 1..10 is a range which you can iterate over with each
puts x
end
1.upto(10) { |x| puts x } # Integers have upto and downto methods that can be useful
You originally mentioned trying to use a for loop. Notwithstanding the various other comments in the answers, here's the for loop approach:
for i in 0...5
samples[i] = amplitude
amplitude *= -1
end
Nobody here has actually offered an alternate solution that actually does what Fred originally intended - and that's iterate around the value of the constant SampleCount. So could you do:
SampleCount.times do |i|
Or:
limit = SampleCount
limit.times do |i|
Or:
for i in 0..SampleCount
Would any of those be Ruby-esque enough?
The problem with the end statement is related to i++. Ruby wants to add something. There is no increment operator in Ruby. You need to use i += 1. With that change you can use your C style loop as is.

Resources