Crunch vowels out of a string
Perl, 48 45 43 bytes
Includes +4 for -Xlpi
(-X can be left out but leaves ugly warnings on STDERR)
Run with the number after the -i
option and the input on STDIN (supports multiple lines too). e.g. perl -Xlpi50 crunch.pl <<< "Duis commodo scelerisque ex, ac consectetur metus rhoncus."
crunch.pl
:
s/.*\K[aeiou]|.*\K |.$// while pos=-$^I
MATL, 20 bytes
t11Y2mEG32=+K#Si:)S)
Try it online!
t % implicitly input string. Duplicate
11Y2 % predefined literal 'aeiou'
m % ismember. Gives true for input characters that are vowels
E % multiply by 2
G % push input string again
32 % ASCII for space
= % gives true for input characters that are spaces
+ % add: gives 2 for vowels, 1 for space, 0 for non-vowels-and-non space
K#S % sort and push only the indices of the sorting. Sorting is stable, so first
% will be non-vowels-and-non space characters in their original order, then
% spaces in their original order, then vowels in their original order
i % input number n of characters that should be kept
: % range [1,2,...,n]
) % index with that: keep first n indices of the sorting
S % sort those indices to restore their original order
) % index into input string to keep only those characters. Implicitly display
JavaScript (ES6), 66 61 bytes
Saved 5 bytes thanks to @Neil
f=(s,n)=>s[n]?f(s.replace(/(.*)[aeiou]|(.*) |.$/,"$1$2"),n):s
I don't think the regex is golfable further. Surprisingly, the shortest I can come up with to remove front-to-back is a byte longer:
f=(s,n)=>s[n]?f(s.replace(/(.*?)[aeiou]|(.*?) |./,"$1$2"),n):s
More interesting attempt (ES7), 134 bytes
(s,n,i=0)=>[for(c of s)[/[aeiou]/.test(c)*2+(c<'!'),i++,c]].sort(([x],[y])=>x-y).slice(0,n).sort(([,x],[,y])=>x-y).map(x=>x[2]).join``
This uses an approach similar to the MATL answer.