20
\$\begingroup\$

Given a lower case string. Ex:

s = 'abcdefghijklmnopqrstuvwxyz'

The goal is to make every other vowel uppercase.

Desired output here:

abcdEfghijklmnOpqrstuvwxyz

As you can see, from aeiou, \$`e`\$ and \$`o`\$ get uppercased.

For aeiou, the desired output is:

aEiOu

There are only lowercase characters in the strings in all cases.

This is , so shortest code in bytes wins.

P.S. The vowels are aeiou

\$\endgroup\$
11
  • 1
    \$\begingroup\$ I take it vowels are aeiou and not y? \$\endgroup\$
    – pxeger
    Commented Jan 2, 2022 at 7:20
  • 1
    \$\begingroup\$ Very closely related: codegolf.stackexchange.com/q/122783/9365 \$\endgroup\$ Commented Jan 2, 2022 at 7:26
  • 3
    \$\begingroup\$ Maybe add a test case without vowels, with only one vowel, and an empty test case too? \$\endgroup\$
    – Adám
    Commented Jan 2, 2022 at 8:32
  • 1
    \$\begingroup\$ @AmirrezaRiahi because the challenge says to make every other vowel uppercase, meaning to make every odd one uppercase ;) \$\endgroup\$
    – user110034
    Commented Jan 2, 2022 at 21:44
  • 5
    \$\begingroup\$ @richardec it's not definitely a vowel. It's mostly used as such in English. You can't replace it with an i. The examples you give would give it a different pronunciation. The International phonetic alphabet explicitly makes a distinction between the two sounds. /j/ as in yes and /i/ as in feet. The former is a consonant while the latter is a vowel \$\endgroup\$
    – PC Luddite
    Commented Jan 3, 2022 at 13:52

29 Answers 29

14
\$\begingroup\$

Perl 5, 23 bytes

s/[aeiou]/$&^$"x$|--/ge

Try it online!

Explanation

s///ubstitutes each of the lowercase vowels with itself XORed with either 1 or 0 spaces ($" defaults to space) based on $|-- which will alternate each time it's decremented.

\$\endgroup\$
12
\$\begingroup\$

C (gcc), 61 bytes

A full program, where input is taken from STDIN.

x;main(c){for(;read(0,&c,1);)putchar('Xz'%c?c:c^x++%2*32);}

Try it online!

Checking for vowels

Vowels are aeiou, which have the corresponding ASCII codes 97,101,105,111,117. The LCM of these numbers is 1484392455, which has the property of being evenly divisible by only the letters aeiou. Therefore, we can say that c is a vowel if 1484392455%c equals 0. We can compress this number by the use of multi-character constants, giving 'Xz\x08\x07'.

C (clang), 48 bytes

As offered by @AZTECCO, a function which takes a wide string as input, and modifies the string in-place.

x;f(*s){for(x=0;*s;)*s++^='Xz'%*s?0:x++%2*32;}

Try it online!

\$\endgroup\$
12
  • 2
    \$\begingroup\$ Note that this is the only answer that doesn't use the set 'aeiou'. \$\endgroup\$
    – AZTECCO
    Commented Jan 2, 2022 at 11:31
  • 2
    \$\begingroup\$ @AZTECCO Maybe this what you're looking for? (It's on the C++ tips page, but not the C one) \$\endgroup\$ Commented Jan 2, 2022 at 23:26
  • 2
    \$\begingroup\$ In machine code, we'd normally use a bitmap for a lookup table instead of division (as in Vowels up, consonants down), so that's another way to avoid listing the vowels, @AZTECCO. But this way takes fewer characters in C source than (0x8208222>>c)&1 (and that's assuming that constant>>c works as constant >> (c&31), which will be the case on x86 for runtime-variable shift counts). In x86 machine code, there's bt for testing a position in a bitmap in another register so the immediate bitmap trick is compact there. \$\endgroup\$ Commented Jan 3, 2022 at 0:43
  • 1
    \$\begingroup\$ @PeterCordes I was avoiding it because getchar() returns -1 on EOF, thus never terminating the loop properly. It would be great if it returned 0, but it does not appear to be the case on TIO. \$\endgroup\$ Commented Jan 3, 2022 at 0:43
  • 3
    \$\begingroup\$ @AZTECCO: Cheers. :P Have a look at stackoverflow.com/tags/x86/info for x86 asm (and performance) in general, and Tips for golfing in x86/x64 machine code for code-size optimization. I find golf in asm more fun than most languages, since optimizing for code-size is a real thing that's actually useful sometimes. (For speed when all else is equal, or for bootloaders and other space-constrained things, and there's even a "demo scene" of tiny executables that do cool graphics and sound, often DOS .com) \$\endgroup\$ Commented Jan 5, 2022 at 11:17
