# Replace all vowels with repeated "aeiou"

Let's say I have this string:

s = "Code Golf! I love Code Golf. It is the best."


I want to replace all the vowels with repeated "aeiou".

Notes:

• Uppercase vowels should be replaced by an uppercase letter, and lowercase vowels should be replaced by a lowercase letter.

• Consonants (all alphabet characters except for "aeiou") and non alphabetical characters should be kept the same.

Desired output:

Cade Gilf! O luva Cedi Golf. Ut as the bist.


As you can see, the vowels are replaced in repetitive order of "aeiou".

Another example:

s = "This is a test! This is example number two."


Output:

Thas es i tost! Thus as eximplo numbar twe.


This is , so shortest code in bytes wins.

• Cade Gilf! O luva Cedi Golf. Ut as the bist. -- you've captured the New Zealand accent perfectly. (I am a Kiwi fyi) Dec 20, 2022 at 13:45
• @roblogic Lol! Maybe they do this on purposely :) Dec 20, 2022 at 13:58

# C (clang), 65 bytes

i;f(*s){for(i=0;*s++^=2130466>>*s&*s>64?i*5^5%++i^*s&30:0;i%=5);}


Try it online!

## How?

### Detecting vowels

We determine whether the current character at *s is a vowel with:

2130466 >> *s & *s > 64


The value $$\2130466\$$ is a bitmask describing the positions of vowels:

000001000001000001000100010
^     ^     ^   ^   ^
zyxwvutsrqponmlkjihgfedcba


The shift amount is interpreted modulo 32 (to my knowledge, this is true for at least Intel and ARM processors). This means that we just have to make sure that the character is a letter (with *s > 64) and can use the same expression for lower and upper case.

### Turning them into different vowels

An interesting thing about vowels is that all their ASCII codes are odd:

A |  65 | 1000001        a |  97 | 1100001
E |  69 | 1000101        e | 101 | 1100101
I |  73 | 1001001        i | 105 | 1101001
O |  79 | 1001111        o | 111 | 1101111
U |  85 | 1010101        u | 117 | 1110101
||    |
||    '--> always 1
|'-------> 'case' bit
'--------> always 1


To turn a vowel of a given case into another vowel with the same case, only bits #1 to #4 (0-indexed) need to be modified. This can be represented with the bitmask $$\00011110_2=30_{10}\$$.

Hence a possible formula:

new_vowel = old_vowel XOR (x XOR (old_vowel AND 30))


where $$\x\in\{0,4,8,14,20\}\$$ (for A,E,I,O,U respectively).

Given $$\i\in[0\dots4]\$$, we get $$\x_i\$$ with:

$$x_i=(i\times 5)\operatorname{xor}(5 \bmod (i+1))$$

i i * 5 5 mod (i+1) xor
0 0 0 0
1 5 1 4
2 10 2 8
3 15 1 14
4 20 0 20

As C code, this gives:

*s ^= i * 5 ^ 5 % ++i ^ *s & 30


which, conveniently, is incrementing $$\i\$$ at the same time.

### Putting everything together

i;                  // i is a counter for vowel replacement
f(*s) {             // s is the input string
for(              // main loop:
*s++ ^=         //   update the character *s:
2130466 >> *s //     if this looks like a vowel
& *s > 64 ?   //     and really is a letter:
i * 5 ^     //       turn it into a different vowel
5 % ++i ^   //       and increment i afterwards
*s & 30     //
:             //     else:
0;          //       leave it unchanged
//   (NB: we stop when the result is NUL)
i %= 5          //   make sure to keep i in [0..4]
);                // end of loop
}                   //

• I really love to see bit masking solutions, nice one btw! Dec 21, 2022 at 16:23

# R, 9481 79 bytes

Edit: -2 bytes thanks to pajonk

\(i){u=match(i,v<-el(strsplit("aAeEiIoOuU","")),0)
i[!!u]=v[1:5*2-u[!!u]%%2]
i}


Attempt This Online!

Input & output as character vectors.
(Splitting-up an input string and reassembling one for the output costs about +36 bytes, for comparison with any alternative approaches that directly use strings).

Previous 94-byte version (using grep and toupper)

• Not using the scan trick leads to -2 bytes. Dec 21, 2022 at 12:39
• @pajonk - Ah, thanks! I think it saved something in the old version with only a e i o u, but I didn't notice that the extra letters now stopped it making sense any more... Dec 21, 2022 at 12:56

# Excel (ms365), 183, 164 bytes

-19 bytes thanks to @jdt

Formula in B1:

