34
\$\begingroup\$

Challenge

You will be given a string that can contain lowercase letters, uppercase letters, or spaces. You have to turn the vowels (a, e, i, o, u) in the string to upper case and consonants to lower case. This applies whether or not the letter was originally upper case or lower case. Spaces remain as is. Note that "y" is a consonant.

Examples

Hello World -> hEllO wOrld
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVXWYZ -> AbcdEfghIjklmnOpqrstUvwxyz AbcdEfghIjklmnOpqrstUvxwyz

Info

  • The input string can contain letters A to Z, lowercase or uppercase, and spaces.

Input

The string

Output

The formatted string (Vowels uppercase and consonants lowercase).

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Why on many challenges is "y" counted as a consonant ? \$\endgroup\$
    – CreaZyp154
    Feb 16, 2022 at 13:40
  • \$\begingroup\$ Because it is a consonant. (<pedantic> unless you're using international phonetic alphabet, where it's the front-high-rounded vowel /y/</pedantic>) \$\endgroup\$
    – bigyihsuan
    Feb 16, 2022 at 15:35
  • \$\begingroup\$ @bigyihsuan It's a bit more complicated than that. Wikipedia says: "In the English writing system, it mostly represents a vowel and seldom a consonant." As a child, I was taught that the vowels were "A, E, I, O, U, and sometimes Y," which could lead to viewing Y as "not really a vowel" because it's not always a vowel. Y is also a consonant in some very common words like "yes" and "you." But these are just guesses; I'm not entirely sure why Y is often not considered a vowel in coding challenges. \$\endgroup\$
    – DLosc
    Feb 16, 2022 at 18:44

62 Answers 62

25
\$\begingroup\$

JavaScript (Node.js),  55 ... 46  45 bytes

Saved 1 byte thanks to @KevinCruijssen

s=>Buffer(s).map(c=>c^(c^~68174912>>c)&32)+''

Try it online!

How?

The constant \$68174912\$ is a bitmask describing the positions of the vowels:

00000100000100000100010001000000
     v     v     v   v   v
