Swap two integers in ruby without creating a third - ruby

Swap two integers in ruby you can:
a,b = b, a
or:
b ^= (a ^= b)
a ^= b
or so:
a = a + b
b = a - b
a = a - b
Are there more ways to swap two integers without the creation of a third?

Compilation of answers from comments. All are welcome to add their additional answers.
a = b.tap { b = a }
eval("a = #{b}; b = #{a}")
a = b + 0 * (b = a)

Are there more ways to swap two integers without the creation of a third?
temp = a
a = b
b = temp
There are only two Integers in this code, there is no third one created.
Note that several of the examples posted here fail this criterion:
b ^= (a ^= b)
# ^^^^^^ this creates a third integer
a ^= b
a = a + b
# ^^^^^ this creates a third integer
b = a - b
a = a - b

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))

Implementing a FIR filter using Vectors

I have implemented a FIR filter in Haskell. I don't know that much about FIR filters and my code is heavily based on an existing C# implementation. Therefore, I have a feeling that my implementation is has too much of a C# style and is not really Haskell-like. I would like to know if there is a more idiomatic Haskell way of implementing my code. Ideally, I'm lucky for some combination of higher-order functions (map, filter, fold, etc.) that implement the algorithm.
My Haskell code looks like this:
applyFIR :: Vector Double -> Vector Double -> Vector Double
applyFIR b x = generate (U.length x) help
where
help i = if i >= (U.length b - 1) then loop i (U.length b - 1) else 0
loop yi bi = if bi < 0 then 0 else b !! bi * x !! (yi-bi) + loop yi (bi-1)
vec !! i = unsafeIndex vec i -- Shorthand for unsafeIndex
This code is based on the following C# code:
public float[] RunFilter(double[] x)
{
int M = coeff.Length;
int n = x.Length;
//y[n]=b0x[n]+b1x[n-1]+....bmx[n-M]
var y = new float[n];
for (int yi = 0; yi < n; yi++)
{
double t = 0.0f;
for (int bi = M - 1; bi >= 0; bi--)
{
if (yi - bi < 0) continue;
t += coeff[bi] * x[yi - bi];
}
y[yi] = (float) t;
}
return y;
}
As you can see, it's almost a straight copy. How can I turn my implementation into a more Haskell-like one? Do you have any ideas? The only thing I could come up with was using Vector.generate.
I know that the DSP library has an implementation available. But it uses lists and is way too slow for my use case. This Vector implementation is a lot faster than the one in DSP.
I've also tried implementing the algorithm using Repa. It is faster than the Vector implementation. Here is the result:
applyFIR :: V.Vector Float -> Array U DIM1 Float -> Array D DIM1 Float
applyFIR b x = R.traverse x id (\_ (Z :. i) -> if i >= len then loop i (len - 1) else 0)
where
len = V.length b
loop :: Int -> Int -> Float
loop yi bi = if bi < 0 then 0 else (V.unsafeIndex b bi) * x !! (Z :. (yi-bi)) + loop yi (bi-1)
arr !! i = unsafeIndex arr i
First of all, I don't think that your initial vector code is a faithful translation - that is, I think it disagrees with the C# code. For example, suppose that both "x" and "b" ("b" is coeff in C#) have length 3, and have all values of 1.0. Then for y[0] the C# code would produce x[0] * coeff[0], or 1.0. (it would hit continue for all other values of bi)
With your Haskell code, however, help 0 produces 0. Your Repa version seems to suffer from the same problem.
So let's start with a more faithful translation:
applyFIR :: Vector Double -> Vector Double -> Vector Double
applyFIR b x = generate (U.length x) help
where
help i = loop i (min i $ U.length b - 1)
loop yi bi = if bi < 0 then 0 else b !! bi * x !! (yi-bi) + loop yi (bi-1)
vec !! i = unsafeIndex vec i -- Shorthand for unsafeIndex
Now, you're basically doing a calculation like this for computing, say, y[3]:
... b[3] | b[2] | b[1] | b[0]
x[0] | x[1] | x[2] | x[3] | x[4] | x[5] | ....
multiply
b[3]*x[0]|b[2]*x[1] |b[1]*x[2] |b[0]*x[3]
sum
y[3] = b[3]*x[0] + b[2]*x[1] + b[1]*x[2] + b[0]*x[3]
So one way to think of what you're doing is "take the b vector, reverse it, and to compute spot i of the result, line b[0] up with x[i], multiply all the corresponding x and b entries, and compute the sum".
So let's do that:
applyFIR :: Vector Double -> Vector Double -> Vector Double
applyFIR b x = generate (U.length x) help
where
revB = U.reverse b
bLen = U.length b
help i = let sliceLen = min (i+1) bLen
bSlice = U.slice (bLen - sliceLen) sliceLen revB
xSlice = U.slice (i + 1 - sliceLen) sliceLen x
in U.sum $ U.zipWith (*) bSlice xSlice

Swapping two numbers using only two variables