=LET(x,MID(A1,ROW(A:A),1),y,"uaeio",r,SEARCH(x,y),z,SCAN(0,r,LAMBDA(a,b,IF(ISERR(b),a,a+1))),w,MID(y,MOD(z,5)+1,1),CONCAT(IFERROR(IF(r*(CODE(x)<97),UPPER(w),w),x)))

• =LET(x,MID(A1,ROW(A:A),1),y,"uaeio",r,SEARCH(x,y),z,SCAN(0,r,LAMBDA(a,b,a+(-ISERR(b)=0))),w,MID(y,MOD(z,5)+1,1),CONCAT(IFERROR(IF(r*(CODE(x)<97),UPPER(w),w),x)))
– jdt
Dec 23, 2022 at 16:29

# Vyxal, 11 bytes

⟑A[kv¥i$•&›  Try it Online! If I had a nickel for every time I'd answered a vowel-related challenge with an 11 byte Vyxal answer in the last 2 weeks, I'd have 2 nickels, which isn't a lot but it's weird that it's happened twice. Outputs as a list of characters (add the s flag if you want a string object). ## Explained ⟑A[kv¥i$•&›
⟑           # To each character:
A[         #  if it is a vowel:
kv¥i     #    get the (register)th item of the string "aeiou" - wraps around if the register > 5
$• # and give it the same case of the current character &› # increment the register to get the next vowel  • If I had a nickel for every time lyxal used a "if I had a nickel for every time I did something" metaphor I'd have about 3-4 nickels right now Jan 5 at 4:54 # Python, 109 106 104 98 bytes f=lambda s,i=0:s and((c:=s[0])in(v:='uaeioUAEIO')and[v[:5],v[5:]][c<'a'][i:=-~i%5]or c)+f(s[1:],i)  Attempt This Online! • -6 thanks to Steffan # Python, 117 116 112 111 bytes ### (not valid - this is just for fun) lambda s:re.sub('[aeiou]',g,s,0,2) i=0 def g(c):global i;i=-~i%5;return['uaeio','UAEIO'][c[0]<'a'][i] import re  Attempt This Online! • -4 thanks to Steffan • -1 thanks to pxeger Just wanted to try with a Regex-based approach. The function isn't reusable so it's not a valid solution. • i:=-~i%5 doesn't need parens, ord(c)<96 => c<'a' (a could be any char higher than Z) Dec 20, 2022 at 22:10 • @Steffan thanks! Dec 21, 2022 at 9:46 • sub('[aeiouAEIOU]',g,s) can be sub('[aeiou]',g,s,0,2) (0 is the maximum number of replacements to perform (0 meaning unlimited), and 2 is the value of the re.IGNORECASE flag) Dec 21, 2022 at 14:30 • Your second submission is not valid though, because it's not reusable: you'd need to reset i to 0 every time the lambda is called. Dec 21, 2022 at 14:31 • @pxeger thanks. I've updated the answer. Dec 21, 2022 at 14:35 # JavaScript (ES6), 59 bytes s=>s.replace(/[aeiou]/gi,c=>"aAeEiIoOuU"[i++%5*2|c<{}],i=0)  Try it online! • Does /gi not help? – Neil Dec 20, 2022 at 13:57 • @Neil I was just testing the /gi solution. Turns out it's one byte shorter. Dec 20, 2022 at 13:58 • Oh, I hadn't realised you were using the regex source for your vowels... – Neil Dec 20, 2022 at 13:59 # Python, 80 74 bytes • -6 thanks to xnor! V=v='UuAaEeIiOo' for c in input():print(end=c[c in V:]or(v:=v[2:]+V)[c>V])  Attempt This Online! Full program. # Python, 8581 78 bytes • -4 thanks to Steffan! • -3 thanks to xnor! lambda s,v='uUaAeEiIoO':''.join(c[c in v:]or(v:=v[2:]+v[:2])[c<'a']for c in s)  Attempt This Online! • I'm pretty sure you can leave out the f= since it's not recursive Dec 20, 2022 at 17:40 • @TheThonnu Oh right, I forgot about that, thanks! Dec 20, 2022 at 17:52 • ord(c)<96 => c<'a' Dec 20, 2022 at 22:09 • 78 bytes – xnor Dec 21, 2022 at 13:05 • 74 bytes – xnor Dec 21, 2022 at 13:10 # Raku, 44 bytes {$!=0;S:g:ii[<[aeiou]>]=<a e i o u>[$!++%*]}  Try it online! Most of the magic here is in the samecase flag on the substitution, whose short form is ii. It makes the match case-insensitive, and furthermore carries the case information forward into the substituted text. • You can remove $!=0 and use $++ instead of $!++ Dec 20, 2022 at 21:30
• @Steffan Actually I can't, because the $ state variable would keep its value from one function call to the next. – Sean Dec 20, 2022 at 21:53 • No, that's not how $ works. It is scoped to the substitution, not the function. Dec 20, 2022 at 22:04
• @jubilatious1 $! is a special variable that holds the last thrown exception. You can use it for anything you want, though. It's not uncommon to see it used as a helper variable in golfing, since it saves you two bytes over declaring a new variable with my. I would never use it for that purpose in real code, though. – Sean Dec 21, 2022 at 15:55 • @jubilatious1 In Raku, you can pass a function as the subscript to an array. Raku will call the function with the size of the array as its argument, and use whatever the function returns as the actual index into the array. Most often this is used to index from the end of the array, eg. @array[*-1] to get the last element. Here *-1 is just an anonymous function that subtracts one from its argument. In my code here, $!++ % * is another anonymous function that increments $! and returns the remainder of its previous value when divided by the function's argument. – Sean Dec 23, 2022 at 17:10 # Pip, 37 21 bytes - 14 bytes of mostly DLosc, and jezza_99 getting ninja'd - 2 bytes thanks to jezza_99 aR-XV{YVW@UvaNz?yUCy}  Try It Online! I'm bad at golfing in pip lol. aR-XV{YVW@UvaNz?yUCy} aR-XV{ } Replace (case-insensitive) vowels with ... YVW@Uv Set y to the (vth*1) vowel aNz?yUCy Copy case to y  • Hint: instead of running a For loop, this is a good occasion to use regex replacement (-XV, i.e. "vowels, case-insensitive," is the regex you'll want). By using a function as the replacement, you can make the logic for picking the replacement character as complex as needed. Dec 20, 2022 at 20:09 • 24 bytes using @DLosc tip Dec 20, 2022 at 20:40 • @jezza_99 oh nvm yours is 23 too, there's a crlf in the end Dec 20, 2022 at 20:52 • @mathcat haha whoops, yes 23 bytes Dec 20, 2022 at 21:21 • 21 bytes by shifting the increment and checking if a is in the lowercase alphabet z Dec 21, 2022 at 0:37 # Japt v2.0a0, 21 bytes r\v@T°gaeiŒc^H*XèXu  Try it r\v@T°gaeic^H*XèXu :Implicit input of string r :Replace \v :RegEx /[aeiou]/gi @ :Pass each match X through the following function T° : Postfix increment T (initially 0) g : Index into aei : Compressed string "aeiou" c : Map charcodes ^ : Bitwise XOR with H* : 32 multiplied by Xè : Count the occurrences in X of Xu : X uppercased  # Haskell, 93 bytes (%"aAeEiIoOuU") (x:r)%u@(v:t:w)|elem x u=c:r%(w++[v,t])|1>0=x:r%u where c|x>'Z'=v|1>0=t o%_=o  Attempt This Online! Prettified: import Data.Char g vowels@(vowel:vOWEL:rest) (char:chars) | char elem vowels = mappedChar : g rotatedVowels chars | otherwise = char : g vowels chars where rotatedVowels = rest ++ [vowel, vOWEL] mappedChar | isUpper char = vOWEL | otherwise = vowel g _ "" = ""  g "aAeEiIoOuU"  # Python 3.8+, 183 156 127 117 111 bytes -29 bytes thanks to ElPedro -10 bytes thanks to Neil -6 bytes thanks to help from the Discord (mainly by dzaima and me) def x(n):m,j='aeiou',0;return''.join([((m,m.upper())[i<'a'][j%5],j:=j+1)[0]if i.lower()in m else i for i in n])  • A few golfs to help you get it down to 127 Dec 20, 2022 at 15:12 • @ElPedro t+=(m,m.upper())[i<'a'][j%5];j+=1 saves another 10 bytes. – Neil Dec 20, 2022 at 19:44 • @Neil Very nice. Not sure how a missed i<'a'. I've maybe been away from Code Golf for too long :-) Dec 20, 2022 at 20:20 • ElPedro and Neil note that I have now golfed this to 111 bytes by using a list comprehension Jan 3 at 15:51 • This doesn't seem to be syntactically correct - you seem to be missing at least 1 parenthesis, and the brackets/parentheses seem to be unbalanced Jan 3 at 19:15 # Python 3, 130122 120 bytes p=print v='aeiou' n=0 for i in input(): if i.lower()in v:p(end=[v[n],v[n].upper()][i.isupper()]);n=-~n%5 else:p(end=i)  Try it online! -8 bytes thanks to myself -2 bytes thanks to The Thonnu • Beat me by 1 byte! Dec 20, 2022 at 13:15 • @TheThonnu Haha! Dec 20, 2022 at 13:16 • Added a new 120 byte solution... Dec 20, 2022 at 13:17 • @TheThonnu Added a 122 byte! Dec 20, 2022 at 13:19 • You can equal my score by replacing n=(n+1)%5 with n=-~n%5 Dec 20, 2022 at 13:19 # Pyth, 25 bytes sm?}r0dK"uaeio"r@K=hZrId1  Try it online! ### Explanation sm?}r0dK"uaeio"r@K=hZrId1dQ # implicitly add dQ to the end # implicitly assign Q = eval(input()) K"uaeio" # assign K to "uaeio" s # sum of m Q # map lambda d over Q ?}r0dK # ternary, if lowercase(d) in K: r rId1 # map case to d of @K # (looping) index K at =hZ # increment Z, and assign it to the increment d # else: d  # Jelly, 23 bytes ØciⱮðḟ0ØėṁŒs>5$}¡"Ɗż@œp


Try it online!

Jelly isn't great at challenges. Full program, as we take advantage of Jelly's smash printing.

## How it works

ØciⱮðḟ0ØėṁŒs>5$}¡"Ɗż@œp - Take a string S on the left Øc - Yield "AEIOUaeiou" Ɱ - For each character C in S: i - Get the index of C in "AEIOUaeiou", or 0 if not found ð - Begin new dyadic chain, with vowel indices V on the left and S on the right ḟ0 - Remove zeros from V, call that V' Ɗ - Group the previous 3 links into a monad f(V'): Øė - Uppercase vowels; "AEIOU" ṁ - Repeat to the same length as V' " - For each pair (v, i) with v a vowel and i an index in V': ¡ - Repeat:$         -       Iteration count:
}        -         Is i...
>5          -         ...greater than 5?
Œs            -       Action: Swapcase
œp - Partition S at the the indices in V
ż@   - Zip the partition and the vowels, with reversed @rguments


