Generate numbers in Ruby that aren't equal to other numbers? - ruby

Basically I am generating numbers and they can't be equal to any other numbers I've generated. Is there a quicker way to do this because it looks slightly ridiculous.
Thanks
#possible generated values
x1 = 0
x2 = 1
x3 = 2
#generate co-ordinates
x4 = rand(7)
until x4 != x1 && x4 != x1+1 && x4 != x1+2 && x4 != x2 && x4 != x2+1 && x4 != x2+2 && x4 != x3 && x4 != x3+1 && x4 != x3+2 do
x4 = rand(7)
end
#possible generated values
y1 = 0
y2 = 1
y3 = 2
y4 = rand(7)
until y4 != y1 && y4 != y1+1 && y4 != y1+2 && y4 != y2 && y4 != y2+1 && y4 != y2+2 && y4 != y3 && y4 != y3+1 && y4 != y3+2 do
y4 = rand(7)
end

For Ruby 1.9+
(0..6).to_a.sample(x)
or for older versions
(0..6).to_a.shuffle.take(x)
where x is the number of integers you want to take. Since rand(7) does not include the number 7, you need your range to be one less than the number you'd pass to rand.
And obviously you can't take more numbers than are in the range.

Related

Lost Robot program

This is an ICPC online round question. I checked sample input and my own imaginary inputs.
This is link to question
Here is my code. This code is in Python.
for _ in range(int(input())):
x1,y1,x2,y2=map(int,input().split())
if (x2-x1==y2-y1)or((x2-x1!=0)and(y2-y1!=0)):
print('sad')
elif (x2-x1==0 and y2-y1>0):
print('up')
elif (x2-x1==0 and y2-y1<0):
print('down')
elif (y2 - y1 == 0 and x2 - x1 > 0):
print('right')
elif (y2 - y1 == 0 and x2 - x1 < 0):
print('left')
Can anyone suggest inputs for that code will not work?? If code is correct for all inputs , any modification will be welcomed?.
Your code already does not parse the input correctly. Have a look:
python /tmp/test.py
1
0 0 0 1
Traceback (most recent call last):
File "/tmp/test.py", line 3, in <module>
x1, y1, x2, y2 = map(int, input().split())
File "<string>", line 1
0 0 0 1
^
Besides from that, it seems to be logical correct.
However, your coding style is improvable. Have a look at my version:
for _ in range(int(input())):
x1, y1, x2, y2 = map(int, input().split())
if x1 != x2 and y1 != y2:
print('sad')
elif x1 == x2 and y1 < y2:
print('up')
elif x1 == x2 and y1 > y2:
print('down')
elif y1 == y2 and x1 < x2:
print('right')
elif y1 == y2 and x1 > x2:
print('left')
The only thing I changed was to improve the conditions. Furthermore, I removed the redundant condition at the bottom.
As a former participant of NWERC and ACM-ICPC I can only suggest to have an eye on readable code. It is not as important as in production code bases, but it helps a lot when you have to debug printed code, as happens at real competitions.

Does two sets of three numbers have at least two numbers in common?