How is it performing swapping?
a=a+b
b=a+b
a=b+a
I don't agree that it's swap to a book!!!
The book options include "complements of values of a and b" ,"negate and b".Hope these options aren't satisfying it too???
The correct algorithm should be:
a = a + b
b = a - b
a = a - b
The swap is performed using XOR, which is typically written as a plus within a circle; for example:
a := 5
b := 7
a := a xor b (2)
b := a xor b (5)
a := b xor a (7)
I recently underwent an interview for java fresher, the interviewer asked me to perform swapping of two numbers (but in one line).
Swapping of two numbers can be performed in one line also, without using a temp variable.
The logic is really simple,
x is added with y in the same line, y is assigned as x which is subtracted by their sum.
after performing this one line arithmetics the numbers were swapped. (only in one line)
public class SwapInOneLine {
public static void main(String[] args) {
int x = 10; int y = 20;
System.out.println("Before Swaping: x = " + x + " and y= " + y);
x = x + y - (y = x);
System.out.println("After Swaping: x = " + x + " and y= " + y);
}}
output:
Before Swaping: x = 10 and y= 20
After Swaping: x = 20 and y= 10
We can use XOR (^) for this.
Advantage of XOR : As XOR works on bit level, it takes very less amount of time than any other operations.
If a = 5 and b = 7
then to swap :
a = a ^ b
b = a ^ b
a = a ^ b
Where '^' means XOR.
Result :
a = 7 and b = 5
Actually, it can be done by two ways:
int a = 5, b = 10;
Using Addition(+) and Subtraction(-)
a = a + b;
b = a - b;
a = a - b;
Using Multiple(*) and Division(/)
a = a * b;
b = a / b;
a = a / b;

Rounding of double to nearest member of an arithmetical progression?

I have a formula of a sequence of double numbers k = a + d * n, where a and d are constant double values, n is an integer number, k >= 0, a >= 0. For example:
..., 300, 301.6, 303.2, 304.8, 306.4, ...
I want to round a given number c to a nearest value from this sequence which is lower than c.
Currently I use something like this:
double someFunc(double c) {
static double a = 1;
static double d = 2;
int n = 0;
double a1 = a;
if (c >= a) {
while (a1 < c) {
a1 += d;
}
a1 -= d;
} else {
while (a1 > c) {
a1 -= d;
}
}
return a1;
}
Is it possible to do the same without these awful cycles? I ask because the following situation may appear:
abs(a - c) >> abs(d) (the first number is much more then the second one and so a lot of iterations possible)
My question is similar to the following one. But in my case I also have a a variable which has influence on the final result. It means that a sequence may haven't number 0.
Suppose c is a number in your sequence. Then you have n = (c - a) / d.
Since you want an integer <= c, then take n = floor((c - a) / d).
Then you can round c to: a + d * floor((c - a) / d)
Suppose k = 3 + 5 * n and you round c=21.
And 3 + 5 * floor((21 - 3) / 5) = 3 + 5 * 3 = 18

Calculating pi using iterations in ruby

For a school's assignment I am trying to calculate pi using the Gauss Legendre algorithm to test cpu efficiency.
Therefore, I have written a program in Ruby.
This program should iterate 500000000 times and display the the time used for it. But everytime it executes within a second.
My question:
Is there a better way to iterate so it really does repeat 500 million times and display pi and the time?
include Math
a = 1
b = 1/sqrt(2)
t = 0.25
p = 1
i = 0
imax = 500000000
start = Time.now
until i = imax
an = (a/2) + (b/2)
bn = sqrt(a) * sqrt(b)
tn = t - p * ((a-an) * (a-an))
pn = 2 * p
a = an
b = bn
t = tn
p = pn
i +=1
PI = ((a+b)*(a+b))/(4*t)
end
finish = Time.now
time = finish - start
puts PI
puts time
Start by not making i equal imax right away:
until i = imax
Should be
until i == imax
Even better, just do
500000000.times do
Instead of that line.
In addition to the issues raised by #Nick and #sawa your algorithm is flawed: the square root of the product of a and b is not equal to the product of the square roots of a and b.
In ruby:
include Math
a, b, t, p = 1, 1/sqrt(2), 0.25, 1
imax = 5
imax.times do |i|
an = (a+b) / 2
bn = sqrt(a * b)
tn = t - p * ((a-an) * (a-an))
pn = 2 * p
a, b, t, p = an, bn, tn, pn
pi = ((a+b)*(a+b))/(4*t)
printf "%d : %10.60f\n", i, pi
end
Running this gives me:
0 : 3.140579250522168575088244324433617293834686279296875000000000
1 : 3.141592646213542838751209274050779640674591064453125000000000
2 : 3.141592653589794004176383168669417500495910644531250000000000
3 : 3.141592653589794004176383168669417500495910644531250000000000
4 : 3.141592653589794004176383168669417500495910644531250000000000
So clearly you need more accuracy, hence BigDecimal. As this is your homework assignment I'll leave that up to you :-). (If unsure which variables to change, try all except i and imax. Also check out http://www.ruby-doc.org/stdlib-1.9.3/libdoc/bigdecimal/rdoc/BigDecimal.html)
Another thing you are doing wrong is assigning a constant PI within a loop. Although it is possible to reassign a constant, it is not correct to do so. Either use a variable or move the assignment to outside of the loop so that it would be assigned only once.
Even if I remove the assignment and print out the result for each iteration like this:
include Math
a = 1
b = 1/sqrt(2)
t = 0.25
p = 1
i = 0
imax = 500000000
until i == imax
an = (a/2) + (b/2)
bn = sqrt(a) * sqrt(b)
tn = t - p * ((a-an) * (a-an))
pn = 2 * p
a = an
b = bn
t = tn
p = pn
i +=1
puts ((a+b)*(a+b))/(4*t)
end
I get the wrong result. It goes like this:
-2.1244311544725596
-1.1383928808463357
-1.1265990444799223
-1.1265961703346379
-1.126596170334544
-1.126596170334544
... # very long repetition of the same number
-1.126596170334544
-1.126596170334544
NaN
NaN
... # NaN forever
Something must be wrong with your algorithm.

Resources