# Factor, 87 86 bytes

[ EBNF[=[ r=([aeiouAEIOU]=>[[96 > 0 -32 ? 0 inc 0 get 1 - 5 mod "aeiou"nth +]]|.)*]=]]


Attempt This Online!

• [ ... ] Define a quotation, or anonymous function, that takes a string as input from the data stack and leaves a string as output on the data stack.
• EBNF[=[ ... ]=] Define an anonymous EBNF parser that automatically runs on an input and produces an output.
• r= Name the topmost EBNF rule. There has to be at least one rule, so here it is.
• (...|.)* Match any number (*) of ... or (|) anything (.). The . matches consonants which will remain the same.
• [aeiouAEIOU] Match any vowel.
• =>[[...]] An EBNF action. The code inside the double brackets will run on each token before being added to the parse tree.
• 96 > 0 -32 ? Is the vowel we matched lowercase? Push 0 on the data stack if so; otherwise, push -32 on the data stack.
• 0 inc Increment the value stored at 0. In Factor, any value (such as 0) can be used as a variable (key) to store a value in an implicit hierarchy of hash tables. If 0 contains f, which all uninitialized variables do by default, inc will cause the value to become 1.
• 0 get Get the value stored at 0.
• 1 - Subtract one. We do this because it's shorter than initializing 0 to 0.
• 5 mod Modulo five.
• "aeiou"nth Get the nth letter in "aeiou".
• + Add this letter to the 0 or -32 from earlier. This is what capitalizes the letter or keeps it lowercase.
• First time I've ever seen EBNF used in a competitive answer. And to think I thought it was only good for lexers and parsers! :p Dec 21, 2022 at 12:38