8
\$\begingroup\$

Python, 73 71 ··· 58 bytes

lambda s,c=0:bytes(a^c|(c:=c^34087456>>a-97&32)for a in s)

Attempt This Online!

Inputs and outputs as a byte string.

Explanation (I use a $ sigil on variables to distinguish them from letters):

  • Consider the lookup table for "letter $a is a vowel": this is the binary array 10001000100000100000100000 (the 1s are at the alphabet positions of aeiou)
  • If we store this as an integer (converting the binary array into a decimal number 35784736), we can lookup into it using 35784736 >> 97 - alphabet_index($a) & 1
  • If $a is actually the ASCII code of the character, we can get its alphabet index using $a - 97 (since 'a' == 97)
  • By taking input and output as bytes in Python, we can get this ASCII code basically for free
  • We can reverse the lookup table to make it shorter by changing $a - 97 to 97 - $a, because by reversing it the trailing zeroes (for vwxyz) become leading zeroes and make the number smaller
  • The reverse lookup table is 00000100000100000100010001 = 100000100000100010001, or 1065233 in decimal, giving us 1065233 >> $a - 97 & 1
  • We can toggle the flag variable $c if $a is a vowel, using $c := $c ^ (1065233 >> $a - 97 & 1)
  • We also want to uppercase $a sometimes. Observe that the uppercase ASCII letters differ from the lowercase letters by exactly 32, so we can toggle the case of $a using $a ^ 32
  • The case toggling should happen if both:
    • $c is on (since we initialise it to 0, and every vowel starting with the second should be capitalised)
    • $a is a vowel
  • This is equivalent to $a ^ 32 * ($c & (1065233 >> $a - 97 & 1))
  • If we store "on" as 32 rather than just 1, and we adjust the lookup table to return 32/0 rather than 1/0, we'll save bytes.
  • We can do this by using 1065233 * 32 = 34087456 as the magic number and &-ing with 32 instead of 1. The resulting expression is 34087456 >> ($a - 97) & 32
  • We want to avoid using 34087456 >> ($a - 97) & 32 in more than one place, because it's a long expression
  • Since we're modifying $c with a := expression, we can do a computation on its value before and after modification to extract the correct value. Let $c be the value before modification and $c' be the new value
  • $c' is different to $c if and only if $a is a vowel, so we want to capitalise if $c is on and $c' != $c, i.e. $c is on and $c' is off
  • Recall that lowercase letters have the 32s bit set, and to uppercase a letter we need to unset it. This means $a has the 32s bit set initially
  • By xoring $a and $c, when $c is on, we remove the 32s bit, uppercasing the letter
  • But we only want to do this when $a is a vowel, so we can re-set the 32s bit when it isn't. Thus by adding | $c', the 32s bit is added again when $c' is 32. This is the case if $c was 32 and $a' was not a vowel, so the bit is only removed when $a is a vowel and $c is 32
\$\endgroup\$
1
  • \$\begingroup\$ Cool, those fancy lambdas \$\endgroup\$ Commented Jan 2, 2022 at 7:24
7
\$\begingroup\$

Retina, 17 bytes

1,2,T`l`L`[aeiou]

Try it online! Link includes test cases. Explanation:

[aeiou]

Match lower case vowels.

1,2,

Only process every other vowel.

T`l`L`

Upper case them.

