Two solutions designed by my esteemed colleague Marshall, master of speeding up APL. The formulas used are both in '70s APL, so they works in APL\360 on an IBM/360 mainframe. They are anonymous prefix functions taking a character matrix as argument. N
is not needed but may be supplied as optional (and ignored) left argument.
The first solution is O(n2)
A naive approach:
{0.5×(+/,(⍉i)∧.∨i)-+/∧⌿i←∨/'aeiou'∘.=⍵}
Try it online!
Processes* the large data set in about 4.5 ms. TIO takes about twice that.
{
…}
"dfn"; the argument is ⍵
:
'aeiou'∘.=⍵
equality 3D array with vowels along the first axis, words along the middle axis and characters along the last axis
∨/
OR-reduction along the last axis; this gives us a 5-row table with one column per word
i←
store that in i
(for in)
∧⌿
AND-reduction along the first axis; this gives us a mask of words that contain all vowels
+/
sum; count of words containing all vowels (we need to discount their "self-pairs")
(
…)-
subtract that from the following:
(⍉i)∧.∨i
the Boolean matrix where the OR of corresponding masks is all-true.
,
ravel (flatten)
+/
sum; this gives us the count of ordered pairs
0.5×
halve; this gives us the count of unordered pairs
The second solution is O(n)
Breaks even with the above O(n2) solution at about 150 words of 10 evenly distributed characters. It requires 0-based indexing, and a pre-computed 32-by-32 Boolean vowel signature pairing table:
{
a←0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
a[2⊥∨/'aeiou'∘.=⍵]+←1
(0.5×lׯ1+l←a[31])++/,p×a∘.×a
}
Processes* the large dataset in 0.09 ms. TIO's timing is too inconsistent to make any conclusions, but it is likely that it takes about twice the time here too.
* 64-bit Dyalog APL 17.0 on 2.6 Ghz i7-4720HQ
6Welcome to PPCG! I think this is a promising first challenge! For the example input, any solution will be limited by the IO speed. Do you have a larger test set? Are all input words random English dictionary words, or do they need to meet certain criteria? For what input are we measuring fastest-code? You could have a specific list of N words, or you could take the average when selecting N random words a few times. On what machine are we measuring? Can we use multiple cores to speed up calculations? – maxb – 2019-03-04T08:32:18.020
@maxb Inputs don't necessarily have to be of any format. They can be words or even random, meaningless bunches of characters. – Viswalahiri – 2019-03-04T08:40:58.927
3Then that needs to be specified. A solution where <1% of all pairs contain all vowels can look very different from a solution where 50% of all pairs are positives. We will try to optimize for the challenge. To refine what you have, look at some previous fastest-code challenges and what information they contain. As a small example, if all input strings are 1000 random characters, almost every input contains all vowels, so the algorithm to find the number of collisions would be different compared to having English words as input. – maxb – 2019-03-04T08:51:49.860
How long will the words be? – Adám – 2019-03-04T08:59:06.277
Will there ever be words that contain all five vowels? E.g.
education
– Adám – 2019-03-04T09:10:16.250@ Adám It doesn't have to be a word. The inputs can be just meaningless strings like absdfterc or any other combination. – Viswalahiri – 2019-03-04T09:16:24.870
1I'd recommend having a large test case to test against, as well as specifying the specs of the computer the code will be running on. – Jo King – 2019-03-04T09:29:15.290
4I've updated the question to have a dataset of 10000 10 lettered words. – Viswalahiri – 2019-03-04T10:06:42.480
1@ViswalahiriHejeebu Thank you for the large dataset, but what is the answer for it? – Adám – 2019-03-04T10:29:03.943
1I'm sorry I didn't mention. The answer is
1968503
. – Viswalahiri – 2019-03-04T10:36:38.5801What is the maximum length for a string (if any)? Is
'aeiou', 'aeiou'
a valid pair? – None – 2019-03-04T10:36:55.453Also, CPU specs very much needed. – None – 2019-03-04T10:38:19.840
The maximum length for each string is a 1000 characters, and
'aeiou', 'aeiou'
can be considered as a valid pair. – Viswalahiri – 2019-03-04T10:59:54.973