# Java (JDK), 125131 bytes

s->{String v="aeiouAEIOU",r="";int j=0,p;for(var c:s.toCharArray()){p=v.indexOf(c);r+=p>=0?v.charAt((p>4?5:0)+j++%5):c;}return r;};


Try it online!

(Edited to add some lambda boilerplate.)

• Welcome to Code Golf! I think usually the method/function declaration boilerplate is included in the score Dec 21, 2022 at 19:58
• Thanks. Should it be (1) String f(String s){...} or is (2) (s)->{...}; allowed, with the declaration (e.g. Function<String,String>) of the lambda omitted? Dec 21, 2022 at 20:20
• I've changed it to a lambda but left the lambda declaration implicit as per this Java answer to another challenge. Dec 21, 2022 at 20:38
• 126 bytes Dec 22, 2022 at 16:49

# Retina, 82 54 bytes

i[aeiou]
a$& ,Y0ava. TvV.[AEIOU] 1,2,i[aeiou]  Try it online! Link includes test cases. Explanation: i[aeiou] a$&


Prefix as to all of the vowels, both lower and upper case.

,Y0ava.


Cyclically transliterate only the new as to vowels.

TvV.[AEIOU]


Uppercase the new vowels that precede old uppercase vowels.

1,2,i[aeiou]



