Check if numeral within bounds in one statement - ruby

Is there a way to check if a number x is greater than a number a and less than a number b, without specifying x twice?
I can do this:
x = 4
a = 1
b = 10
x > a && x < b
...but is there a way to do something like this:
# not valid ruby, is there another way?
a < x < b

This does not answer the question exactly, please read the Edit part of the answer.
Tested this to work for x being an Integer and a Float.
(a..b).include? x
Edit:
As #spickermann pointed out in comments the original question excludes the beginning and the end of the interval.
To exclude the end is easy, this is what ... is for. Therefore
(a...b).include? x # is the same as `a <= x && x < b`
To exclude the start of the interval is not that easy. One could use next_float:
(a.to_f.next_float...b).include? x
However even the (a...b) is something I would not use because it is not so common literal and in my opinion decreases readability of the code. With a.to_f.next_float we are making some really awkward code that may work for Integers and Floats but I would be afraid of other Numeric data types.
Unless someone brings completely different approach I would stick with x > a && x < b

Related

For loop with flexible stop variable

I need to write a loop
for x in (1..y)
where the y variable can be changed somehow. How can I do that?
For example:
for x in (1..y/x)
But it does not work.
Normally we'd use a loop do with a guard clause:
x = 1
loop do
break if x >= y
x += 1
...
end
Make sure y is larger than x or it'll never do anything. y can change if necessary and as long as it's greater than x the loop will continue. As soon as y drops below x the loop will terminate on the next iteration.
Note: I use >= because testing for equality is a bug-in-waiting. Sometimes we try to compare where x starts out greater than y or we are incrementing a float and comparing it to an integer or another float and using == and never hit the magic "equal" causing the loop to run away. Instead always check for a greater-than-or-equal to end the loop.
I think you might be confused about return values. This actually works fine, it's just that the return value is equal to the original range.
y = 4
for x in (1..y)
puts x
end
# 1
# 2
# 3
# 4
#=> 1..4
Here's a code snippet to prove it.

Can we write an algorithm which gives me two whole numbers X and Y when I want to get a desired fraction F such that F= X/Y?

I am working to prepare a test data set in which I have to check rounding. Suppose I want to check round, round_up and round_down is working correctly at 10 th decimal place or not.
Then
if, X=100 and Y = 54 so, X/Y = 1.8518518518518518518518518518519 (test round equidistant)
if, X= 10 and Y = 7 so, 1.4285714285714285714285714285714 (test round_up)
if, X= 10 and Y = 3 so, 3.3333333333333333333333333333333 (test round_down)
Can we write an algorithm in which
input will be rounding mode (round_up, round, round_down) and decimal place I want to round at(in our example 10)
output will be X and Y like above?
If the required location is p (=10 in your example), then y=10^p and then you can choose any x you want.
Depending on the language you are using, p might be too big for you to do 10^p, so in the worst case just divide the result from x/y by 10, 100 or whatever is necessary.
Or you can do like this
# n = number of fraction you want to return
def getFraction(a, b, n):
result = ""
for i in range(n):
f = int((a % b) * 10 / b)
result += str(f)
a = a * 10 - b * f
return result
getFraction(10, 7, 11) # return 42857142857 which 10/7 = 1.42857142857...
What I do is like what you have learnt in elementary school on how to do division by pen and paper.
Actually, if the required digit is d, then if d is not 9, the answer would be x=d,y=9 regardless of p which is the position of the digit. If d is 9, then if p is odd, the answer is x=10,y=11 and if p is even, x=1,y=11. If a trivial answer for d=0 won't do, the mirror answer for d=9 is suitable, that is, if d=0 and p is odd, the answer is x=1,y=11, and if p is even, x=10,y=11. A lot shorter than an answer with y=10^p and certainly fitting in nearly any architecture.

Multiline conditionals in Ruby and other mysteries -- why won't this compile?