Although the transliterate command has a shortcut code for vowels, they aren't of any help here so I haven't used them.

\$\endgroup\$
7
\$\begingroup\$

R, 57 bytes

function(s,t=s%in%utf8ToInt("aeiou"))s-t*32*!cumsum(t)%%2

Try it online!

Input is vector of character codes (for comparison to pajonk's answer). Would be 77 bytes with input as string (for comparison to Maël's answer).


Edit: this approach would be only 48 bytes by porting dingledooper's great modulo trick...

\$\endgroup\$
2
  • \$\begingroup\$ Wow, well done! I did not think of using cumsum. Just wondering, do the general rules of code golf allows for the footer to be intToUtf8(f(utf8ToInt(s)))? \$\endgroup\$
    – Maël
    Commented Jan 2, 2022 at 19:51
  • 2
    \$\begingroup\$ @Maël - Somewhere in codegolf.meta.stackexchange.com there's a generally-accepted post that input/output as lists of character codes is an Ok alternative to input/output as string. Sometimes this can be helpful, although obviously an approach that is competitive with both IO methods is most satisfying... \$\endgroup\$ Commented Jan 2, 2022 at 20:16
6
\$\begingroup\$

Jelly, 13 bytes

e€ØẹTḊm2
Œuç¦

Try It Online!

e€ØẹTḊm2  Helper Link; get every other vowel
e€        For each element, is it in
  Øẹ      the list of vowels ("aeiou")?
    T     Get said indices
     Ḋm2  Pop off the first one and take every other one
Œuç¦      Main Link
   ¦      Apply
Œu        to-uppercase
  ç       to every other vowel
\$\endgroup\$
3
  • \$\begingroup\$ So is Ø the character for in? \$\endgroup\$ Commented Jan 2, 2022 at 7:26
  • \$\begingroup\$ @U12-Forward no, Øẹ is just the string "aeiou". The "contains" is e \$\endgroup\$
    – pxeger
    Commented Jan 2, 2022 at 7:28
  • \$\begingroup\$ @pxeger Ah, got it \$\endgroup\$ Commented Jan 2, 2022 at 7:28
6
\$\begingroup\$

Vyxal, 9 bytes

ATy$_⁽⇧¨M

Try it Online!

The power of triads!

Explained

ATy$_⁽⇧¨M
AT       # indices of vowels
  y      # uninterleave into two lists - this pushes a list of every second vowel and every first vowel
   $_    # remove the list of every first vowel
     ⁽⇧¨M # and apply upper-case (a function pushed by ⁽⇧) to those indices (¨M)
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Wow!! Seems to be the language similar to your username that's the shortest. \$\endgroup\$ Commented Jan 2, 2022 at 7:54
  • 1
    \$\begingroup\$ @U12-Forward Haha it pays to be uncreative with naming! \$\endgroup\$
    – lyxal
    Commented Jan 2, 2022 at 7:59
  • \$\begingroup\$ Haha, vlyxal lvyxal \$\endgroup\$ Commented Jan 2, 2022 at 7:59
6
\$\begingroup\$

R, 94 bytes

-26 bytes thanks to Giuseppe. -2 bytes thanks to Robin Ryder

function(s){s=el(strsplit(s,""))
s[i]=toupper(s[i<-grep("[aeiou]",s)[!1:0]])
Reduce(paste0,s)}

See pajonk's and Dominic van Essen's answers for a clever use of intToUtf8 and utf8ToInt.

Try it online!

\$\endgroup\$
7
  • 1
    \$\begingroup\$ 96 bytes \$\endgroup\$
    – Giuseppe
    Commented Jan 2, 2022 at 13:34
  • \$\begingroup\$ Does not work as is, but works with "[aeiou]", thanks! \$\endgroup\$
    – Maël
    Commented Jan 2, 2022 at 13:47
  • \$\begingroup\$ The !1:0 trick is really nice! \$\endgroup\$
    – Maël
    Commented Jan 2, 2022 at 13:56
  • \$\begingroup\$ 94 bytes \$\endgroup\$ Commented Jan 2, 2022 at 17:53
  • 2
    \$\begingroup\$ Or 84 bytes using intToUtf8/utf8ToInt... \$\endgroup\$ Commented Jan 2, 2022 at 18:33