I just had to write a function that seemed simple to write, but when I actually did it, it turned out way gorier than I had expected. It's really bugging me, I feel like there's a better solution, but my brain is going crazy trying to think of it, so therefore I'm turning to you fine folks.
Basically, I have 2 triangles, and I want to know if they share a common edge. The triangles are indexed by their vertices (i.e. their vertices is just an index to an array containing the actual coordinates), so it comes down to finding if two sets of three numbers have two numbers in common. I.e. triangles (1,2,3) and (3,1,5) do share an edge, the (1,3) edge. However, triangles (1,2,3) and (1,5,6) does not share an edge (only a vertex) and neither does (1,2,3) and (4,5,6).
How would you write this "two numbers in common function"? You can assume all values inside each set are distinct (i.e. (1, 1, 2) is not going to be an input) and you can also assume that two sets don't equal each other (i.e. I'm not going to compare (1,2,3) and (1,3,2), because those two are the same triangle). However, no assumptions can be made regarding order, they are not sorted or anything like that.
This is basically what I came up with (assuming the sets are (x0, x1, x2) and (y0, y1, y2)):
// If the x0 is equal to any of (y0, y1, y2), make sure at least one of (x1, x2)
// is equal to one of the y numbers
if (x0 == y0) {
return x1 == y1 || x1 == y2 || x2 == y1 || x2 == y2;
} else if (x0 == y1) {
return x1 == y0 || x1 == y2 || x2 == y0 || x2 == y2;
} else if (x0 == y2) {
return x1 == y0 || x1 == y1 || x2 == y0 || x2 == y1;
} else {
// if x0 is not equal to any of (y0, y1, y2), then x1 and x2 both have
// to be equal to two of the y numbers.
return (x1 == y0 && x2 == y1)
|| (x1 == y0 && x2 == y2)
|| (x1 == y1 && x2 == y0)
|| (x1 == y1 && x2 == y2)
|| (x1 == y2 && x2 == y0)
|| (x1 == y2 && x2 == y1);
}
but it feels so gory to me! So many branches and such long boolean statements! I feel like i'm missing an obvious easy solution, and it's driving me insane.
In addition, this happens in an inner loop in a very performance sensitive application, so performance (branching, arithmetic, whatever) matters.
BTW, the code I'm writing is C#, but the question is the same in more or less any imperative language.
EDIT:
I put together a quick benchmark (here's the code) with the suggestions so far. Here are the results (running it at a million random pairs of triangles):
Original method result: 7035, time elapsed in ms: 8.6252
qwertyman method result: 7035, time elapsed in ms: 8.2537
midjji method result: 7035, time elapsed in ms: 8.7984
Single HashSet method result: 7035, time elapsed in ms: 184.4984
Many HashSets method result: 7035, time elapsed in ms: 190.5785
The numbers remain fairly consistent run to run, with #qwertyman's method always being a bit faster than my original version or #midjii's. It also has the advantage of being the cleanest and nicest of them all, so I'm going to go with that one.
I was actually a bit surprised that the "Many HashSets" was so close to "Single HashSet", I would have thought constructing a million HashSets would have a bigger overhead than around 16 milliseconds (though this obviously doesn't count the increased pressure on the garbage collector), though they're both obviously far behind the other methods.
Thanks for the help!
You can do something like this:
int n = 0;
// check if x0 is among the values in the second set
if (x0 == y0 || x0 == y1 || x0 == y2) {
n++;
}
// check if x1 is among the values in the second set
if (x1 == y0 || x1 == y1 || x1 == y2) {
n++;
}
// check if x2 is among the values in the second set
if (x2 == y0 || x2 == y1 || x2 == y2) {
n++;
}
return n >= 2;
This relies on the fact that (as you mentioned) the numbers in each set are distinct, resulting in a simpler logic.
If you are using C, you could write it shorter:
int n = 0;
n += x0 == y0 || x0 == y1 || x0 == y2;
n += x1 == y0 || x1 == y1 || x1 == y2;
n += x2 == y0 || x2 == y1 || x2 == y2;
return n >= 2;
I would use:
...
{
//ti= xi in y
bool t0= (x0==y0) ||(x0==y1)|| (x0==y2);
bool t1= (x1==y0) ||(x1==y1)|| (x1==y2);
bool t2= (x2==y0) ||(x2==y1)|| (x2==y2);
return (t0 && t1) || (t0 && t2) || (t1 && t2);
}
Mostly because I think its easier to read.
Performance-wise it is rather likely that with the right settings it should be as fast. Compilers are fantastic at optimizing self enclosed, no side effect, logical statements and use lazy evaluation for bool(assuming nothing silly has been done to ==).

Extended find of unique tuples in a relation represented by a BDD

Consider {<1,2>, <1,3>, <1,7>, <0,4>} as the set of tuples of a relation R. Now consider that R is represented (via its membership function) by a BDD. That is, The BDD representing R depends on variables {x1,x2, y1, y2, y3} where {x1, x2} are used to represent the first element of every tuple and {y1, y2, y3} are used to represent the second element.
Now, consider the problem of finding the set of tuples that have unique values in its first element. For the relation above that set would be {<0,4>}. All the other elements are discarded as they are more than one value having 1 in the first component.
As a second example consider the relation with set of tuples {<1,2>, <1,3>, <1,7>, <2,3>, <2,5>, <0,4>}. In such a case the expected result is still {<0,4>} as 2 appears more than once as first element.
The problem can be also seen as abstracting away the variables {y1,y2,y3} such that only unique values for {x1,x2} remain. With this result, the expected relation can be reconstructed by computing the conjunction of the resulting BDD with the input one.
In summary, the the question is: which are the BDD operations that have to be performed on The representation of R to obtain the BDD with only the unique tuples.
Notice that this is a genralization of this question
EDIT 1:
The following code reflects the implementation I have so far. However, I am wondering if it is possible to get a more efficient version. For simplicity I intentionally omit the handling of the computed table (crucial to get better time complexity). Additionally, I use &, | and ! to denote the conjunction, disjunction and complement operations on BDDs.
BDD uniqueAbstract(BDD f, BDD cube) {
if ((f.IsZero() || f.IsOne()) && !cube.IsOne())
return zero();
BDD T = high(f);
BDD E = low(f);
if(level(f) == level(c)) { // current var is abstracted
BDD uniqueThen = uniqueAbstract(T, high(c));
BDD existElse = existAbstract(E, high(c));
BDD existThen = existAbstract(T, high(c));
BDD uniqueElse = uniqueAbstract(E, high(c));
return (uniqueThen & !existElse) | (uniqueElse & !existThen)
} else {
BDD uniqueThen = uniqueAbstract(T,c);
BDD uniqueElse = uniqueAbstract(E,c);
return ite(top(f), uniqueThen, uniqueElse);
}
}
EDIT2: After trying three different implementations there are still some performance issues. Let me describe the three of them.
A C implementation of my approach, let me call it the reference implementation4.
The implementation proposed by user meolic in the accepted answer3.
A hybrid approach between the two and available2.
The goal of this update is to analyze a bit the results from using the three approaches. As time measures seem misleading at this time to judge them, I decided to evaluate the implementations on a different set of measures.
Recursive calls
Cache hits
Abstract simple. Number of times the function call was solved without requiring existential abstraction.
Abstract complex: Number of times the function call was solved requiring existential abstraction.
Exist abstract: Number of calls to the existential abstraction.
The results for implementation 1: (21123 ms):
Unique abstraction statistics:
Recursive calls: 1728549.000000
Cache hits: 638745.000000
Non abstract: 67207.000000
Abstract simple: 0.000000
Abstract complex: 0.000000
Exist abstract: 1593430.000000
Results for implementation 2: (run time: 54727 ms)
Unique abstraction statistics:
Recursive calls: 191585.000000
Cache hits: 26494.000000
Abstract simple: 59788.000000
Abstract complex: 12011.000000
Exist abstract: 24022.000000
Results for implementation 3: (run time: 20215 ms)
Unique abstraction statistics:
Recursive calls: 268044.000000
Cache hits: 30668.000000
Abstract simple: 78115.000000
Abstract complex: 46473.000000
Exist abstract: 92946.000000
EDIT 3: The following results were obtained after implementing every logical operation in terms of ITE5.
uniqueAbstractRecRef (21831 ms)
Unique abstraction statistics:
Total calls: 1723239
Optimized calls: 0
Total exist abstract calls: 30955618
Unique abstract calls to exist abstract: 2385915
Total ite calls: 3574555
Out of the total time, uniqueAbstractRecRef takes 4001 ms (12.4%)
uniqueAbstractSERec (56761 ms)
Unique abstraction statistics:
Total calls: 193627
Optimized calls: 60632
Total exist abstract calls: 16475806
Unique abstract calls to exist abstract: 24304
Total ite calls: 1271844
Out of the total time, uniqueAbstractSERec takes 33918 ms (51.5%)
uniqueAbstractRec (20587 ms)
Unique abstraction statistics:
Total calls: 270205
Optimized calls: 78486
Total exist abstract calls: 13186348
Unique abstract calls to exist abstract: 93060
Total ite calls: 1256872
Out of the total time, uniqueAbstractRec takes 3354 ms (10.6%)
There exist simple and efficient solution if variables are ordered in such a way that x1 and x2 are at the top of BDD.
Consider BDD for second example.
You can traverse (in breadth-first order) first two layers of it to get four sub-BDDs. One for each possible combination of x1,x2. Three of those sub-BDDs a rooted at y1 and fourth is empty (constant False).
Now you can count number of elements in each sub-BDD (Algorithm C from Knuth's Volume 4 Fascicle 1, Bitwise Tricks & Techniques; Binary Decision Diagrams).
If number of elements in sub-BDD is greater than 1 then drop it (shortcut from parent node directly to False), otherwise leave it as it is.
It is possible to run this algorithm in single pass by memoizing partial results while counting elements.
Here is my implementation. I have studied author's proposed solution and it seems to me that it is the best if not the only simple BDD-based solution for arbitrary ordering. However, there may be some improvements if the algorithm is implemented in my way- PLEASE CHECK. I am using my own wrapper over BDD package but you should not have any troubles to understand it.
EDITED: I have simplified the solution, function Bdd_GetVariableChar() is not used anymore.
/* TESTING SOLUTION FOR QUESTION ON STACK OVERFLOW */
/* bdd_termFalse,bdd_termTrue: Boolean constants */
/* Bdd_isTerminal(f): check if f is Boolean constant */
/* Bdd_Low(f),Bdd_High(f): 'else' and 'then' subfunction */
/* Bdd_Top(f): literal function representing topvar of f */
/* Bdd_IsSmaller(f,g): check if topvar of f is above topvar of g */
/* existentialAbstraction(f,cube): \exist v.f for all v in cube */
Bdd_Edge specialAbstraction(Bdd_Edge f, Bdd_Edge cube) {
if (Bdd_isTerminal(cube)) return f;
if (Bdd_isTerminal(f)) return bdd_termFalse;
if (Bdd_IsSmaller(f,cube)) {
Bdd_Edge E,T;
E = specialAbstraction(Bdd_Low(f),cube);
T = specialAbstraction(Bdd_High(f),cube);
return Bdd_ITE(Bdd_Top(f),T,E);
} else if (Bdd_IsSmaller(cube,f)) {
return bdd_termFalse;
} else {
Bdd_Edge E,T;
cube = Bdd_High(cube);
E = Bdd_Low(f);
T = Bdd_High(f);
if (Bdd_isEqv(E,bdd_termFalse)) {
return specialAbstraction(T,cube);
} else if (Bdd_isEqv(T,bdd_termFalse)) {
return specialAbstraction(E,cube);
} else {
Bdd_Edge EX,TX,R;
EX = existentialAbstraction(E,cube);
TX = existentialAbstraction(T,cube);
if (Bdd_isEqv(EX,TX)) return bdd_termFalse;
R = Bdd_ITE(Bdd_ITE(EX,bdd_termFalse,T),
bdd_termTrue,
Bdd_ITE(TX,bdd_termFalse,E));
return specialAbstraction(R,cube);
}
}
}
And, yes, if variable ordering is fixed with x above y, the algorithm can really be much more efficient - you can remove all the calculations from the most complex 'else' block and just return 0.
Here are some testing runs:
CUBE (JUST IN CASE YOU ARE NOT FAMILIAR WITH BDD ALGORITHMS)
+ y1 y2 y3 y4 y5
ORIGINAL (ORDERED WITH X ABOVE Y)
+ *x1 *x2 x3 *x4 x5 y1 *y2 y3 y4 y5
+ *x1 x2 *x3 *x4 *x5 y1 y2 *y3 y4 y5
+ *x1 x2 *x3 *x4 x5 *y1 y2 *y3 y4 y5
+ *x1 x2 *x3 x4 *x5 y1 *y2 y3 *y4 *y5
+ *x1 x2 x3 *x4 x5 *y1 *y2 *y3 *y4 y5
+ *x1 x2 x3 *x4 x5 *y1 y2 y3 *y4 *y5
+ x1 *x2 *x3 *x4 *x5 y1 y2 y3 y4 *y5
+ x1 x2 *x3 x4 x5 *y1 *y2 *y4 *y5
+ x1 x2 x3 *x4 *x5 *y1 *y2 *y3 y4 *y5
ABSTRACTION
+ *x1 *x2 x3 *x4 x5
+ *x1 x2 *x3 *x4
+ *x1 x2 *x3 x4 *x5
+ x1 *x2 *x3 *x4 *x5
+ x1 x2 x3 *x4 *x5
ORIGINAL (ORDERED WITH Y ABOVE X)
+ *y1 *y2 *y3 *y4 *y5 x1 x2 *x3 x4 x5
+ *y1 *y2 *y3 *y4 y5 *x1 x2 x3 *x4 x5
+ *y1 *y2 *y3 y4 *y5 x1 x2 x3 *x4 *x5
+ *y1 *y2 y3 *y4 *y5 x1 x2 *x3 x4 x5
+ *y1 y2 *y3 y4 y5 *x1 x2 *x3 *x4 x5
+ *y1 y2 y3 *y4 *y5 *x1 x2 x3 *x4 x5
+ y1 *y2 y3 *y4 *y5 *x1 x2 *x3 x4 *x5
+ y1 *y2 y3 y4 y5 *x1 *x2 x3 *x4 x5
+ y1 y2 *y3 y4 y5 *x1 x2 *x3 *x4 *x5
+ y1 y2 y3 y4 *y5 x1 *x2 *x3 *x4 *x5
ABSTRACTION
+ *x1 *x2 x3 *x4 x5
+ *x1 x2 *x3 *x4
+ *x1 x2 *x3 x4 *x5
+ x1 *x2 *x3 *x4 *x5
+ x1 x2 x3 *x4 *x5
ORIGINAL (MIXED ORDER)
+ *x1 *x2 y1 *y2 y3 y4 y5 x3 *x4 x5
+ *x1 x2 *y1 *y2 *y3 *y4 y5 x3 *x4 x5
+ *x1 x2 *y1 y2 *y3 y4 y5 *x3 *x4 x5
+ *x1 x2 *y1 y2 y3 *y4 *y5 x3 *x4 x5
+ *x1 x2 y1 *y2 y3 *y4 *y5 *x3 x4 *x5
+ *x1 x2 y1 y2 *y3 y4 y5 *x3 *x4 *x5
+ x1 *x2 y1 y2 y3 y4 *y5 *x3 *x4 *x5
+ x1 x2 *y1 *y2 *y3 *y4 *y5 *x3 x4 x5
+ x1 x2 *y1 *y2 *y3 y4 *y5 x3 *x4 *x5
+ x1 x2 *y1 *y2 y3 *y4 *y5 *x3 x4 x5
ABSTRACTION
+ *x1 *x2 x3 *x4 x5
+ *x1 x2 *x3 *x4
+ *x1 x2 *x3 x4 *x5
+ x1 *x2 *x3 *x4 *x5
+ x1 x2 x3 *x4 *x5
One approach involves directly translating the definition of uniqueness:
R(x,y) and forall z . ~R(x,z) or y = z
An implementation may look like this:
def inspect(function, name, nvars):
sys.stdout.write(name) # avoid print's trailing space or newline
function.summary(nvars) # minterm count needs number of variables
function.printCover()
import sys
from cudd import Cudd
m = Cudd()
nx = 2
ny = 3
x = [m.bddVar() for i in range(nx)]
y = [m.bddVar() for i in range(ny)]
R = (~x[0] & x[1] & (~y[0] & y[1] | y[1] & y[2]) |
x[0] & ~x[1] & (y[0] ^ y[1]) & y[2] |
~x[0] & ~x[1] & y[0] & ~y[1] & ~y[2])
# This approach is independent of variable order. We are free to enable
# reordering or call it explicitly.
m.reduceHeap()
inspect(R, 'R', nx+ny)
# Create auxiliary variables and selector function.
z = [m.bddVar() for i in range(ny)]
zcube = reduce(lambda a, b: a & b, z)
P = ~m.xeqy(y,z)
# A pair is in L iff:
# - it is in R
# - there is no other pair in R with the same x and different y
L = R & ~(R.swapVariables(y,z).andAbstract(P,zcube))
inspect(L, 'L', nx+ny)
Result of running that code:
R: 10 nodes 1 leaves 6 minterms
01-11 1
10101 1
10011 1
00100 1
0101- 1
L: 6 nodes 1 leaves 1 minterms
00100--- 1
The first two variables encode the first element of the pair; the next three variables encode the second element of the pair; the last three variables are the auxiliary variables.
The code applies DeMorgan's to the formula above to make use of andAbstract.

non-negative integer solutions to system of linear equations in mathematica

Related to my previous question, just wonder how to solve a system of linear equations with non-negative integral solutions, for example:
c11*x+c12*y+c13*z=d1
c21*x+c22*y+c23*z=d2
Thanks a lot!
Edit
I meant efficiently. For example, I could have used FrobeniusSolve to get two solution lists and try to find the intersection. But sometimes, the individual solution list is probably hugely large. Or try to verify each individual solution returned by one FrobeniusSolve to see whether they satisfy all the remaining equations, but that suffers from the same drawback.
Reduce is able to solve these types of problems.
To answer the specific case in your comment above:
In[1]:= solns = Reduce[x1 + 2 x2 + 5 x3 + 7 x4 == 40 &&
x1 + x2 + 2 x3 + x4 == 20 &&
x1 > 0 && x2 > 0 && x3 > 0 && x4 > 0,
{x1, x2, x3, x4}, Integers]
Out[1]= (x1 == 6 && x2 == 11 && x3 == 1 && x4 == 1) ||
(x1 == 7 && x2 == 8 && x3 == 2 && x4 == 1) ||
(x1 == 8 && x2 == 5 && x3 == 3 && x4 == 1) ||
(x1 == 9 && x2 == 2 && x3 == 4 && x4 == 1) ||
(x1 == 11 && x2 == 5 && x3 == 1 && x4 == 2) ||
(x1 == 12 && x2 == 2 && x3 == 2 && x4 == 2)
Edit:
You can check that this is the same solution you get by solving the two equations separately and taking the intersection of their solutions:
In[2]:= a = Reduce[x1 + 2 x2 + 5 x3 + 7 x4 == 40 &&
x1 > 0 && x2 > 0 && x3 > 0 && x4 > 0,
{x1, x2, x3, x4}, Integers];
b = Reduce[x1 + x2 + 2 x3 + x4 == 20 &&
x1 > 0 && x2 > 0 && x3 > 0 && x4 > 0,
{x1, x2, x3, x4}, Integers];
In[4]:= solns == Intersection[a, b]
Out[4]= True
And you can extract the solutions by, e.g.,
turning the solutions into a list of replacement rules
and applying to the variables:
In[5]:= {x1, x2, x3, x4} /. {ToRules[solns]}
Out[5]= {{6, 11, 1, 1}, {7, 8, 2, 1}, {8, 5, 3, 1},
{9, 2, 4, 1}, {11, 5, 1, 2}, {12, 2, 2, 2}}

how to assign integration limits in mathematica after solving a set of inequalities

I have a set of inequalities, for example,
2 x1 >=3 x2 && 0<=x1<=1 && 0<=x2<=1
which can be solved with Reduce. Then I want to do an integration for the function f(x1,x2)=1/x1 in the area defined by the inequalities above. In this case, Reduce gives a result
(x1 == 0 && x2 == 0) || (0 < x1 <= 1 && 0 <= x2 <= (2 x1)/3)
Then I can do integration by using
Integrate[Integrate[1/x1, {x2, 0, 2 x1/3}], {x1, 0, 1}]
But these all need my manual intervention. How do I do this in a streamline fashion? Many thanks!
Integrate[1/x1 Boole[2 x1 >= 3 x2 && 0 <= x1 <= 1 &&0 <= x2 <= 1], {x1, -\[Infinity], \[Infinity]}, {x2, -\[Infinity], \[Infinity]}]

Resources