How to swap values of two variables without using temp variable? - ruby

I have two variables x and y
x = 1
y = 2
I want to swap their value using one line of code without using a temp variable
temp = y
y = x
x = temp
Any idea how?

Try something like this
x, y = y, x

Related

how to write an algorithim to swap two variables without creating the third variable?

how to swap two variables without creating the third variable? for ex. a=10 b=20 so, how can I write an Algorithm to swap these two variable to a=20 b=10 without adding another variable c in my logic?
You can use this technique
a=a+b
b=a-b
a=a-b
Edit 1:
As commented by pjs, the above technique could overflow in some languages so you can use XOR:
a=a^b
b=a^b ## which is b= (a^b)^b=a
a=a^b ## which is b= (a^b)^a=b
int x = 987, y = 123;
x = x xor y;
y = x xor y;
x = x xor y;
Now x and y are swapped:
x = 123, y = 987;

retracting and asserting values in prolog

I have been modelling some directive graphs in prolog. It consists of nodes and edges and how they are connected. Every node has a certain value of surfers (page rank).
e.g.
e(a,c).
e(b,a).
e(b,h).
:-dynamic s/2.
s(a,1).
s(b,1).
s(c,1).
I have written an interpreter. This interpreter calculates new values for each node.
The problem is how to assign these new values to the database.
I have been doing it with retractall(s(,)) and asserting new values to every single node with e.g. assertz(s(a,sum0),
assertz(s(b,sum1), ....
This has been working, but is it possible to assert new values without asserting each particular node in the graph a value, so that the interpreter is completely independent from the graph?
I have been trying to generate a list with all nodes in a graph and indicating the nodes of a graph in this list.
sum_nodes_0(X,Y):-
list_nodes(_,L),
amount_nodes(N),
nth1(I,L,X),I=<N,sum_node(X,Y).
reset(X,S):-
list_nodes(_,L),
s(X,S),
sum_node(X,Y),
retractall(s(_,_)),
forall(member(X,L),assertz(s(X,Y))).
sum_nodes_0 displays me the new values like.
X = a,
Y = 1.0 ;
X = b,
Y = 1 ;
X = c,
Y = 2 ;
X = d,
Y = 0.5 ;
X = e,
Y = 1.5 ;
X = f,
Y = 0.5 ;
X = g,
Y = 1 ;
X = h,
Y = 0.5.
These values I want to be assigned by reset(X,S). But reset just resets one value not all. e.g.
X=h; Y=0
I have tried foreach, forall and member predicates. But it didn't work as intended.
I hope that someone has an idea.

How do I return a list based on an argument to a function in Prolog?

Basically, I want to pass an argument to a function and depending on the value, return one of many lists to display on the console. To be specific, this is the code I wrote:
student(X):- X = Arpit, X = ["Mechanical", "Suits", 1995].
student(X):- X = Manoj, X = ["Computer_Science", "Black_Mirror", 1996].
student(X):- X = Dhruv, X = ["Civil", "House_of_Cards", 1997].
student(X):- X = Srishti, X = ["Electronics", "Mr_Robot", 1995].
The idea is to return one of the four lists, depending on the value of the variable (Arpit/Manoj/Dhruv/Srishti). But when I call the function as student(Arpit), it returns:
Arpit = ["Mechanical, "Suits", 1995]
when I call student(Manoj/Dhruv/Srishti) also, it returns the same list, irrespective of the value of the variable. How do I solve this?
In prolog, you have relations not functions. So your predicate will need two arguments, and you can only bind variables to values once.
Another thing is that variables are denoted with capital letters so you cant just say X =Arpit as this means that the vairable X is bound to the vairable Arpit so you either need to use lowercase names or enclose the name in quotes.
student(X,Y):- X = "Arpit", Y = ["Mechanical", "Suits", 1995].
student(X,Y):- X = "Manoj", Y = ["Computer_Science", "Black_Mirror", 1996].
student(X,Y):- X = "Dhruv", Y = ["Civil", "House_of_Cards", 1997].
student(X,Y):- X = "Srishti", Y = ["Electronics", "Mr_Robot", 1995].
?- student("Arpit", List).
List = ["Mechanical", "Suits", 1995].
You can also generate all pairs with :
?- student(Name,List).
Name = "Arpit",
List = ["Mechanical", "Suits", 1995];
You can hit space for more results here
Or find the name associated with a list:
?- student(Name,["Mechanical", "Suits", 1995]).
Name = "Arpit".
Or check if a pair exists at all:
?- student("Fred",["Extra", "Shirts", 2010]).
false.

Assigning values to multiple variables in Go

I recently came up across this:
func main() {
x, y := 0, 1
x, y = y, x+y
fmt.Println(y)
}
What I thought was that:
x, y = y, x+y
Is identical to:
x = y
y = x+y
Which would result to final values x = 1, y = 2
However the final values I get is x = 1, y = 1
Why is that?
Thanks.
This is how it's specified:
The assignment proceeds in two phases. First, the operands of index expressions and pointer indirections (including implicit pointer indirections in selectors) on the left and the expressions on the right are all evaluated in the usual order. Second, the assignments are carried out in left-to-right order.
Assignment first evaluates all expressions on the right side and then assigns the results to the variables on the left side.
Your
x, y = y, x+y
is basically equivalent to this
tmp1 := y
tmp2 := x+y
x = tmp1
y = tmp2
You can even use this fact to swap 2 variables in one line, like this:
a, b = b, a

Python vs Ruby: Is y greater than x and less than z?

Is there a less verbose way to compare three integer values in Ruby?
For example, in Python the following return True:
x = 2
y = 3
z = 4
x < y < z
With the same variable bindings in Ruby the following will both return true:
x < y && y < z
x.send(:<, y) && y.send(:<, z)
but this:
x < y < z
returns NoMethodError:
NoMethodError: undefined method `<' for true:TrueClass
I presume this is because the first comparison of x < y evaluates to true and the error is raised from the resulting TrueClass.instance < z? Is there a way in Ruby to compare three integer values without the use of &&?
Thank you.
You can write
(x+1...z).cover? y
or (my preference)
(x+1..z-1).cover? y
Because x, y and z are numeric, this is the same as
(x+1..z-1).include? y
See Range#cover? and Range#include?.

Resources