zyxwvutsrqponmlkjihgfedcba`_^]\[

As per the ECMAScript specification, the following expression:

~68174912 >> c & 32

is equivalent to:

~68174912 >> (c % 32) & 32

and therefore evaluates to \$32\$ for a consonant or \$0\$ for a vowel, no matter the case of \$c\$.

Commented

s =>                   // s = input string
  Buffer(s)            // turn s into a buffer
  .map(c =>            // for each ASCII code c:
    c ^                //   change the case if:
      ( c              //     c is not in lower case
        ^              //     XOR
        ~68174912 >> c //     c is a consonant
      ) & 32           //
  ) + ''               // end of map(); coerce back to a string
\$\endgroup\$
3
  • \$\begingroup\$ Thank you for the answer, it is so beautiful! \$\endgroup\$
    – Chau Giang
    Mar 26, 2021 at 8:05
  • \$\begingroup\$ Damn... I'll definitely try to use bit masks for future submissions... \$\endgroup\$
    – CreaZyp154
    Feb 16, 2022 at 13:37
  • \$\begingroup\$ Worth mention that space is treated as a consonant and don't turn into \0 \$\endgroup\$
    – l4m2
    Feb 16, 2022 at 13:42
17
\$\begingroup\$

C (gcc), 49 bytes

Port of my JS answer.

f(char*s){for(;*s;s++)*s^=(*s^~68174912>>*s)&32;}

Try it online!


C (clang), 48 bytes

A version suggested by @Neil

This is abusing the way clang is dealing with the pointer post-increment.

f(char*s){for(;*s;)*s++^=(*s^~68174912>>*s)&32;}

Try it online!

\$\endgroup\$
6
  • 4
    \$\begingroup\$ Ah, this is a binary lookup table of ASCII characters mod 32. Smart. \$\endgroup\$
    – S.S. Anne
    Mar 22, 2020 at 20:22
  • \$\begingroup\$ @S.S.Anne Yes, exactly. (I've just added an explanation to my JS answer.) \$\endgroup\$
    – Arnauld
    Mar 22, 2020 at 20:34
  • 1
    \$\begingroup\$ GCC is too clever, but if you switch to clang then you can (currently) get away with incrementing the pointer in the assignment statement thus saving a byte. \$\endgroup\$
    – Neil
    Mar 23, 2020 at 11:13
  • 1
    \$\begingroup\$ GCC actually generates these for long strings of comparisons. Of course, they're in machine code, but still. \$\endgroup\$
    – S.S. Anne
    Mar 23, 2020 at 14:04
  • 1
    \$\begingroup\$ @S.S.Anne Yes, you are absolutely right: for n==1|n==5|n==7|n==13, it will test the bitmask 0x20a2 (C to machine code) provided that the code is compiled with at least -O1. \$\endgroup\$
    – Arnauld
    Mar 23, 2020 at 17:37
13
\$\begingroup\$

Perl 5 -p, 20 19 bytes

-1 due to @NahuelFouilleul

$_=lc;y;aeiou;AEIOU

Try it online!

Convert everything to lower case, then change vowels to upper case.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ can save one byte using ; as transliterator delimiter and ommiting the last Try it online! \$\endgroup\$ Mar 23, 2020 at 17:16
  • \$\begingroup\$ Thanks for the reminder \$\endgroup\$
    – Xcali
    Mar 23, 2020 at 18:59
13
\$\begingroup\$

Python 3, 55 bytes

lambda s:[[c,c.upper()][c in"aeiou"]for c in s.lower()]

Try it online!

Input: A string/sequence of characters
Output: a list of characters.

Explanation

The solution converts the string to lower case, then convert all vowels to uppercase.

  • for c in s.lower() converts the string to lower case, then loop through each character in the string.
  • [c,c.upper()][c in "aeiou"] converts any vowel to uppercase, and consonant to lower case.
    c in "aeiou" evaluates to 0 or 1, which is used to index into the list [c,c.upper()].
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Please could you share an explanation of how your lambda Python 3 function works, I'm new to code-golf and my own Python 3 attempt relies on a for loop through list. \$\endgroup\$
    – user90593
    Mar 23, 2020 at 19:40
  • 4
    \$\begingroup\$ @AryanBeezadhur the main trick to working out what this answer does is figuring out which meanings the brackets have. The outer ones are a list comprehension, the first inner bracket is a 2 element list, and the second pair of inner brackets are list indexing (using the coercion from booleans to integers) \$\endgroup\$
    – Potato44
    Mar 24, 2020 at 10:04
  • \$\begingroup\$ @Potato44 +1, thanks! \$\endgroup\$
    – user90593
    Mar 24, 2020 at 10:06
  • \$\begingroup\$ Shouldn't the output be a formatted string? \$\endgroup\$ Mar 26, 2020 at 14:31
10
\$\begingroup\$

Python, 53 bytes

lambda s:[(c*2).title().strip('aeiou')[-1]for c in s]

Try it online!

Outputs a list of characters.

Here is an explanation of how it transforms each character c, with examples c='A' and c='B':

                'A'  'B'
(c*2)           'AA' 'BB'  # Two copies of c in a two-character string
.title()        'Aa' 'Bb'  # Title case: uppercase first letter and the rest lowercase
                           # This disregards the case of c
.strip("aeiou") 'A'  'Bb'  # Remove any leading or trailing lowercase vowels 'aeiou'
                           # For a two-character string, this removes all such letters
[-1]            'A'  'b'   # Take the last letter

55 bytes

lambda s:[(c*2).title()[~(c in'aieouAEIOU')]for c in s]

Try it online!

If we were instead lowercasing vowels and uppercasing consonants, we wouldn't need the ~() and would have 52 bytes.

\$\endgroup\$
1
  • 3
    \$\begingroup\$ Alternative 53, Python 3 only: lambda s:[max({*(c*2).title()}-{*'aeiou'})for c in s] \$\endgroup\$
    – Bubbler
    Mar 25, 2020 at 2:36
7
\$\begingroup\$

CJam, 15 bytes

lel"aeiou"_euer

Try it online!

Explanation

l         e# Read line
el        e# To lowercase
"aeiou"   e# Push this string
_         e# Duplicate
eu        e# To uppercase
er        e# Transliterate. Implicitly display
\$\endgroup\$
0
7
\$\begingroup\$

Java 8, 86 34 bytes

S->S.map(c->c^(c^~68174912>>c)&32)

-52 bytes by porting @Arnauld's JavaScript answer, so make sure to upvote him!!

Original 86 bytes answer:

s->{s=s.toLowerCase();for(var p:"aeiou".toCharArray())s=s.replace(p,p&=~32);return s;}

Try it online.

Explanation:

s->{                               // Method with String as both parameter and return-type
  s=s.toLowerCase();               //  Convert the entire String to lowercase
  for(var p:"aeiou".toCharArray()) //  Loop over the vowels as characters:
    s=s.replace(p,p&=~32);         //   And replace the lowercase vowels to uppercase ones
  return s;}                       //  Then return the modified String as result
\$\endgroup\$
7
\$\begingroup\$

Bash + Core utilities, 25 23 bytes

tr aeiou AEIOU<<<${1,,}

Try it online!

Saved 2 bytes thanks to a suggestion of Nahuel Fouilleul.

Input is passed as an argument, output is on stdout.

\$\endgroup\$
2
  • \$\begingroup\$ saved 2 bytes using lowercase expansion Try it online! \$\endgroup\$ Mar 23, 2020 at 17:23
  • \$\begingroup\$ @NahuelFouilleul Thank you -- did you mean something like this? TIO wasn't working on your link ("The permalink could not be decoded"), but I modified the code to use lowercase expansion as you suggested, and saved two bytes. \$\endgroup\$ Mar 23, 2020 at 18:40
6
\$\begingroup\$

Jelly,  9  7 bytes

Saved 2 using a variation of Luis Mendo's CJam approach

ØCŒHyŒu

A monadic Link accepting a list of characters which yields a list of characters.

Try it online!

How?

ØCŒHyŒu - Link: list of characters, S   e.g. "I am OK!"
ØC      - consonants                         "BCDF...XYZbcdf...xyz"
  ŒH    - split into two                     ["BCDF...XYZ", "bcdf...xyz"]
     Œu - convert (S) to upper-case          "I AM OK!"
    y   - translate                          "I Am Ok!"
\$\endgroup\$
1
  • \$\begingroup\$ This makes much more sense than the other "Jelly" answer. I fiddled with it and got an answer 1 byte longer: ØcṚŒHyŒl by doing the same thing but translating vowels. \$\endgroup\$
    – RGS
    Mar 22, 2020 at 17:40
6
\$\begingroup\$

APL (Dyalog Extended), 14 bytesSBCS

Anonymous tacit prefix function.

⌈@(∊∘'aeiou')⌊

Try it online!

 lowercase

⌈@() uppercase at the following positions:

∊∘'aeiou' members of "aeiou"

\$\endgroup\$
6
\$\begingroup\$

sed, 41 25 24 bytes

Saved 16 bytes thanks to Surculose Sputum!!!
Saved a byte thanks to S.S. Anne!!!

s/./\L&/g
y/aeiou/AEIOU/

Try it online!

\$\endgroup\$
4
  • \$\begingroup\$ 25 bytes \$\endgroup\$ Mar 22, 2020 at 18:03
  • \$\begingroup\$ @SurculoseSputum Ah, yes of course. Very nice - thanks! :-) \$\endgroup\$
    – Noodle9
    Mar 22, 2020 at 18:05
  • \$\begingroup\$ 24 bytes \$\endgroup\$
    – S.S. Anne
    Mar 22, 2020 at 18:11
  • \$\begingroup\$ @S.S.Anne Interesting, y commands ("Transliterate" according to the docs) act sort of like tr. Nice one - thanks! :-) \$\endgroup\$
    – Noodle9
    Mar 22, 2020 at 18:16
6
\$\begingroup\$

x86-64 machine code, 21 bytes

(Or 20 bytes for an x86-32 version with an explicit length input, allowing dec/jnz as the loop condition. Using cl for a shift count makes it not a win to use loop, and 64-bit mode has 2-byte dec so it's break-even to make it explicit-length).

Callable as void vucd_implicit(char *rdi) with the x86-64 System V calling convention. (It leaves RDI pointing to the terminating 0 byte if you want to use that bonus return value.)

# disassembly: objdump -drwC -Mintel
0000000000401000 <theloop>:
  401000:       b8 a0 bb ef fb          mov    eax,0xfbefbba0
  401005:       d3 e8                   shr    eax,cl
  401007:       30 c8                   xor    al,cl
  401009:       24 20                   and    al,0x20
  40100b:       30 c8                   xor    al,cl
  40100d:       aa                      stos   BYTE PTR es:[rdi],al
000000000040100e <vowel_up_consonant_down>:        # the function entry point
  40100e:       8a 0f                   mov    cl,BYTE PTR [rdi]
  401010:       84 c9                   test   cl,cl
  401012:       75 ec                   jne    401000 <theloop>
  401014:       c3                      ret    

Notice that the function entry point is in the middle of the loop. This is something you can do in real life; as far as other tools are concerned, theloop is another function that falls into this one as a tailcall.

This uses something like Arnauld's xor/and/xor idea for applying the lcase bit to an input character, instead of the more obvious and cl, ~0x20 to clear it in the original, and al, 0x20 to isolate it from the mask, and or al, cl to combine. That would be 1 byte larger because and cl, imm8 can't use the AL,imm special encoding with no ModRM.

Having the bitmap left-shifted by 5 so the bit we want lines up with 0x20 is also due to @Arnauld's answer. I had been planning to use bt/salc like in a previous vowel/consonant bitmap answer and mask that with 0x20 until I tried Arnauld's way and found it could be done even more efficiently.

NASM source (Try it online! with a test caller that does strlen on a command line arg and uses a write() system call afterward)

global vowel_up_consonant_down
theloop:
                                             ; consonant bitmap
    ;          ZYXWVUTSRQPONMLKJIHGFEDCBA@    For indexing with ASCII c&31 directly
    mov   eax, 111110111110111110111011101b << 5   ; line up with the lcase bit
                                             ; the low bit is 1 to preserve 0x20 ' '
    shr   eax, cl               ; AL & 0x20 is how the lowercase bit *should* be set
    xor   al, cl                ; bitdiff = (mask>>c) & c
    and   al, 0x20              ; isolate the lowercase bit
    xor   al, cl                ; flip the lcase bit if needed
    stosb                       ; and store
vowel_up_consonant_down:
    mov   cl, [rdi]
    test  cl, cl
    jnz  theloop               ; }while(c != 0)
    ret

Variants

no spaces: 19 bytes

If we didn't need to handle spaces (ASCII 0x20), we enter the function at the top, with the mov cl, [rdi] load at the top, but still leave the loop condition at the bottom. So we'd load and re-store the terminating 0, and the XOR that produced it would set ZF. The low bit of the bitmap would be 0 instead of 1.

vucd_pure_alphabetic:
.loop:
    mov   cl, [rdi]
   ...               ; same, but with bitmap[0] => 0
    xor   al,cl
    jnz  .loop       ; mask>>0 leave the terminating 0 unmodified; xor sets ZF

Upper-case-only input, like the A to Z in the question indicates: 19 bytes

(Or 17 without spaces either.)

If we can assume the lower-case bit was already cleared on input ASCII bytes, we can save one XOR (and change the other one to an OR)

    ...
    shr   eax, cl
    and   al, 0x20
    or    al, cl
    ...

Using the bt instruction:

Normally testing a bitmap is a job for the bt instruction, but where we're not branching on the result, it turns out to be cheaper to shift it, even though that means we can't easily use the loop instruction. (I haven't gone back to this idea to re-golf it after realizing we need to handle spaces).

I suspect there's room for more golfing, but the first version of this I tried was

vucd:
.loop:
    mov   dl, [rdi]
    ;          ZYXWVUTSRQPONMLKJIHGFEDCBA@    1-indexed using ASCII codes directly
    mov   esi, 111110111110111110111011101b   ; consonant/vowel bitmap for use with bt
    bt    esi, edx              ; CF = mask & (1U << (c&31))
%if CPUMODE == 32
    salc                        ; 1B   only sets AL = 0 or 0xFF.  Not available in 64-bit mode
%else
    sbb   eax, eax              ; 2B   eax = 0 or -1, according to CF.
%endif
    xor   al, dl
    and   al, 0x20              ; just the lowercase bit
    xor   al, dl
    loop .loop
    ret

Not re-tested after tweaking to handle spaces.

bt + salc in 32-bit mode costs the same as shr reg,cl + the extra test cl,cl that's needed because we can't use loop. So I think this is also 21 bytes. But 32-bit mode explicit-length can just dec/jnz a reg other than cl for a 20-byte total.

mov esi, imm32 can be hoisted out of the loop, or we can use EAX. Neither affects byte count, only efficiency or the calling-convention.

\$\endgroup\$
6
\$\begingroup\$

Ruby, 33 bytes

->s{s.downcase.tr"aeiou","AEIOU"}

Straightforward solution: downcase everything, then upcase vowels.

Try it online!

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

Retina, 9 bytes

T`vVL`VVl

Try it online! Explanation:

T`v`V

Lowercase vowels get uppercased.

T`V`V

Uppercase vowels also get uppercased, to avoid being matched later.

T`L`l

All other uppercase letters get lowercased.

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

C (gcc), 75 \$\cdots\$72 71 bytes

Added 4 bytes to fixed a bug.
Saved a byte thanks to ceilingcat!!!

u;f(char*s){for(;*s;*s++=u-65&&u-69&&u-73&&u-79&&u-85?*s|32:u)u=*s&95;}

Try it online!

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

C (gcc), 58 \$\cdots\$ 58 bytes

f(char*s){for(;*s;)*s++=index("aeiou",*s|32)?*s&95:*s|32;}

I tried to find a pattern in the vowels' representations using the modulo operator but nothing short enough. Instead, use strchr.

Fixed a bug kindly pointed out by Noodle9 at the cost of 3 bytes.
-1 byte thanks to Noodle9!
-1 byte thanks to Surculose Sputum!
-1 byte thanks to ceilingcat!

Try it online!

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

x86 platform-independent machine code, 46 bytes.

Expects the string pointer to be passed in eax, trashes ebx and edx. Entry point is located at 0x26.

Hex dump:

BA 22 82 20 00 D3 EA F6 C2 01 74 0B 8D
51 9F 83 FA 19 8D 59 E0 EB 09 8D 51 BF
83 FA 19 8D 59 20 0F 46 CB 88 08 40 0F
BE 08 85 C9 75 D3 C3

Disassembly:

00000000  BA22822000        mov edx,0x208222
00000005  D3EA              shr edx,cl
00000007  F6C201            test dl,0x1
0000000A  740B              jz 0x17
0000000C  8D519F            lea edx,[ecx-0x61]
0000000F  83FA19            cmp edx,byte +0x19
00000012  8D59E0            lea ebx,[ecx-0x20]
00000015  EB09              jmp short 0x20
00000017  8D51BF            lea edx,[ecx-0x41]
0000001A  83FA19            cmp edx,byte +0x19
0000001D  8D5920            lea ebx,[ecx+0x20]
00000020  0F46CB            cmovna ecx,ebx
00000023  8808              mov [eax],cl
00000025  40                inc eax
00000026  0FBE08            movsx ecx,byte [eax]
00000029  85C9              test ecx,ecx
0000002B  75D3              jnz 0x0
0000002D  C3                ret

byte count = 0x2E = 46

\$\endgroup\$
5
  • 1
    \$\begingroup\$ :( bytes in decimal please \$\endgroup\$
    – ASCII-only
    Mar 23, 2020 at 3:48
  • \$\begingroup\$ Two possible options for golfing that bitmap >> (c&31) test of the immediate bitmap: use bts edx, ecx, or use a bitmap that's already shifted by 1 so the bit you want goes into CF instead of the low bit of EDX. (Except that fails for CL&31=0 which doesn't clear CF). Also, you aren't taking any advantage of AL,imm8 short forms like 2-byte test al, imm8. Use ESI as the input pointer so you can lodsb / xchg eax,ecx to do cl = *esi++ Or with BTW, you don't need the byte in CL so it's also better for that reason. \$\endgroup\$ Mar 23, 2020 at 4:29
  • \$\begingroup\$ @ASCII-only: I fixed the title line of this answer to count in decimal. I think that's allowed even within codegolf's strict rules about not editing other people's code, only fixing formatting and maybe explanations. \$\endgroup\$ Mar 23, 2020 at 8:09
  • \$\begingroup\$ @Krysztof: Turns out a right-shift works at least as well as bt / salc when you use the ASCII code directly, so it's 1-indexed. I'm not sure why you need so much branching and cmov, though. I think you're separately doing c-'a' and/or c-'A'. You can just mask away the lower-case bit (What is the idea behind ^= 32, that converts lowercase letters to upper and vice versa?); Anyway my answer on this Q ended up branchless other than the loop, 21 bytes. \$\endgroup\$ Mar 23, 2020 at 8:15
  • \$\begingroup\$ You also don't need a movsx load. This is code-golf: performance isn't important so we don't need to avoid false dependencies or partial-register stalls (e.g. from using a 32-bit cmov after writing 8-bit partial registers). \$\endgroup\$ Mar 23, 2020 at 8:18
4
\$\begingroup\$

05AB1E,  9  6 bytes

Saved 3 using Luis Mendo's CJam approach

lžMDu‡

Try it online! (Footer formats the resulting list of characters as a plain string)

How?

lžMDu‡         e.g. input="LowEr"  stack: []
l      - push lower-case (input)          ["lower"]
 žM    - push lower-case vowels           ["aeiou", "lower"]
   D   - duplicate                        ["aeiou", "aeiou", "lower"]
    u  - upper-case                       ["AEIOU", "aeiou", "lower"]
     ‡ - transliterate                    ["lOwEr"]
       - implicit print                   lOwEr
\$\endgroup\$
2
  • 1
    \$\begingroup\$ YES...! I was assuming this was Jelly...................................... I was about to come here and comment that I couldn't even find it in the code but now I understand why! Thanks. \$\endgroup\$
    – RGS
    Mar 22, 2020 at 17:29
  • \$\begingroup\$ I have a Jelly answer too :) \$\endgroup\$ Mar 22, 2020 at 17:32
4
\$\begingroup\$

Io, 72 bytes

Takes input as a special format.

method(x,x map(i,if("aeiou"containsSeq(i),i asUppercase,i asLowercase)))

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Red, 83 82 bytes

func[s][v: charset"aoeiu"parse lowercase s[any[to v change t: v(uppercase t/1)]]s]

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Javascript (V8), 97 bytes

s=>[...s].map(c=>{t="aeiouAEIOU";return(t.includes(c)?c.toUpperCase():c.toLowerCase())}).join('')

Takes a string, iterate over every chars and check if the char is a vowel. If so return the char in uppercase, otherwise in lowercase. Then join the return of the map with a void char.

  • First post/answer here, if you see some errors or missed case, or just want to improve my code feel free to do so
\$\endgroup\$
4
\$\begingroup\$

Haskell, 68 bytes

import Data.Char
f=map(g.toLower)
g x|x`elem`"aeiou"=toUpper x|1<2=x

Try it online!

\$\endgroup\$
4
\$\begingroup\$

JavaScript (V8), 93...77 bytes

Log:

  • -5 bytes thanks to @Benji
  • -14 bytes: switched to case insensitive matching and .test()
s=>[...s].map(c=>/[aeiou]/i.test(c)?c.toUpperCase():c.toLowerCase()).join('')

Try it online!

s=> // es6 arrow function
    [...s]. // split input string into array
        map(c => // another es6 arrow function, this time for a callback iterating over the array
             /[aeiou]/i // case insensitive regex
                .test(c)? // use a ternary operator to check if the character matches the regex
                    c.toUpperCase(): // if true return character to uppercase
                        c.toLowerCase()) // otherwise return lowercase
                            .join('') // join the array back into a string

Methods mentioned:

\$\endgroup\$
2
  • \$\begingroup\$ You could save a few bytes if you change /a|e|i|o|u/ -> /[aeiou] \$\endgroup\$
    – Benji
    Mar 25, 2020 at 19:28
  • 1
    \$\begingroup\$ right! thanks @Benji \$\endgroup\$ Mar 26, 2020 at 4:21
3
\$\begingroup\$

Japt v2.0a0 -m, 10 7 bytes

u r\c_v

Try it

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

Python 3, 50 bytes

lambda s:bytes(c^(c^~68174912>>c%32)&32for c in s)

Try it online!

Port of Arnauld's JS answer using bytes object in Python. Because Python's >> does not imply %32 on its right argument, it must be done manually.

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

T-SQL, 48 bytes

SELECT TRANSLATE(LOWER(v),'aeiou','AEIOU')FROM t

Takes input from a pre-existing table t with varchar column v, per our IO rules.

Converts the entire string to lowercase, then makes just the vowels uppercase. The function TRANSLATE works in SQL 2017 and later.

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

K4, 24 bytes

Solution:

.q.ssr/[;_v;v:"AEIOU"]@_

Explanation:

Replace each lowercase vowel with the uppercase equivalent.

.q.ssr/[;_v;v:"AEIOU"]@_ / the solution
                       _ / lowercase
                      @  / apply
.q.ssr/[;  ;         ]   / search/replace, iterate over vowels
            v:"AEIOU"    / store uppercase vowels as 'v'
         _v              / lowercase vowels
\$\endgroup\$
2
\$\begingroup\$

K (oK), 27 23 21 bytes

Solution:

`c$x-32*~^"aeiou"?x:_

