I coded a conversion tool from binary to integer, but it had a limit on how large the number can be. So, I tried to code a formula for binary. I came up with an equation, so I tried to put it into code. Everything worked, except for applying the equation to each digit. This is the equation I came up with:
Let d represent the integer
Let z represent any (and every) digit
d = z[2^(z-1)]
This is what I've coded so far:
answer = gets.chomp
n = answer.reverse # reverses the answer
y1 = answer.size # the amount of digits in the answer
x1 = answer
z = (1..y1).each { |z| puts z } # every number between 1 and number of digits
w = (1..1).each.to_a * y1.to_i #in case I need to multiply the entire array
s = x1 # [z] - 1 # any given digit minus one
v = 2 ** s.to_i # exponent
u = z.zip(w).map{|x, y| x * y} # an array: [1, 2, 3]
print u
t = u.to_i # Tried converting to integer
puts x1[t]
But when I ran that, for example, with the number 1011, I got this error:
[1, 2, 3, 4]
undefined method `to_i' for [1, 2, 3, 4]:Array
Did you mean? to_s
to_a
to_h
(repl):16:in `<main>'
I feel like I have tried everything, but if you somehow find a way to apply the equation to every digit, or if you come up with a simpler equation, please tell me.
This return an array u = z.zip(w).map{|x, y| x * y} so you are triying to conver an array to integer. If you want, you can do something like this:
array = [1,0,1] #your binary in array form
s = array.join('') #transform it into string
s.to_i(2) #this return the integer and result (2) represents base
Check this link
And for better: array.join('').to_i(2)
Related
I tried to execute a calculation in Ruby. The result I get is 1589.5833333333333. I would like to limitat the numbers of digits after the comma.
The result should always be limited to 2 digits as followed:
1589.58
Question #1 = how can I set the limitation?
Question #2 = how can I round up 1589.60 or down 1589.55
Many thanks for help. Language is ruby
Other option but keeping the object as Float:
n = 1589.5833333333333
m = n.truncate(2) #=> 1589.58
h = n.round(1) #=> 1589.6 # for the last zero you need to format the string
And a tricky:
k = (n*100).to_i.digits.tap{ |ary| ary.first > 5 ? ary[0] = 5 : ary[0] = 0 }.reverse.join('').to_i/100.0
#=> 1589.55
For question 1:
num = 1589.5833333333333
printf('%.2f', num)
=> 1589.58
For question 2 to round up to first digit:
num = 1589.5833333333333
printf('%.2f', num.round(1))
=> 1589.60
1589.55 is a bit of an arbitrary number, rounding down would usually be calculated as 1589.58. I don't know of any Ruby function that does that off-hand.
I want to take an integer from the user, and generate a sequence of five numbers starting with the given integer, and multiplying each previous number by four, using iteration. E.g., if I enter 2 then the list should be [2, 8, 32, 128, 512].
n = gets
i = 0
while i < 4
n = n * 4
p n
i = i + 1
end
I am not sure if you are looking to create an array of numbers to use later or just want to iterate. In the following you can replace puts memo with whatever you want, memo will contain the value you are looking for each pass.
s = 2
(s...(s+5)).reduce(s) do |memo, i|
puts memo
memo = memo * 4
end
Run:
(5 - 1).times.with_object([gets.to_i]){|i, a| a.push(a.last * 4)}
Input:
2
Return value:
[2, 8, 32, 128, 512]
There are a lot of ways to accomplish what you are describing. You already have some implementations in the comments and in the other answer by #Abhimanyu.
the trouble I'm having is to iterate the value for the sequence. I keep getting it as [2,2,2,2,2]
Your code example won't work because Kernel#gets doesn't return a number, but a String followed by a newline character (because it uses a default separator, from the global variable $/, which happens to be "\n"):
[1] pry(main)> gets
2
=> "2\n"
[2] pry(main)> gets.class
2
=> String
To fix your snippet you'll need to add .chomp.to_i to remove the newline and to convert it to an integer:
def generate_sequence
n = gets.chomp.to_i
i = 0
while i < 4
n = n * 4
p n
i = i + 1
end
end
I'm a beginner in Ruby and I don't understand what this code is doing, could you explain it to me, please?
def a(n)
s = 0
for i in 0..n-1
s += i
end
s
end
def defines a method. Methods can be used to run the same code on different values. For example, lets say you wanted to get the square of a number:
def square(n)
n * n
end
Now I can do that with different values and I don't have to repeat n * n:
square(1) # => 1
square(2) # => 4
square(3) # => 9
= is an assignment.
s = 0 basically says, behind the name s, there is now a zero.
0..n-1 - constructs a range that holds all numbers between 0 and n - 1. For example:
puts (0..3).to_a
# 0
# 1
# 2
# 3
for assigns i each consecutive value of the range. It loops through all values. So first i is 0, then 1, then ... n - 1.
s += i is a shorthand for s = s + i. In other words, increments the existing value of s by i on each iteration.
The s at the end just says that the method (remember the thing we opened with def) will give you back the value of s. In other words - the sum we accumulated so far.
There is your programming lesson in 5 minutes.
This example isn't idiomatic Ruby code even if it is syntactically valid. Ruby hardly ever uses the for construct, iterators are more flexible. This might seem strange if you come from another language background where for is the backbone of many programs.
In any case, the program breaks down to this:
# Define a method called a which takes an argument n
def a(n)
# Assign 0 to the local variable s
s = 0
# For each value i in the range 0 through n minus one...
for i in 0..n-1
# ...add that value to s.
s += i
end
# The result of this method is s, the sum of those values.
s
end
The more Ruby way of expressing this is to use times:
def a(n)
s = 0
# Repeat this block n times, and in each iteration i will represent
# a value in the range 0 to n-1 in order.
n.times do |i|
s += i
end
s
end
That's just addressing the for issue. Already the code is more readable, mind you, where it's n.times do something. The do ... end block represents a chunk of code that's used for each iteration. Ruby blocks might be a little bewildering at first but understanding them is absolutely essential to being effective in Ruby.
Taking this one step further:
def a(n)
# For each element i in the range 0 to n-1...
(0..n-1).reduce |sum, i|
# ...add i to the sum and use that as the sum in the next round.
sum + i
end
end
The reduce method is one of the simple tools in Ruby that's quite potent if used effectively. It allows you to quickly spin through lists of things and compact them down to a single value, hence the name. It's also known as inject which is just an alias for the same thing.
You can also use short-hand for this:
def a(n)
# For each element in the range 0 to n-1, combine them with +
# and return that as the result of this method.
(0..n-1).reduce(&:+)
end
Where here &:+ is shorthand for { |a,b| a + b }, just as &:x would be short for { |a,b| a.x(b) }.
As you are a beginner in Ruby, let's start from the small slices.
0..n-1 => [0, n-1]. E.g. 0..3 => 0, 1, 2, 3 => [0, 3]
for i in 0.. n-1 => this is a for loop. i traverses [0, n-1].
s += i is same as s = s + i
So. Method a(n) initializes s = 0 then in the for loop i traverse [0, n - 1] and s = s + i
At the end of this method there is an s. Ruby omits key words return. so you can see it as return s
def a(n)
s = 0
for i in 0..n-1
s += i
end
s
end
is same as
def a(n)
s = 0
for i in 0..n-1
s = s + i
end
return s
end
a(4) = 0 + 1 + 2 + 3 = 6
Hope this is helpful.
The method a(n) calculates the sums of the first n natural numbers.
Example:
when n=4, then s = 0+1+2+3 = 6
Let's go symbol by symbol!
def a(n)
This is the start of a function definition, and you're defining the function a that takes a single parameter, n - all typical software stuff. Notably, you can define a function on other things, too:
foo = "foo"
def foo.bar
"bar"
end
foo.bar() # "bar"
"foo".bar # NoMethodError
Next line:
s = 0
In this line, you're both declaring the variable s, and setting it's initial value to 0. Also typical programming stuff.
Notably, the value of the entire expression; s = 0, is the value of s after the assignment:
s = 0
r = t = s += 1 # You can think: r = (t = (s += 1) )
# r and t are now 1
Next line:
for i in 0..n-1
This is starting a loop; specifically a for ... in ... loop. This one a little harder to unpack, but the entire statement is basically: "for each integer between 0 and n-1, assign that number to i and then do something". In fact, in Ruby, another way to write this line is:
(0..n-1).each do |i|
This line and your line are exactly the same.
For single line loops, you can use { and } instead of do and end:
(0..n-1).each{|i| s += i }
This line and your for loop are exactly the same.
(0..n-1) is a range. Ranges are super fun! You can use a lot of things to make up a range, particularly, time:
(Time.now..Time.new(2017, 1, 1)) # Now, until Jan 1st in 2017
You can also change the "step size", so that instead of every integer, it's, say, every 1/10:
(0..5).step(0.1).to_a # [0.0, 0.1, 0.2, ...]
Also, you can make the range exclude the last value:
(0..5).to_a # [0, 1, 2, 3, 4, 5]
(0...5).to_a # [0, 1, 2, 3, 4]
Next line!
s += i
Usually read aloud a "plus-equals". It's literally the same as: s = s + 1. AFAIK, almost every operator in Ruby can be paired up this way:
s = 5
s -= 2 # 3
s *= 4 # 12
s /= 2 # 6
s %= 4 # 2
# etc
Final lines (we'll take these as a group):
end
s
end
The "blocks" (groups of code) that are started by def and for need to be ended, that's what you're doing here.
But also!
Everything in Ruby has a value. Every expression has a value (including assignment, as you saw with line 2), and every block of code. The default value of a block is the value of the last expression in that block.
For your function, the last expression is simply s, and so the value of the expression is the value of s, after all is said and done. This is literally the same as:
return s
end
For the loop, it's weirder - it ends up being the evaluated range.
This example may make it clearer:
n = 5
s = 0
x = for i in (0..n-1)
s += i
end
# x is (0..4)
To recap, another way to write you function is:
def a(n)
s = 0
(0..n-1).each{ |i| s = s + i }
return s
end
Questions?
I have a square matrix of indeterminate row & column length (assume rows and columns are equal as befits a square).
I've plotted out an example matrix as follows:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
My goal is to get a sum from top-left to bottom-right of the diagonal values.
Obviously in this example, this is all i'll need:
diagsum = matrix[0][0]+matrix[1][1]+matrix[2][2]
#=> 15
I see the pattern where it's a +1 incremental for each row & column argument in the matrix, so the code i've developed for my matrix of indeterminate length (supplied as the argument to my method diagsum would preferably need to implement some sort of row_count method on my matrix argument.
If
arr = [[1,2,3],
[4,5,6],
[7,8,9]]
then:
require 'matrix'
Matrix[*arr].trace
#=> 15
This will sum the diagonal values.
matrix = []
matrix[0] = [1,2,3]
matrix[1] = [4,5,6]
matrix[2] = [7,8,9]
def diagsum(mat)
sum = 0
mat.each_with_index { |row,i| sum += row[i] }
sum
end
puts (diagsum matrix) # 15
Not clear what x is.
But assuming that it is the number of columns/rows, you have 0..x, while the index only goes up to x - 1. You should change it to 0...x.
You are assigning to variable i, whose scope is only in the block.
You are only using i once, perhaps intended to correspond to either row or column, but not both.
You are adding the indices instead of the corresponding elements.
each will return the receiver regardless of whatever you get in the blocks.
puts will return nil regardless of whatever you get.
In Ruby, I would like to take an array of numbers, select 2 different numbers, add those 2 numbers together and see weather there equal to a variable x.y'd a variable x. Here is the code I used
def arrayIsEqual? (numArray, x)
return true if numArray.sample + numArray.sample == x
return false if numArray.empty? || numArray.count == 1
end
for example
numArray = [4,2,7,5]
x = 11
arrayIsEqual (numArray, n) should return true, since 4 + 7 = n(11)
How do I get this to work?
I don't want it to be 2 random numbers, just any 2 different numbers that add up to n
It looks like you're trying to see if there are any two numbers in the array that add up to the specified value x. However, your code just picks two numbers at random and checks if those numbers add up.
Ruby has the Array#combination method, which generates all combinations of a given length:
def contains_pair_for_sum?(arr, n)
!!arr.uniq.combination(2).detect { |a, b| a + b == n }
end
A few things to note:
First, we named it according to Ruby conventions: each word is separated_by_underscores. The ? on the end means that the method is a predicate method and returns a true or false value.
Inside the method, a few things happen. Let's look at that line, piece by piece.
arr: We take the array that was passed in.
<...>.uniq: We only look at the unique elements (because the OP wants to pick two different numbers).
<...>.combination(2): We ask for all combinations from the array of length 2. If the array was [4, 5, 6], we'd get [[4, 5], [4, 6], [5, 6]].
<...>.detect { |a, b| a + b == n }: We look for the first combination that adds up to n. If we found one, that's the result of that method. Otherwise, we get nil.
!!<...>: Finally, we take the result we got from detect and negate it twice. The first negation produces a Boolean value (true if the value we got was nil, or false if it's anything else); the second negation produces a Boolean value that's identical to the truth value of the first negation. This is a Ruby idiom to coerce a result into being either true or false.
Let's see it in action:
array = [4, 5, 9, 7, 8]
contains_pair_for_sum?(array, 11)
# => true (because [4, 7] sums to 11)
contains_pair_for_sum?(array, 17)
# => true (because [9, 8] sums to 17)
contains_pair_for_sum?(array, 100)
# => false (no pair matched)
I understand that your question is "is there any pair of numbers in my array equals x", in which case this will do what you need:
def has_pair_equal?(num_array, x)
(0..num_array.length-1).any? do |i|
num_array[i+1..-1].any? { |n| n + num_array[i] == x }
end
end
This checks all sums of pairs of numbers in the array, and checks if their sum is x. sample randomly picks an item from the array, which means that what your code does is "return true sometimes if there is a pair of numbers in my array equals x"
def array_is_equal? (num_array, x)
equality = 0
num_array.each do |a|
equality += 1 if a == x
return true if equality == 2
end
return false
end
Use lowercase and underscores for variables in Ruby. The convention is different here than in some other languages.
One liner
x=[4,2,7,5]; x.each_with_index.any? {|y,i| x.each_with_index.any? {|z,j| unless i==j; z+y==11; end } }
And as a function
def pair_sum_match?(arr, x)
arr.each_with_index.any? do |y,i|
arr.each_with_index.any? do |z,j|
unless i==j
z+y==x
end
end
end
end
Updated: Added each_with_index to avoid self inclusion on checks. It's a lot longer now :-/
Just iterate over it once and use the target number to see if it matches. 100 times faster then most of the answers here
numbers = ( -10..10 ).to_a
numbers.unshift( numbers.first + -1 ) # if you do -20 or 20
numbers.push( numbers.last + 1 )
target = 5
searched = { }
matches = { }
numbers.each do |number|
if searched[ target - number + 1 ] == true
matches[ "#{ number }_plus_#{ target - number }" ] = target
end
searched[ number + 1 ] = true
end
ap matches