I'm learning Ruby, but I'm having trouble predicting what Ruby will behave under certain circumstances. For example, the following causes a syntax error:
[2, 3, 4].any? do |x|
(x > 1
and x < 4)
end
but this compiles fine:
[2, 3, 4].any? do |x|
(x > 1 and
x < 4)
end
(the difference is in the placement of the and)
Why does the former fail to compile, while the latter succeeds, and how would I have known that? i.e.: since the above seems totally unintuitive, where is the formal grammar for Ruby, like https://docs.python.org/3/reference/grammar.html , or a guide like this https://docs.python.org/3/reference/lexical_analysis.html so I don't have to just guess at Ruby's behavior and figure it out by trial & error?
You have to end the line with an operator if you want the statement to be continued on the next line.
I will try to see if I can re-find the doc on this.
This is documented in the following book , chapter 2.
The Ruby Programming Language
By David Flanagan, Yukihiro Matsumoto
To paraphrase :
With having semicolons as explicit end of statement indicators, the ruby interpreter must figure out when a statement ends. It does this by figuring out if a statement is complete or not, if not it continues parsing on the next line. So
total = x +
y
is the same as total = x + Y since total = x + is not a complete statement
but
total = x
+y
is the same as total = x followed by the statement +y, which is just y
so the same applies for a conditional , if you end with a && for example the interpreter will continue parsing on the next line
x = a &&
b
is the same as x = a && b
but
x = a
&& b
is assigns a to x and generates a syntax error for the next line
Your best friend: CLICK ME
If you would like to format your conditionals like your first example(I don't know why you would) you can use the \format. Try this
[2, 3, 4].any? do |x|
(x > 1 \
and x < 4)
end
Basically just add the slash after each Boolean except your last one!
However standard Ruby convention is to be as short, descriptive, and concise as possible. A similar conditional could be written as so
As johnson said it should be
[2, 3, 4].any? { |x| x > 1 && x < 4 }
Happy Coding!

All possible products

I'm trying to find all possible product of two 3-digit numbers. When I work with small ranges, I'm able to get an output in short amount of time but when the ranges are big, it seems to take really long time. Is there any way to to shorten the time to get the result?
The problem I'm working on is:
"A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers."
a = []
for x in 100..999
for y in 100..999
num = (x * y)
unless a.include? num
a.push num
end
end
end
p a
This is going to compute 100 x 101 and 101 x 100 separately, even though they're not going to be pushed to the array since they're already in it.
I'm bad at math, but maybe every time x goes up, y's minimum range can go up since that one was just used? people who are better at math can tell me if this is going to start missing numbers.
z= 100
for x in 100..999
for y in z..999
num = (x * y)
unless a.include? num
a.push num
end
z = z+1
end
end
I think doing this might make the "unless a.include? num" line unnecessary, too.
Looking at your code a quick optimization you can make is to use a set rather than an array to store the already computed products.
Since a is an array, a.include?(num) will have to iterate through the entire list of elements before returning true / false.
If a were to be a set, a.include?(num) will return in sub linear time.
Example:
require 'set'
a = Set.new
for x in 100..999
for y in 100..999
num = (x * y)
unless a.include? num
a.add(num)
end
end
end
puts a.to_a.join(", ")
Moreover one of the nice properties of a set is that it only stores unique elements so the following would be equivalent:
require 'set'
a = Set.new
for x in 100..999
for y in 100..999
num = (x * y)
a.add(num)
end
end
puts a.to_a.join(", ")
What are you really trying to do, i.e. what is the original problem, and why do you need all of these products?
Are you printing every single one out? Is someone asking you for a concrete list of every single one?
If not, there is likely a better way to deal with this problem. For example, if all you wanted is to check if a number X will be an element in "that list of products", all you'd have to do is:
range = 100..999
range.any? { |i| range.include?(x / i) }

Python Matrix Neighbor Checking

I have a 7*7 matrix containing 0s and 1s in which each (x,y) will be checked for how many of its neighbors are a 1. I am a beginner to python, and will only be using basic programming procedures.
I have:
for x in range(rows):
for y in range(cols):
lives = 0
lives = neighbors(matrix, rows, cols)
def neighbors(matrix, rows, cols):
if matrix[x][y+1] == 1:
lives += 1
if matrix[x-1][y+1] == 1:
lives += 1
#All 8 positions are checked like this
return lives
I am getting the ol indexing error. This seems like a very simple problem I just can't seem to figure out how to fix it.
First of all, the index error occurs when you do y+1. Since you are going in the range of the amount of cols, this will end up being cols+1, which is out of range.
What you can do is use a try-except block, or make sure it doesn't get out of range through only looping to cols-1.
Additionally your function definition is redundant, since you don't use all your input parameters, and you access the x and y variables in the global scope.
The easiest thing to do is probably just to remove the definition and the return-statement.
This should work:
for x in range(rows):
for y in range(cols-1): #Loop until the second to last element.
lives = 0
if matrix[x][y+1] == 1:
lives += 1
if x == 0: #You probably don't want to check x-1 = -1
continue
if matrix[x-1][y+1] == 1:
lives += 1

Resources