6
+50
\$\begingroup\$

x86 / x86-64 machine code, 22 bytes

Takes pointer (RSI), length (RCX) in registers, modifies the string in-place. Callable from C with the x86-64 SysV calling convention as void vowel_alt_caseflip(int dummy, char *RSI, int dummy, size_t RCX). Same machine code works in 32-bit mode, although none of the standard 32-bit C calling conventions match.

NASM listing, with address, machine-code bytes, and source the machine-code answer was generated from.

     1                         ;;; char *str /* RSI */,  size_t len /* RCX */
     2                         vowel_alt_caseflip:
     3 00000000 BF22822000         mov edi, 0x0208222      ; ASCII vowel bitmap, 1-indexed like ASCII codes are with 'a' = 0x61 not 0x60
     4 00000005 31D2               xor edx, edx            ; first vowel is not flipped
     5                         .loop:
     6 00000007 AC                 lodsb                   ; al = *str++
     7 00000008 0FA3C7             bt  edi, eax            ; if (bitmap & (1<<(al&31)))
     8 0000000B 7306               jnc .non_vowel
     9 0000000D 3056FF             xor [rsi-1], dl         ; caseflip or not the current character
    10 00000010 80F220             xor dl, 0x20            ; toggle state for the next
    11                         .non_vowel:
    12 00000013 E2F2               loop  .loop
    13 00000015 C3                 ret

; next address is 0x16, size is 0x16 = 22 bytes

Since the input string is guaranteed to be all lowercase alphabetic, I just used XOR instead of AND with ~0 / ~0x20 to flip instead of clear the ASCII lower-case bit. It would work out to the same size with mov dl, 0xFF / and [rsi-1], dl.

Try it online! with a Linux _start caller that passes it the alphabet twice and makes write system calls before/after, so we can see that it correctly treats u as a vowel.

For more about the immediate bitmap strategy, and variations like using it branchlessly, see SO and two of my previous x86 answers:


Alternate version, same size

I had hoped to be able to use xor al, 0x20 to save a byte vs. DL, but we need AL for efficient string-reading via lodsb. (We need a char from the string in a register to use as a source for bt.) We could start with mov there and use stosb to store, but that would have to be separate from a reg-reg XOR or AND, and still doesn't free up AL.

We could use scasb as a 1-byte inc rdi. Using mov dl, [rdi] to start, and saving the -1 in the memory-dest addressing mode, and another byte from xor al, 0x20 short-form, that's break-even for size and worse for efficiency (useless scasb reload). Or similar efficiency in 32-bit mode since we could use inc edi there.

;;; char *str /* RDI */,  size_t len /* RCX */
vowel_alt_caseflip_scasb:
    mov esi, 0x0208222      ; ASCII vowel bitmap, 1-indexed like ASCII codes are with 'a' = 0x61 not 0x60
    xor eax, eax            ; first vowel is not flipped
.loop:
    mov dl, [rdi]
    bt  esi, edx            ; if (bitmap & (1<<(c&31)))
    jnc .non_vowel
    xor [rdi], al           ; caseflip or not the current character
    xor al, 0x20            ; toggle state for the next
.non_vowel:
    scasb                   ; inc rdi   in one byte even on x86-64
    loop  .loop
    ret
\$\endgroup\$
5
\$\begingroup\$

Dyalog APL, 23 bytes

1∘⎕C@(=\≠⍨)@(∊∘'aeiou')

1∘⎕C uppercase…

@() at…

  =\ XNOR scan (i.e. every other) of the
  ≠⍨ XOR selfie (i.e. all 0s)

@() at…

   member
   of
  'aeiou' vowels

Try APL online!

\$\endgroup\$
5
\$\begingroup\$

R, 65 bytes

function(s){s[i]=s[i<-which(s%in%utf8ToInt("aeiou"))[!1:0]]-32;s}

