Assign the first non-zero value - ruby

Let's say I have the following variables defined:
a = 6
b = 4
c = 0
I want to assign the first non-zero value to another variable, but in reverse order (c -> b -> a). I originally tried d = c || b || a, but that still resulted in 0. Is there a one-liner way of doing this?

Use detect
[c,b,a].detect { |i| i > 0 }

[c,b,a].select { |i| i > 0 }.first => 4

Related

Change x,y from 1,1 to p,q using given rules

Given a = p, b = q
In one cycle a can change to a = a + b or b = b + a
In any cycle either of two can be performed but not both.
Starting from a = 1, b = 1
Calculate no of iterations required to convert (x, y) from (1, 1) to (p,q) using the above mentioned rules.
Return not possible if cannot be done
Can anyone tell how to solve this problem.
As already mentioned in a comment you can just go backwards. The larger element must be the one where the calculation was performed. So you could just do the reverse on the larger element and see if you end up with (1, 1). Or better subtract the smaller element directly as many times as needed from the larger one so that it becomes smaller than the other one:
function steps(a, b) {
let count = 0
while (a != b) {
console.log('(' + a + ', ' + b + ')')
let t
if (a > b) {
t = a % b == 0 ? a / b - 1 : Math.floor(a / b)
a -= t * b
} else {
t = b % a == 0 ? b / a - 1 : Math.floor(b / a)
b -= t * a
}
count += t
}
if (a == 1)
return count
return -1
}
console.log(steps(87, 13))
console.log(steps(23, 69))

Pseudocode for adding 2 until number is 100

I have a pseudocode assignment for a class. I have to design a program to output every even number starting with 2 and going to 100. I need someone to tell me if this is correct. If it isn't could someone point me in the right direction?
start
Declarations
num A = 0
num B = 100
num C
while A < B
C = A + 2
Output C
Endwhile
stop
start
Declarations
num A = 0
num B = 100
while A < B
A = A + 2
Output A
Endwhile
stop

System Stack Error

So I have the following code for a Merge Sort in Ruby.
class MergeSort
def sort(array)
if array.length == 1 || array.length == 0
return array
end
firstHalf = array[0..array.length / 2]
secondHalf = array[(array.length / 2) + 1..array.length]
firstHalf = sort(firstHalf)
secondHalf = sort(secondHalf)
b = 0
c = 0
for i in (0..(firstHalf.length - 1))
while b < secondHalf.length && firstHalf[i] >= secondHalf[b]
array[c] = secondHalf[b]
b = b + 1
c = c + 1
array[c] = firstHalf[i]
c = c + 1
end
return array
end
end
array = [1,4,9,14,20,25]
puts MergeSort::new.sort(array)
When I run the code, I get a SystemStackError. Can someone tell me why this is happening? Thanks.
At a guess, once the array length gets to 3 (i.e. elements [0..2]), the call
firstHalf = array[0..array.length / 2]
evaluates to
0..1.5 and if 1.5 is rounded up to 2
which then calls sort [0..2] again
and eventually you get a stack overflow?
In order to call .new you have to have an initialize method in your class.
What you probably wanted to do was calling .sort on the class itself, in which case you have to prefix it with self, so:
class MergeSort
def self.sort(array)
...
Afterwards you can call it like this:
MergeSort.sort(array)

DRYer method for if-else conditional statement?

How to write DRYer code for this in a model:
a = 10
b = 6
if a == b
a = 20
else
a
end
Basically, a remains a = 10 when a != b.
a = 10
b = 6
a = 20 if a == b
If this is in a method and you want the last value of a to be returned:
a = 10
b = 6
a == b ? a = 20 : a
Here's the third one :
You can also use short circuit operator and
a = 10
b = 6
a == b and a = 20

Strange Ruby String Selection

The string in question (read from a file):
if (true) then
{
_this = createVehicle ["Land_hut10", [6226.8901, 986.091, 4.5776367e-005], [], 0, "CAN_COLLIDE"];
_vehicle_10 = _this;
_this setDir -2.109278;
};
Retrieved from a large list of similar (all same file) strings via the following:
get_stringR(string,"if","};")
And the function code:
def get_stringR(a,b,c)
b = a.index(b)
b ||= 0
c = a.rindex(c)
c ||= b
r = a[b,c]
return r
end
As so far, this works fine, but what I wanted to do is select the array after "createVehicle", the following (I thought) should work.
newstring = get_string(myString,"\[","\];")
Note get_string is the same as get_stringR, except it uses the first occurrence of the pattern both times, rather then the first and last occurrence.
The output should have been: ["Land_hut10", [6226.8901, 986.091, 4.5776367e-005], [], 0, "CAN_COLLIDE"];
Instead it was the below, given via 'puts':
["Land_hut10", [6226.8901, 986.091, 4.5776367e-005], [], 0, "CAN_COLLIDE"];
_vehicle_10 = _this;
_this setDir
Some 40 characters past the point it should have retrieve, which was very strange...
Second note, using both get_string and get_stringR produced the exact same result with the parameters given.
I then decided to add the following to my get_string code:
b = a.index(b)
b ||= 0
c = a.index(c)
c ||= b
if c > 40 then
c -= 40
end
r = a[b,c]
return r
And it works as expected (for every 'block' in the file, even though the strings after that array are not identical in any way), but something obviously isn't right :).
You want r = a[b..c] instead of r = a[b,c].
Difference is: b..c = start from b, go to c, while b,c = start from b and move c characters to the right.
Edit: You don't have to/shouldn't escape the [ and ] either, because you are using strings and not regexen. Also, you have to take the length of the end ("];") into consideration, or you will cut off parts of the end.
def get_stringR(a,b,c)
bp = a.index(b) || 0
cp = a.rindex(c) || bp
r = a[bp..cp + c.size - 1]
return r
end
def get_string(a,b,c)
bp = a.index(b) || 0
cp = a.index(c) || bp
r = a[bp..cp + c.size - 1]
return r
end

Resources