| Bytes | Lang | Time | Link |
|---|---|---|---|
| 090 | AWK | 250908T200835Z | xrs |
| nan | Perl 5 | 170824T024921Z | Xcali |
| 090 | APL | 170721T193410Z | marinus |
| 129 | JS ES6 | 170720T204726Z | ABot |
| 238 | Python 3 | 170720T202055Z | hyperneu |
| 417 | Python | 170720T194737Z | Quuxplus |
| 175 | APL Dyalog | 170720T105038Z | Adá |
AWK, 90 bytes
{for($0=toupper($0);i++<NF;x+=$i~/[AEIOU]/){$i~/ /&&x=0
printf($i!~$(i-1)?x?$i$i$i:$i:X)}}
Perl 5, 139 + 1 (-p) = 140 bytes
$_=uc,s/^([^AEIOU]*)//,$s=$1,s/([^AEIOU])\1*/$1x(($q=length$&)>3?$q:3)/ge,s/.*?\K([AEIOU])\1*/$1x(($q=length$&)>3?$q:3)/e,print"$s$_ "for@F
Even handles the "aaaabbbbc" test case in accordance with the example.
APL, 90 bytes
{1↓∊{s←{⍵⊂⍨1,2≠/⍵}⋄x↑⍨¨(3⌈≢¨s⍵)⌊≢¨x←s⍵/⍨(1+2×{⌽<\⌽⍵}∨~∧∨\)⍵∊'AEIOU'}¨w⊂⍨w=⊃w←' ',1(819⌶)⍵}
Explanation:
1(819⌶)⍵: convert to uppercasew⊂⍨w=⊃w←' ',: split on spaces{...}¨: for each word...s←{⍵⊂⍨1,2≠/⍵}:sis a function that splits a string into groups of contiguous matching characters⍵∊'AEIOU': mark the vowels(...): see which characters to triplicate~∧∨\: all consonants past the first vowel,{⌽<\⌽⍵}: the last vowel.2×: multiply the bit vector by two,1+: and add one. Now all selected characters have3and the rest have1.
⍵/⍨: replicate each character in⍵by the given amountx←s: split it up into strings of matching characters, and store this inx.(3⌈≢¨s⍵): the length of each group of matching characters in the input word, with a maximum of 3.⌊≢¨: the minimum of that and the lengths of the groups inx.x↑⍨¨: make each group be that length
1↓∊: flatten the result and drop the first character (the space that was added at the beginning to help with splitting)
JS (ES6), 138 134 129 bytes
s=>s.toUpperCase()[r="replace"](/(\w)\1/g,"$1")[r](/[AEIOU](?=[^AEIOU]*( |$))/g,s=>s+s+s)[r](/\B./g,s=>/[AEIOU]/.test(s)?s:s+s+s)
WAAAYYY TOOO MAAANNNYYY BYYYTTTEEESSS. Contains AEIOU 3 times, but I can't golf those into one.
-4 bytes thanks to HyperNeutrino
Ungolfed
function v(str){
return str.toUpperCase().replace(/(\w)\1/g,"$1").replace(/[AEIOU](?=[^AEIOU]*( |$))/g,s=>s+s+s).replace(/\B./g,s=>[..."AEIOU"].includes(s)?s:s+s+s);
}
I like to write, not read code.
Python 3, 238 bytes
def f(s):
s=s.upper();k=[s[0]];s=''.join(k+[s[i]for i in range(1,len(s))if s[i]!=s[i-1]])
for i in range(1,len(s)):k+=[s[i]]*(3-2*(s[i]in'AEIOU'and i!=max(map(s.rfind,'AEIOU'))))
return''.join(k)
print(' '.join(map(f,input().split())))
Python, 417 bytes
Here's a reference implementation in Python. Not terribly golfed.
import itertools,re
def j(s):return re.match('^[AEIOU]+$',s)
def c(s):return ''.join(sum(([h,h,h]for h in[k for k,g in itertools.groupby(s)]),[]))
def v(s):
while len(s)>=2 and s[-2]==s[-1]:s=s[:-1]
return s+s[-1]+s[-1]
def a(n):
r=''
for w in n.split():
if r:r+=' '
ss=re.split('([AEIOU]+)',w.upper())
for i,s in enumerate(ss):
r+=[v(s),s][any(j(t) for t in ss[i+1:])]if j(s)else[s,c(s)][i>0]
return r
Test with:
while True:
print a(raw_input('> '))
APL (Dyalog), 175 bytes
1↓' +'⎕R' '⊢'[AEIOU][^AEIOU]+ '⎕R{m/⍨1,3×2≠/m←⍵.Match}'([AEIOU])\1*([^AEIOU]*? )' ' [AEIOU]' ' [^ AEIOU]+' '([^AEIOU ])\1*'⎕R'\1\1\1\2' '&' '&' '\1\1\1'⊢'$| |^'⎕R' '⊢1(819⌶)⍞
⍞ prompt for character input
1(819⌶) convert to uppercase (819 ≈ Big)
⊢ pass the result further (serves to separate the strings and the 1)
'$| |^'⎕R' ' Replace:
the end, any space, and the beginning
→ two spaces
⊢ pass the result further (serves to separate two groups of strings)
'([AEIOU])\1*([^AEIOU]*? )' ' [AEIOU]' ' [^ AEIOU]+' '([^AEIOU ])\1*'⎕R'\1\1\1\2' '&' '&' '\1\1\1' Replace:
any number of identical vowels and any number of non-vowels and a space
→ the vowel thrice and the unmodified consonants
a space and a vowel
→ themselves
a space and a consonant cluster
→ themselves
a run of identical consonants
→ three of those vowels
'[AEIOU][^AEIOU]+ '⎕R{…} Replace:
a run of non-vowels and a space
→ the result of the following anonymous function with the namespace ⍵ as argument:
⍵.Match the text that was found
m← assign that to m
2≠/ pair-wise different-from
3× multiply by three
1, prepend one
m/⍨ use that to replicate m
⊢ pass the result further (serves to separate two strings)
' +'⎕R' ' Replace:
one or more spaces
→ with a single space
1↓ drop the initial letter (a space)