Try it online!

Takes input and outputs as vectors of char codes.

Some parts borrowed from @Maël's R answer.

\$\endgroup\$
2
  • \$\begingroup\$ See Maël's Q to me. Do you have the link to the meta post showing that IO as character codes is Ok? \$\endgroup\$ Commented Jan 2, 2022 at 20:17
  • 1
    \$\begingroup\$ @DominicvanEssen, the last point here covers this, I think. \$\endgroup\$
    – pajonk
    Commented Jan 2, 2022 at 21:02
5
\$\begingroup\$

BQN, 19 bytesSBCS

⊢-32×·≠`⊸<∊⟜"aeiou"

Run online!

Textbook use for under, but character arithmetic is much, much shorter. -10 from Marshall, then -3 from Marshall.

Explanation

⊢-32×·≠`⊸<∊⟜"aeiou"
          ∊⟜"aeiou" bitmask of vowels
      ≠`            inequality scan(XOR scan)
        ⊸<          lesser than original bitmask?
  32×·              32 × that
⊢-                  subtract from the input
\$\endgroup\$
3
  • \$\begingroup\$ Mind adding an explanation? I'm curious if the approach can be adapted for J... \$\endgroup\$
    – Jonah
    Commented Jan 3, 2022 at 0:21
  • 1
    \$\begingroup\$ added one. if J has similar character arithmetic it might work. \$\endgroup\$
    – Razetime
    Commented Jan 3, 2022 at 1:48
  • \$\begingroup\$ Sadly it doesn't. Thanks for the explanation though. \$\endgroup\$
    – Jonah
    Commented Jan 3, 2022 at 1:49
5
\$\begingroup\$

Javascript, 57 5654 bytes

s=>s.replace(/[aeiou]/g,c=>(s=!s)?c.toUpperCase():c)

-1 Thanks to Patrick Stephansen.
-2 Thanks to tsh. -2 Thanks to l4m2.

Usage:

console.log((s=>s.replace(/[aeiou]/g,c=>(s=!s)?c.toUpperCase():c)))("string goes here"))

Try it online

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Save one more byte by using a boolean for t: tio.run/##BcExDsIwDADAr5ROtlTSHSll4A1MiMEyVgiK4sg2fD/… \$\endgroup\$ Commented Jan 3, 2022 at 14:28
  • 1
    \$\begingroup\$ You can initial t with any other value available in your code: s=>s.replace(t=/[aeiou]/g,c=>(t=!t)?c.toUpperCase():c) \$\endgroup\$
    – tsh
    Commented Jan 4, 2022 at 3:03
  • 1
    \$\begingroup\$ A more conventional TIO link would be this (so that the correct size is displayed). \$\endgroup\$
    – Arnauld
    Commented Jan 5, 2022 at 7:14
  • 1
    \$\begingroup\$ 52 using s as your t \$\endgroup\$
    – l4m2
    Commented Feb 7, 2022 at 4:24
5
\$\begingroup\$

APOL, 35 bytes

j(ƒ(i ¿(&(c(Ⓔ ↓(∋)) ≐(∈)) ∋ ↑(∋))))

Explanation

j(  Join a list to a string
  ƒ(  Listbuilder for
    i  Input
    ¿(  Returning if (called for each item in the input)
      &(  And (condition)
        c(  String contains
          Ⓔ  The constant string "aeiou"
          ↓(  To lowercase
            ∋  Current character
          )
        )
        ≐(  Is even
          ∈  For loop counter
        )
      )
      ∋  For loop item (executed if true)
      ↑(  To uppercase
        ∋  For loop item
      )
    )
  )
)
\$\endgroup\$
4
\$\begingroup\$

Jelly, 14 bytes

e€Øcn\<$a32^OỌ

Try it online!

e€Øc            For each input character: is it in Øc (vowels)?
                This gets a mask with 1s where vowels are, e.g.
                  “b x d e f h i z k o m u p”
                   0 0 0 1 0 0 1 0 0 1 0 1 0

    n\<$        scanl(≠, mask) < mask: This selects every other 1.
                  scanl(≠):  0 0 0 1 1 1 0 0 0 1 1 0 0
                  original:  0 0 0 1 0 0 1 0 0 1 0 1 0
                         <:  0 0 0 0 0 0 1 0 0 0 0 1 0
                
        a32     Replace all 1s by 32.
           ^O   XOR by ord(input string).
             Ọ  chr()
\$\endgroup\$
4
\$\begingroup\$

Ruby, 41 bytes

Uses the -p flag.

i=1
gsub(/[aeiou]/){[$&,$&.upcase][i^=1]}

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ -1 \$\endgroup\$ Commented Jan 5, 2022 at 13:53
  • \$\begingroup\$ oh, thanks @thejonymyster \$\endgroup\$
    – daniero
    Commented Jan 5, 2022 at 18:17
3
\$\begingroup\$

Retina 0.8.2, 25 bytes

0T-1=`l`L`(.*?[aeiou]){2}

