Bitvector operations: M & (N-1) - collections

I'm dealing with collections represented as a bitvector.
Last I saw something like M & (N-1). Both M and N are collections, both non empty.
What means the outcome of this in terms of collections?

Related

Propositional logic, logical equivalent

a) Determine whether the following statement forms are logically equivalent:
p -> (q -> r) and (p -> q) -> r
b) Use the logical equivalence established in part (a) to rewrite the following sentence in two different ways. (Assume that n represents a fixed integer.)
If n is prime, then n is odd or n is 2.
Can someone help me with the B one? its really confusing
If n is prime, then n is odd or n is 2.
The question is asking you to rewrite the sentence in two different ways in English
If n is prime and n is not odd, then n is 2.
If n is prime and n is not 2, then n is odd.
The following links do a better job of explaining it:
Logically_Equivalent_Statements
Exercises on Logic of Compound Statements and Valid Arguments

All possible co-prime computation efficiently

I need a function which will give me is_coprime(m, n) in constant time. In my case, 1 < m, n < 100. So I can easily pre-compute the values and store them in an 100x100 array.
My approach would be to store gcd(m,n) == 1 for each m,n index in the array. However this is also time-consuming. So I was wondering if there is a well-known algorithmic solution for this type of problems, where all possible gcd / co-prime over a 1 to N range is needed.

White-box and Black-box testing of recursive functions

