This can be easily solved using the correct data structures, but in case you want to do it manually, here is how I will do it in Haskell. I donβt know F # is enough to translate this, but I hope this is similar enough. So, here, in (semi) literate Haskell.
overlap xs ys =
I will start by sorting the two sequences in order to get away from the problem of having to know about the previous values.
go (sort xs) (sort ys) where
Two basic cases for recursion are simple enough to process - if one of them is empty, the result includes another list in the list of elements that do not overlap.
go xs [] = ([], (xs, [])) go [] ys = ([], ([], ys))
Then I check the first items in each list. If they match, I can be sure that the lists overlap over this element, so I add this to the included elements and I allow the excluded elements. I continue to search the rest of the list, recursing along the tails of the lists.
go (x:xs) (y:ys) | x == y = let ( included, excluded) = go xs ys in (x:included, excluded)
Then comes the interesting part! What I essentially want to know is that the first element of one of the lists does not exist in the second list - in this case I must add it to the excluded lists and continue the search.
| x < y = let (included, ( xex, yex)) = go xs (y:ys) in (included, (x:xex, yex)) | y < x = let (included, ( xex, yex)) = go (x:xs) ys in (included, ( xex, y:yex))
And it really is. This seems to work, at least for the example you gave.
> let (matched, unmatched) = overlap xy > matched [2,2,3] > unmatched ([1,3],[4,4,5])