Try it online! Link includes test cases. Explanation:

(.*?[aeiou]){2}

Match the shortest possible substrings containing two vowels.

-1=

Only transliterate the last character of each match. (The 0 indicates that this modifier applies to the characters of the match rather than the matches themselves.)

T`l`L`

Upper case them.

\$\endgroup\$
2
  • \$\begingroup\$ Cool, Retina regular version seems shorter like in your other answer. \$\endgroup\$ Commented Jan 2, 2022 at 12:13
  • 1
    \$\begingroup\$ @U12-Forward Yeah, 1.0 has step limits which makes selecting the vowels much easier; it took me some time to work out how to do this in 0.8.2. \$\endgroup\$
    – Neil
    Commented Jan 2, 2022 at 12:17
3
\$\begingroup\$

C (tcc), 174 111 bytes

Saved 63 bytes thanks to manatwork

i,b;f(char*a,int l){for(i=0;i<l;i++)if(a[i]==97||a[i]=='e'||a[i]=='i'||a[i]=='o'||a[i]=='u')if(b++%2)a[i]-=32;}

Try it online!

Unminified

i, b; 
f(char* a, int l) { 
    for (i = 0; i < l; i++)
        if (a[i] == 97 || a[i] == 'e' || a[i] == 'i' || a[i] == 'o' || a[i] == 'u')
            if (b++ % 2)
                a[i] -= 32; 
}
\$\endgroup\$
4
  • \$\begingroup\$ 1) No need to count the main() function as part of the solution. 2) You can move the incrementing b++ into the if condition as b++%2. Then no more need for the braces around them either. 3) For characters with code below 100 is shorter to use their code: a[i]==97. 4) Use shorthand assignment with subtraction -= operator. Try it online! \$\endgroup\$
    – manatwork
    Commented Jan 2, 2022 at 17:08
  • \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$
    – rydwolf
    Commented Jan 2, 2022 at 17:51
  • \$\begingroup\$ Hello and welcome to CodeGolf. A few notes: b must be initialized inside your function, you can get rid of i counter and use length-- instead(which ends when it reaches 0) , and you can access *a by deference, you can put condition in a ternary operator to select if or not upcase a letter Try it online! \$\endgroup\$
    – AZTECCO
    Commented Jan 3, 2022 at 11:38
  • \$\begingroup\$ Building on @AZTECCO 68 bytes \$\endgroup\$
    – ceilingcat
    Commented Jan 3, 2022 at 16:12
3
\$\begingroup\$

Japt v2.0a0, 10 bytes

r\vÈpu gT°

Try it

\$\endgroup\$
3
\$\begingroup\$

J, 33 31 bytes

(>~:/\)@e.&'aeiou'`(,:toupper)}

Try it online!

-2 thanks to Lynn

Kind of shockingly long, but best I could find so far...

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Porting a trick from my Jelly answer, you can replace (*1-~:/\) with (>~:/\). \$\endgroup\$
    – lynn
    Commented Jan 3, 2022 at 14:02
3
\$\begingroup\$

Python 2, 86 bytes

-26 thanks to ElPedro.

-2 thanks to Daniel.