Try it online!

Explanation:

Even nicer approach thanks to @ngn... either substract 0 or 32 from the input based on whether or not it's a vowel:

`c$x-32*~^"aeiou"?x:_ / the solution
                    _ / lowercase input
                  x:  / store as 'x'
          "aeiou"?    / lookup input in "aeiou" else null
         ^            / is null?
        ~             / not
    -32*              / multiply boolean list by -32 (yields 0 or -32)
   x                  / subtract from x
`c$                   / cast back to characters

Notes:

  • -6 bytes thanks to @ngn
\$\endgroup\$
4
  • 1
    \$\begingroup\$ hint: (-32*isvowel)+x leads to a shorter solution than @[;;;] \$\endgroup\$
    – ngn
    May 23, 2020 at 8:45
  • \$\begingroup\$ i was thinking of `c$(-32*x in"aeiou")+x:_ but yours is even better :) \$\endgroup\$
    – ngn
    May 23, 2020 at 15:36
  • 1
    \$\begingroup\$ -2: `c$x-32*~^"aeiou"?x:_ \$\endgroup\$
    – ngn
    May 23, 2020 at 15:40
  • \$\begingroup\$ Thanks - I managed to golf another byte as I was writing up the explanation - let me update with your latest :) \$\endgroup\$
    – mkst
    May 23, 2020 at 19:11
2
\$\begingroup\$

Julia 49 bytes

Try it!

f=l->map(c->in(c,"aeiou") ? c-32 : c,lowercase.(l))
\$\endgroup\$
2
\$\begingroup\$

Pyth, 20 bytes

K"aeiou"smrd}d+KrK1w

Try it online!

Explanation

                       w=input()
K"aeiou"               K="aeiou"
        s              "".join(
         m              map(
          r              lambda d:r(
           d              d,
             d             d
            }             in
               K           K
              +            +
                 rK1       K.upper())),
                    w    w)
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$ Feb 16, 2022 at 14:27

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.