I learned white-box and black-box testing in terms of iterative functions. Now i need to do white-box and black-box testing of several recursive functions (in F#). take the following recursive algorithm for gcd:
gcd (m, n)
if (m % n) = 0 then
n
else
gcd n ( m % n)
For the white-box test: how exactly do i go about covering the different branches of the algorithm? Naively one could say there are two branches but when the function is called more than once the possible branches will obviously increase. Should i do testing with arguments which results in different amounts of recursive calls or how exactly do i determine which values to test with?
black-box: i get the general idea of black box testing. we should look at possible values we might want to call the function with without having knowledge of its inner workings. In this case i am just not sure which are values we might want to call it with. one way could be just to start with two values m and n for which gcd = 1 and then do the same for values m and for which gcd = 2 up to some gcd= n for some arbitrary number n. Is this how one is supposed to go about this?
First of all, I don't think there is one single established definition of how to do white-box and black-box testing of recursive functions, but here is how I interpret it.
White-box testing. We want to test the function based on its inner working. In case of recursive functions, I think this means that we want to test that the recursive calls it makes are the ones we would expect. One way to do this is to log all recursive calls. A simple implementation of gcd that does this adds a parameter to keep a log and returns it with the result:
let rec gcd log m n =
let log = (m, n)::log
if (m % n) = 0 then List.rev log, n
else gcd log n (m % n)
Now, for some two parameters, say 54 and 22, you can do the calculation by hand, decide what the parameters of the recursive calls should be and write a test for that:
let log, res = gcd [] 54 22
log |> shouldEqual [ (54, 22); (22, 10); (10, 2) ]
Black-box testing. Here, we assume we do not know how exactly the function works, so we cannot test its internals. All we can do is to test it using a number of inputs. It is probably a good idea to think of corner-case or tricky inputs because those are the ones that could cause problems. Given a simple implementation:
let rec gcd m n =
if (m % n) = 0 then n
else gcd n (m % n)
I would probably write tests for the following:
// A random case where one of the numbers is the result
gcd 100 50 |> shouldEqual 50
gcd 50 100 |> shouldEqual 50
// A random case where the only divisor is 1
gcd 13 123 |> shouldEqual 1
gcd 123 13 |> shouldEqual 1
// The following are problematic and I'm not sure what the right behaviour is
gcd 0 0 // This probably should not be allowed
gcd 10 -5 // This returns -5, but I'm not sure that's what we want
Random testing.
You could also use random testing (which is a form of black box testing) to generate multiple test cases automatically. There are at least two random tests I can think of:
Generate two random numbers, a and b and check that gcd a b = gcd b a. This is testing only a very basic property, but it can cover quite a lot of cases.
Pick a random number a and a couple of primes p1, p2, .... Then split the primes into two groups and produce a*p1*p3*p5 and a*p2*p4*p6. Write a test that checks that the GCD of the two numbers is a.

Union and intersection operations on collections in Cypher (Neo4j)

I need to calculate both the union and the intersection of a set of arrays/collections in Cypher. Let's say for instance I have the topics of interest of a number of individuals saved as array properties for each individual node and I need to know (1) the topics that every member of a given group find interesting; but I also need to know (2) the topics that may attract the attention of any of the group members.
So, take the following individuals as the members of a group of two:
CREATE ({name: 'bill', interests: ["biking", "hiking", "fishing", "swimming"]})
CREATE ({name: 'joe', interests: ["swimming", "hiking", "biking", "tennis"]})
Inspired by this great answer I have written the following scripts to get what I need:
Intersection (n.interests ∩ m.interests)
MATCH (n {name:'bill'}), (m {name:'joe'})
RETURN FILTER(x IN n.interests WHERE x IN m.interests)
Response: biking, hiking, swimming
Union (n.interests ∪ m.interests)
MATCH (n {name:'bill'}), (m {name:'joe'})
RETURN FILTER(x IN n.interests WHERE x IN m.interests)+
FILTER(x IN n.interests WHERE NOT(x IN m.interests))+
FILTER(x IN m.interests WHERE NOT(x IN n.interests))
Response: biking, hiking, swimming, fishing, tennis
Both work pretty well for groups of two. The problem is the union script is not generalizable and needs to be expanded further for each additional group member. This is because instead of doing a straightforward n.interests ∪ m.interests I am going the long way by producing (n.interests ∩ m.interests) ∪ (n.interests - m.interests) ∪ (m.interests - n.interests) which equals n.interests ∪ m.interests, but necessitates pairwise comparison of all individuals in the group.
Hence my question: Is there any better way in Cypher to produce the union of two collections/arrays, without redundant results in the response collection?
P.S. As you may have noticed these interests don't really have an ordering, so I am actually treating Neo4j collections as sets.
P.S.2 It is possible that I am misunderstanding and incorrectly conflating the notions of collection and array in Cypher, in which case please don't hesitate to point out what the mistake is.
APOC Procedures has union and intersection functions, should be exactly what you need.
MATCH (n {name:'bill'}), (m {name:'joe'})
RETURN apoc.coll.union(n.interests, m.interests) as interests_union,
apoc.coll.intersection(n.interests, m.interests) as interests_intersection
The above is usable with Neo4j 3.1 and up (which supports user-defined functions). In Neo4j 3.0, these are procedures instead, and you'll need to CALL them as procedures.
This is also easily applied to multiple collections, instead of just two. If the collections are collected, you can run REDUCE() on the list of lists to apply the union or intersection for all collections.
I recently solved the same problem by first taking the duplicated union, and then deduplicating using distinct
MATCH (n {name:'bill'}), (m {name:'joe'})
UNWIND n.interests + m.interests AS interests
RETURN COLLECT(distinct interests) AS interests_union
I think you can generalize it using reduce to produce your collections.
And probably use one of the quantor-predicates (ANY,ALL, SINGLE, NONE)
Something like this for intersection:
WITH [1,2,3] as a, [3,4,5] as b, [2,3,4] as c
REDUCE (res=[], x in a | case when x in b AND x in c then res + [x] else res)
WITH [1,2,3] as a, [3,4,5] as b, [2,3,4] as c
REDUCE (res=[], x in a | case when ALL(coll in [b,c] WHERE x in coll) then res + [x] else res)
But all of these operations won't have really good runtime characteristics.

How to shuffle list in O(n) in OCaml?

It is not hard to shuffle an array in O(n), with in place swapping,
How to do it for list in OCaml, with O(n)?
Requirement:
No array or in place usage
Consider this as an interview question
Lists are immutable, and there's often a log n price to pay for working with immutable data. If you're willing to pay this cost, there's an obvious n log n approach: tag each list element with a random value, sort based on random value, remove random values. This is the way I shuffle lists in my production code.
Here is the shuffle code from the iOS apps that I sell:
let shuffle d =
let nd = List.map (fun c -> (Random.bits (), c)) d in
let sond = List.sort compare nd in
List.map snd sond
You could mimick the riffle shuffle for cards.
A riffle shuffle of a deck of cards means to:
cut the deck in two parts
interleave the two parts
It is actually easier to do the reverse permutation:
have two auxiliary lists A and B, iter through your original list L and push each element randomly (with probability 1/2) in front of A or B.
L := List.rev A # List.rev B (this can be tail recursive with a custom List.rev).
repeat k times.
According to "Mathematical developments from the analysis of riffle shuffling, by Persi Diaconis, 2002", choose k = 3/2 log_2(n) + c. Indeed, the total variation distance between uniformity and the result falls exponentially fast to 0: it is approximately halved each time you increment c. You could choose c=10.
Space O(1) (if you destroy L), time O(n log n). But there are O(n log n) calls to the random generator, while Jeffrey Scofield's solution only needs O(n) random bits, but Θ(n) space.

Resources