c,S=0,''
for i in input():
 if i in'aeiou':S+=(i,i.upper())[c];c^=1
 else:S+=i
print S

Try it online

\$\endgroup\$
10
  • 2
    \$\begingroup\$ You should return, not print. \$\endgroup\$
    – Fmbalbuena
    Commented Jan 2, 2022 at 15:52
  • 2
    \$\begingroup\$ @Fmbalbuena Printing from a function is allowed by default and the challenge does not override that rule \$\endgroup\$
    – ovs
    Commented Jan 3, 2022 at 12:04
  • 1
    \$\begingroup\$ You can shorten the if-else using a ternary: S+=i.upper() if c%2 else i \$\endgroup\$
    – Luatic
    Commented Jan 3, 2022 at 12:22
  • \$\begingroup\$ You can shorten it even further using list slicing: S+=(i,i.upper())[c%2] \$\endgroup\$
    – ElPedro
    Commented Jan 4, 2022 at 11:43
  • 1
    \$\begingroup\$ A couple more golfs to get it down to 88 bytes Try it online! \$\endgroup\$
    – ElPedro
    Commented Jan 4, 2022 at 11:49
3
\$\begingroup\$

05AB1E, 11 bytes

žMÃDεNÉiu]‡

Try it online.

Or alternatively the εNÉiu] could be 2ι`u.ι.

Try it online.

Explanation:

žM         # Push the constant "aeiou"
  Ã        # Only keep those letters from the (implicit) input
   D       # Duplicate it
    ε      # Map the vowels in the copy to:
     NÉi   #  If the 0-based index is odd:
        u  #   Uppercase the vowel
    ]      # Close the if-statement and map
     ‡     # Transliterate the lowercase vowels to the alternating cased vowels
           # in the (implicit) input
           # (after which the result is output implicitly)

    2ι     # Uninterleave into two parts
      `    # Pop and push both parts separated to the stack
       u   # Uppercase the second part
        .ι # And interleave the two parts back again (to a list of characters)
\$\endgroup\$
3
\$\begingroup\$

Uiua, 17 bytes

-×32×\≠.∊,"aeiou"

Try it!

Port of Razetime's BQN answer.

-×32×\≠.∊,"aeiou"
        ∊,"aeiou"  # mask of where vowels are in input
       .           # duplicate
     \≠            # inequality scan
    ×              # multiply
 ×32               # multiply by 32
-                  # subtract (capitalize)
\$\endgroup\$
2
\$\begingroup\$

Charcoal, 21 bytes

⭆S⎇№aeiouι§⁺↥ιιL⊞Oυιι

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

 S                      Input string
⭆                       Map over characters and join
   №                    Count of
         ι              Current character
    aeiou               In literal string `aeiou`
  ⎇                     If exists then
             ι          Current character
            ↥           Uppercase
           ⁺            Plus
              ι         Current character
          §             Indexed by
                   ι    Current character
                ⊞O      Pushed to
                  υ     Predefined empty list
               L        Length after push
                    ι   Otherwise current character
                        Implicitly print
\$\endgroup\$
2
\$\begingroup\$

APL+WIN, 39 bytes

Prompts for string

⎕av[(⎕av⍳s)-32×1=i+i×≠\i←(s←⎕)∊'aeiou']

Index offset from lower to upper case changed in TIO from -32 to +48 to account for differences between APL+WIN and Dyalog atomic vectors.

Try it online!Thanks to Dyalog Classic

\$\endgroup\$
2
\$\begingroup\$

Lua, 81 bytes

print(((...):gsub("[aeiou]",function(x)u=not u;return u and x or(x):upper()end)))

Try it online!

Expects the input as first argument, prints output. Is one character shorter if return instead of print is used.

\$\endgroup\$
2
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 148 123 bytes

	S =INPUT
N	S ARB . L ANY('aeiou') . C REM . S	:F(O)
	X =1 - X
	C =CHAR(ORD(C) - 32) EQ(X)
	O =O L C	:(N)
O	OUTPUT =O S
END

Try it online!

