(defun seq-intersect-p (first second & sequences)
"Determine if FIRST, SECOND and any of the sequences in SEQUENCES have
an intersection."
(if (seq-empty-p sequences)
(seq-intersection first second)
(or (seq-intersection first second)
(apply #'seq-intersect-p
first
(seq-first sequences)
`,@(seq-rest sequences))
(apply #'seq-intersect-p
second
(seq-first sequences)
`,@(seq-rest sequences))
(apply #'seq-intersect-p
(seq-first sequences)
(seq-elt sequences 2)
`,@(seq-rest (seq-rest sequences))))))
Instead of storing intersect-p as a variable and keeping it until the end of the loop, you can return early as soon as you find the first intersection.
Even though a hash table has better symtotic run time, you might find after benchmarking that the O(n^2) is faster for your use case. If you are set on using a hash table, you might consider setting the initial size to something a bit larger (relative to the input lists) to avoid having to dynamically grow the hash table.
I think also the return value of the inner loop is never used...
I personally like to keep my tests assertions top level so I can interactively run each one by itself.
Oh!? And I was under the impression that the code reads more naturally than the initial version 😂
Let me try putting it in words and see if it makes sense to you:
Given sequences seq1 and seq2 and sequence of sequences sequences, seq-intersect-p should return non-nil if at least one pair of the input sequences have got an intersection.
If seq1 and seq2 intersect return t
Recursively check if seq1 intersects w/ any element in sequences. If it does, return t. Otherwise we know seq1 is safe to be ignored - no intersection whatsoever.
Recursively check if seq2 intersects w/ any element in sequences. If they don't, we know seq2 is safe to be ignored too.
Recursively check if any elements of sequences intersect w/ each other.
There's no caching or optimisation in this version. So it's always O(n2).