Delete alternate vowels i.e. the old vowels.

If the input had all been in (say) lowercase, then it could have been done in 11 bytes:

Yva
Yav


Try it online! Link includes test cases. Explanation: Simply cyclically transliterates all the lowercase vowels to as and back to vowels.

# Charcoal, 28 bytes

≔uaeioθ⭆Ｓ⎇№θ↧ι§⎇№αι↥θθＬ⊞Ｏυιι


Try it online! Link is to verbose version of code. Explanation:

≔uaeioθ


Get the vowels into a string to reduce repetition, but start with u because they need to be 1-indexed.

⭆Ｓ⎇№θ↧ι§⎇№αι↥θθＬ⊞Ｏυιι


Loop over the input characters, replacing letters whose lowercase can be found in the string of vowels with letters cyclically chosen from the string or its uppercase according to the number of matches so far.

printf ${k/[$w]/$w[j%5+(#k<91?1:6)]}}  # 05AB1E, 17 bytes žMIlåÅÏžM¾è¼s.uiu  I/O as a list of characters. Explanation: žM # Push string "aeiou" I # Push the input-list l # Convert each letter to lowercase å # Check for each letter if it's in the vowels-string ÅÏ # Apply on the truthy indices of the (implicit) input-list: žM # Push string "aeiou" again ¾è # Get the (modular) 0-based ¾'th vowel ¼ # Then increase ¾ by 1 s # Swap so the current character is at the top .ui # Pop, and if it's uppercase: u # Uppercase the indexed vowel as well # (after which the list of characters is output implicitly as result)  # Ly, 58 bytes "uoiea">ir[s<l'ZLsf:l' *+fsp~[p' *sp:l-s>pl<psprlr00]pp>o]  Try it online! I thought this would be a "minor" variation on another answer I coded earlier this week. I was wrong. :) The code uses one stack to hold a list of vowels. They are rotated each time one of them is used. And it uses a second stack as a "burndown" list of the input characters (codepoints). It copies one input character at a time to the vowel stack, searches for it, and if found substitutes the "next" vowel for the top of the burndown stack. Then it switches back to the burndown stack and prints the top codepoint as a character. The upper/lowercase logic adds a bunch of code to the program and chaos of temporary stack entries... "uoiea">ir - setup... "uoiea" - push vowels onto the stack >ir - switch to a new stack, read STDIN into the stack and reverse [s<l'ZLsf:l' *+fsp~[...if vowel...]pp>o] - process each char [ ] - loop until empty s<l - copy char to vowel stack 'ZL - upper case? s - save result f: - pull char forward, duplicate l - retrieve upper case 1|0 ' *+ - map to lowercase if appropriate f - pull original char forward sp - save it and delete ~ - search for lower case char [...if vowel...] - if it's a vowel, do this block pp - clean up the stack >o - switch stack, print top entry p' *sp:l-s>pl<psprlr00 - code block run if we find a vowel p - delete "if" test var ' * - calculate "should uppercase" delta sp - save and delete from stack : - duplicate current vowel l - load "uppercase" delta - - convert case if called for s> - save vowel to print, switch stacks pl - delete original vowel, load replacement < - switch back to rotating vowel stack p - clean-up stack sprlr - move vowel on top of stack to the bottom 00 - push entries on stack to match non-vowel state  # Jelly, 17 bytes f€ØcØėṁȯ"Œl⁺i$}¡"


Try it online!

Was originally e€ØcÄịØėa@Ʋo⁸O|O&32ƊỌ, but that eventually turned into this with some inspiration from caird's answer.

 €                   For each character of the input,
f Øc                 filter it to AEIOUaeiou, producing a mix of empty and length-1 strings.
Øėṁ              Mold AEIOU to the same shape as that.
ȯ"            Replace empty strings with corresponding characters from the input.
"    For each pair of such corresponding elements:
Œl          lowercase the result
¡     if
⁺  }      the original lowercased (and wrapped in a string)

# Arturo, 79 bytes

\$=>[i:0v:"aAeEiIoOuU"map&'c[(v=v--c)?->c[x:(c>^)?->0->1v\[x+i%10]'i+2]]|join]


Try it