Explanation:

	S =INPUT			;* Read input
N	S ARB . L ANY('aeiou') . C REM . S	:F(O)
					;* Match in S:
					;* ARBitrary string (store as L), ANY single vowel (store as C)
					;* and the REMainder of the string (store as S).
					;* If there is no match, goto O.
	X =1 - X			;* Set X (initially treated as 0) to 1-X.
	C =CHAR(ORD(C) - 32) EQ(X)	;* if X == 0, set C to uppercase, otherwise do nothing.
	O =O L C	:(N)		;* append to O L and C, then goto N.
O	OUTPUT =O S			;* Output updated string
END
\$\endgroup\$
2
\$\begingroup\$

Headascii, 142 bytes

----[]]]][]][++++^^^^D^^^^^+^{{D^(U):++++(R):++++(R):++++++(R):++++++(R):R()+E:P};RP{D^(U):++++(R):++++(R):++++++(R):++++++(R):R()+E:P};R]P}.!

Try it here! Code will have to be copied, and executed like this:

erun("----[]]]][]][++++^^^^D^^^^^+^{{D^(U):++++(R):++++(R):++++++(R):++++++(R):R()+E:P};RP{D^(U):++++(R):++++(R):++++++(R):++++++(R):R()+E:P};R]P}.!","your input")

This one was fun, not sure if there's any room for serious golfing without a different approach. Maybe something with an oscillator to decide whether to uppercase a given vowel? But the 3 main storage registers are used up for comparison, storing -32 (uppercase constant), and storing 97 (ascii a, first vowel). So I'm not sure where the constant would be held. I'll take another whack at it sometime though.

----[]]]][]][++++^^^^D^^^^^+^ Constants -32 and 97
----                          -4
    []]]]                     *4
         []][                 *2, and store
             ++++             4
                 ^^^^         *4
                     D^^^^^+^ *6+1, already stored

{{...};RP{...};R]P}. The rest of block 0
{                 }  Loop
 {   }               Loop until a vowel is found
      ;RP            Concatenate it to the string register
         {   }       Loop until a vowel is found
              ;R]P   Subtract 32 (uppercase) and concatenate to string register
                   . Block separator

{D^(U):++++(R):++++(R):++++++(R):++++++(R):R()+E:P} First loop
{                                                 } Loop
 D^(U)                                              If byte is "a",
       ++++(R)                                      "e"
               ++++(R)                              "i"
                       ++++++(R)                    "o"
                                 ++++++(R)          or "u",
      :       :       :         :         :           Exit loop.
                                                    Else,
                                           R()        If byte is null (i.e. string ended)
                                              +E        Go to block 1
                                                :     Else,
                                                 P      Concatenate byte to string register

{D^(U):++++(R):++++(R):++++++(R):++++++(R):R()+E:P} Second Loop is identical to the first
                                                    Avoiding two identical loops would be
                                                    a major golfing opportunity

!  Block 1
!  Print string register, end of execution
\$\endgroup\$
2
\$\begingroup\$

Factor, 65 bytes

[ dup [ "aeiou"in? ] arg-where <odds> over [ 32 - ] change-nths ]

Try it online!

Explanation

Get the indices of the vowels from the input, take the odd-indexed elements of those, then subtract 32 from the input at those indices. change-nths is a mutating word which has the usual ( indices seq -- ) stack effect which is why we need an extra copy on the stack before we call it.

                          ! "abcdefghijklmnopqrstuvwxyz"
dup                       ! "abcdefghijklmnopqrstuvwxyz" "abcdefghijklmnopqrstuvwxyz"
[ "aeiou"in? ] arg-where  ! "abcdefghijklmnopqrstuvwxyz" V{ 0 4 8 14 20 }
<odds>                    ! "abcdefghijklmnopqrstuvwxyz" { 4 14 }
over                      ! "abcdefghijklmnopqrstuvwxyz" { 4 14 } "abcdefghijklmnopqrstuvwxyz"
[ 32 - ] change-nths      ! "abcdEfghijklmnOpqrstuvwxyz"
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.