20
\$\begingroup\$

Objective

Given an string \$n\$, output two strings, namely the string consisting of vowels "a", "e", "i", "o", and "u", and the string consisting of consonants.

Worked Example

Say the input is "Environment".

The "vowel" output is "Eioe".

The "consonant" output is "nvrnmnt".

I/O format

Flexible; default I/O policies apply.

\$\endgroup\$
6
  • 8
    \$\begingroup\$ Welcome to Code Golf and nice first question! For future reference, we recommend using the Sandbox to get feedback on challenge ideas before posting them to main. You might want to add a few more test cases, and clarify how capital letters are handled. \$\endgroup\$
    – emanresu A
    Commented May 31 at 19:30
  • 4
    \$\begingroup\$ I take it the input will only have letters A-Z and a-z? \$\endgroup\$
    – xnor
    Commented May 31 at 19:44
  • 5
    \$\begingroup\$ Do the vowels and consonants have to be in the same order as they appear in the original string? \$\endgroup\$
    – Graham
    Commented May 31 at 20:28
  • 3
    \$\begingroup\$ This might be a trivial-ish challenge, but if you take the time to answer, you should upvote. \$\endgroup\$
    – SanguineL
    Commented May 31 at 20:56
  • 5
    \$\begingroup\$ By my spy, why pry y? Sync glyphs thy. \$\endgroup\$ Commented Jun 1 at 7:14

30 Answers 30

9
\$\begingroup\$

Python, 54 bytes

lambda s:"".join(sorted(s+" ",key="aiueoAIUEO".count))

Attempt This Online!

Returns a single string with the two parts separated by a space.

Python, 57 bytes (@Mukundan314)

o=2*[""]
for x in input():o[x in"aiueoAIUEO"]+=x
print(o)

Attempt This Online!

Python, 58 bytes

o=["",""]
for x in input():o[x in"aiueoAIUEO"]+=x
print(o)

Attempt This Online!

Full program.

Python, 66 bytes (@Mukundan314)

lambda s,v="aiueoAIUEO":[v:=[i for i in s if{i}-{*v}]for _ in"xx"]

Attempt This Online!

Outputs lists of characters.

Python, 70 bytes

lambda s,v="aiueoAIUEO":[v:="".join(x.strip(v)for x in s)for _ in"xx"]

Attempt This Online!

Python, 72 bytes

lambda s,v="aiueoAIUEO":[v:="".join(x*-v.find(x)for x in s)for _ in"xx"]

Attempt This Online!

Python, 77 bytes

lambda s,v="aiueoAIUEO":[v:=s.translate({}.fromkeys(v.encode()))for _ in"xx"]

Attempt This Online!

\$\endgroup\$
4
  • 1
    \$\begingroup\$ 66 bytes, by outputting as a list of characters instead of a string \$\endgroup\$ Commented Jun 1 at 3:21
  • \$\begingroup\$ @Mukundan314 thanks! I wonder, as we are pushing acceptable I/O, do you happen to know whether it is ok to move everything to byte strings? \$\endgroup\$ Commented Jun 1 at 5:04
  • 1
    \$\begingroup\$ That's totally okay, as you'd do that anyway in C. \$\endgroup\$
    – corvus_192
    Commented Jun 1 at 19:03
  • \$\begingroup\$ 57 bytes, [""]*2 instead of ["",""] \$\endgroup\$ Commented Jun 2 at 1:54
6
\$\begingroup\$

C (gcc), 86 bytes

Prints the consonants, followed by a space, followed by the vowels.

char*v,*q;f(char*s){for(q=v=s;*v=*s;)2130466>>*s++&1?v++:putchar(*v);printf(" %s",q);}

Try it online!

Method

We use 3 pointers:

pointers

  • s is the string pointer passed as input.
  • v is a vowel pointer, less than or equal to s. At each iteration, we copy the character at *s to *v (including the trailing \0). But v is incremented only when the copied character is a vowel, thus progressively overwriting the beginning of the original string with the vowels.
  • q is just a copy of the original pointer. We use it to print all the vowels at once at the end of the process.

Vowels are identified with the following bitmask:

2130466 = 0b1000001000001000100010
            ^     ^     ^   ^   ^
            u     o     i   e   a

It is assumed that only the 5 least significant bits of the shift amount are taken into account, which is the case for at least Intel and ARM.

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

Ruby, 31 bytes

->s{[v=s.grep(/[aeiou]/i),s-v]}

Try it online!

Input as an array of characters, assumed to contain only uppercase and lowercase letters. Output is a two-element array of vowels followed by consonants, both as arrays of characters.

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

Charcoal, 14 bytes

E²Φθ⁼ι№aeiou↧λ

Try it online! Link is to verbose version of code. Outputs the consonants then vowels on separate lines. Explanation:

 ²              Literal integer `2`
E               Map over implicit range
   θ            Input string
  Φ             Filtered where
      №         Count of
             λ  Current character
            ↧   Lowercased
       aeiou    In literal string `aeiou`
    ⁼           Equals
     ι          Outer value
                Implicitly print
\$\endgroup\$
3
\$\begingroup\$

Uiua SBCS, 17 bytes

∩▽¬,,∊,⊂⌵."aeiou"

Try it!

∩▽¬,,∊,⊂⌵."aeiou­⁡​‎‎⁡⁠⁣⁣‏⁠‎⁡⁠⁣⁤‏⁠‎⁡⁠⁤⁡‏⁠‎⁡⁠⁤⁢‏⁠‎⁡⁠⁤⁣‏⁠‎⁡⁠⁤⁤‏⁠‎⁡⁠⁢⁡⁡‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁢⁤‏⁠‎⁡⁠⁣⁡‏⁠‎⁡⁠⁣⁢‏‏​⁡⁠⁡‌⁣​‎‎⁡⁠⁢⁢‏⁠‎⁡⁠⁢⁣‏‏​⁡⁠⁡‌⁤​‎‎⁡⁠⁣‏⁠‎⁡⁠⁤‏⁠‎⁡⁠⁢⁡‏‏​⁡⁠⁡‌⁢⁡​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏‏​⁡⁠⁡‌­"
          "aeiou"  # ‎⁡the string 'aeiou'
       ⊂⌵.         # ‎⁢duplicate, uppercase, prepend
     ∊,            # ‎⁣mask of vowels w/ input
  ¬,,              # ‎⁤mask of consonants w/ input
∩▽                 # ‎⁢⁡keep both
\$\endgroup\$
2
  • \$\begingroup\$ I think you were overthinking this, just use group... :) I like your way too though \$\endgroup\$ Commented Jun 1 at 10:45
  • 1
    \$\begingroup\$ @noodleman Group sometimes only returns one output. \$\endgroup\$
    – chunes
    Commented Jun 1 at 15:08
3
\$\begingroup\$

Japt v2.0a0, 4 bytes

üè\c

Try it

üè\c     :Implicit input of string
ü        :Group & sort by
 è       :  Count of
  \c     :    RegEx character class for consonants
\$\endgroup\$
3
\$\begingroup\$

R, 52 bytes

\(s,`?`=\(p)gsub(p,"",s,T))c(?"[^aeiou]",?"[aeiou]")

Attempt This Online!

Explanation outline

  • The idea is to replace all consonants ([^aeiou]) and then all vowels ([aeiou]) with nothing.
  • For that we use gsub with ignore.case flag (4th argument) set to True.
  • We assign gsub with appropriate arguments to ? for brevity, leaving only pattern as argument.
\$\endgroup\$
4
  • \$\begingroup\$ This does my head in. Could you explain a little what's going on? I see several things that seem impossible, but clearly aren't. \$\endgroup\$
    – AkselA
    Commented Jun 2 at 6:25
  • \$\begingroup\$ @AkselA I've added an explanation outline, feel free to ask any additional questions. \$\endgroup\$
    – pajonk
    Commented Jun 2 at 7:30
  • \$\begingroup\$ After ungolfing it a little like so: s <- "Rekkevidde"; '?'=\(p)gsub(p,"",s,T); c(?"[^aeiou]",?"[aeiou]") I can mostly see what's going on. I couldn't see that ?"[^aeiou]" was a function call. Why is it possible to omit the parentheses here? \$\endgroup\$
    – AkselA
    Commented Jun 2 at 10:20
  • 1
    \$\begingroup\$ @AkselA it's just like any other operator, like ! or +. I could have used them (check it out 😉 ATO), but I chose ?. \$\endgroup\$
    – pajonk
    Commented Jun 2 at 11:01
3
\$\begingroup\$

Zsh, 40 bytes

p=aeiouAEIOU
<<<${1//[^$p]}'
'${1//[$p]}

Try it online!

${1//PATTERN} removes all substrings matching PATTERN. The trailing/leading single quote is there to include a literal newline in the string which is printed.

Bash, 41 bytes

-1 byte thanks to @Themoonisacheese

Bash uses a different character for negation in character classes, and requires two more bytes for echo .... But, as @Themoonisacheese points out, the globbing character ] can be included in the parameter, which saves a byte.

p=aeiouAEIOU]
echo ${1//[!$p}'
'${1//[$p}

Try it online! Try it online!

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

Retina, 18 bytes

*\T`Vv`_
T`Vvp`Vv_

Try it online! Outputs the consonants followed by the vowels. Explanation:

*\`

Run the stage and print the results but don't save them, so the next stage uses the original input.

T`Vv`_

Delete all upper and lower case vowels from the input.

T`Vvp`Vv_

Keep all upper and lower case vowels but delete all other printable ASCII.

This would be a massive 48 bytes in Retina 0.8.2; you do at least save a byte by not needing the explicit \ after the * but Retina 0.8.2 doesn't have V or v so you need to use A\EI\OUaei\ou on the first line and A\EI\OUaeiou twice on the second (o does not need to be quoted if you use it on both sides).

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

Go, 132 128 bytes

import."strings"
func f(s string)(c,v string){for i:=range s{if r:=s[i:i+1];ContainsAny(r,"aeiouAEIOU"){v+=r}else{c+=r}}
return}

Attempt This Online!

Loops over each character, checks to see if it is one of "aeiouAEIOU", and appends it to the corresponding output string.

c is the consonants, and v is the vowels.

  • -4 by @Mukundan314 by just including the uppercase vowels
\$\endgroup\$
1
  • \$\begingroup\$ -4 bytes, its shorter to just include uppercase version of the vowels than to convert char to lowercase. \$\endgroup\$ Commented Jun 1 at 4:20
2
\$\begingroup\$

Bash, 50 bytes

-8 bytes using stdout, thanks GammaFunction
-1 byte with a better alias, by me
-6 bytes using <<< instead of echo , by me
-8 bytes by removing redundant grep call, which enables me to use a better alias, by me

g="grep -i [aeiou] "
$g-o<<<$1
grep -o .<<<$1|$g-v

Try it online!

use as a script or as the body of a bash function and call with input as first argument. Outputs vowels then consonnants, one per line.

See also: 42 bytes by GammaFunction.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Hey, welcome to the SE! The common consensus here is to not allow modifying global variables as I/O, because it makes this a snippet rather than a function or full program. I know you may not think it's in the spirit of the challenge to output to stdout, but Bash is fairly limited in its output options. \$\endgroup\$ Commented Jun 3 at 10:32
  • 1
    \$\begingroup\$ If you really do want to keep this I/O, you can accept the variable names as extra arguments, and then use local -n (TIO) or eval (TIO) to set those variables. (The TIO links are based on my 42 byte answer.) \$\endgroup\$ Commented Jun 3 at 10:35
  • \$\begingroup\$ thanks for the info. i've changed my answer to insted use $1 and stdout, but obviously yours is smaller. I had completely forgotten bash string operators \$\endgroup\$ Commented Jun 3 at 11:54
  • 1
    \$\begingroup\$ @GammaFunction: I can't comment on your answer because i lack rep, but you can shave off 1 byte from your technique (ironically this does not work in zsh): p=aeiouAEIOU] echo ${1//[!$p}' '${1//[$p} \$\endgroup\$ Commented Jun 5 at 9:36
  • 1
    \$\begingroup\$ Nice find! Edited and credited. \$\endgroup\$ Commented Jun 5 at 14:42
2
\$\begingroup\$

sed, 34 bytes

h
s/[^aeiou]//gi
p
g
s/[aeiou]//gi

Try it online!

Prints two strings on separate lines.

Bash (+sed), 37 bytes

p=aeiou]//gi
sed "h;s/[^$p;p;g;s/[$p"

Try it online!

Expands to equivalent of

Bash (+sed), 40 bytes

sed 'h
s/[^aeiou]//gi
p
g
s/[aeiou]//gi'

Try it online!

\$\endgroup\$
1
\$\begingroup\$

APL+WIN, 38 bytes

Prompts for word and outputs consonants followed by vowels in the order they appear in the word. Can be 4 bytes shorter if order does not matter.

(s~v),' ',v[((v←'AaEeIiOoUu')⍳s←⎕)~11]

Try it online! Thanks to Dyalog Classic

\$\endgroup\$
1
\$\begingroup\$

Vyxal 3, 3 bytes

⸠AĠ

Try it Online!

Returns a list of [vowels, consonants]

Explained

⸠AĠ­⁡​‎‎⁡⁠⁣‏‏​⁡⁠⁡‌⁢​‎‎⁡⁠⁡‏⁠‎⁡⁠⁢‏‏​⁡⁠⁡‌­
  Ġ  # ‎⁡Split the input into groups based on whether
⸠A   # ‎⁢Each character is a vowel
💎

Created with the help of Luminespire.

\$\endgroup\$
1
\$\begingroup\$

Arturo, 34 bytes

$->s->@[--s<=match s{(?i)[aeiou]}]

Try it!

Outputs a list where the first element is a list of vowels as singleton strings and the second element is a string of consonants.

Explanation

$->s->                ; function taking a string s
@[   ]                ; capture the following in a list:
--                    ; set difference between...
s                     ; input and...
<=                    ; extra copy of...
match s{(?i)[aeiou]}  ; case-insensitive vowels in input
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -lp, 24 bytes

s/[^AEIOU]/$\.=$&;""/gei

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Why the ^? 15 \$\endgroup\$
    – Neil
    Commented Jun 1 at 13:14
  • \$\begingroup\$ @Neil, to get the vowels first, i though it was required \$\endgroup\$ Commented Jun 2 at 10:07
1
\$\begingroup\$

JavaScript (ES6), 47 bytes

Returns [ consonants, vowels ].

s=>[s.replace(/[aeiou]/gi,c=>(v+=c,""),v=""),v]

Try it online!

Commented

s => [           // s = input string
  s.replace(     // replace in s:
    /[aeiou]/gi, //   look for all vowels, case insensitive
    c =>         //   for each vowel c:
      (          //
        v += c,  //     append c to v
        ""       //     remove it from the original string
      ),         //
    v = ""       //   start with v = ""
  ),             // end of replace() -> only consonants remain
  v              // return the string of vowels in 2nd position
]                //
\$\endgroup\$
1
\$\begingroup\$

Uiua, 12 bytes

⊕□∊⌵,"AEIOU"

Try it online

group (with boxing) by whether each character is a member when capitalized , of "AEIOU"

\$\endgroup\$
1
\$\begingroup\$

Python, 79 78 76 bytes

-1 from me

-2 from solid.py!

lambda s,l='[aeiouAEIOU]':(sub('[^'+l[1:],'',s),sub(l,'',s))
from re import*

Attempt This Online!

Saved a byte by modifying the regex instead of joining the array from .findall().


Original version (79 bytes)

from re import*
f=lambda s,l='[aeiouAEIOU]':(''.join(findall(l,s)),sub(l,'',s))

Attempt This Online!

Returns a tuple including the vowel string and the consonant string.

\$\endgroup\$
4
  • \$\begingroup\$ Alternatively, for 78 bytes, the .findall() version could have been shortened using a case insensitive regexp (?i)[aeiou] \$\endgroup\$
    – Nicola Sap
    Commented Jun 1 at 7:58
  • \$\begingroup\$ @SanguineL Since this is not a recursive function, you could save 2 bytes like this: Python, 76 bytes: lambda s,l='[aeiouAEIOU]':(sub('[^'+l[1:],'',s),sub(l,'',s)) from re import* \$\endgroup\$
    – solid.py
    Commented Jun 1 at 12:21
  • 1
    \$\begingroup\$ @solid.py Nice, thanks! \$\endgroup\$
    – SanguineL
    Commented Jun 1 at 13:25
  • \$\begingroup\$ [64 bytes](# Python, 64 bytes python lambda s:[re.sub(f'[{z}aeiouAEIOU]','',s)for z in'^ '] import re Attempt This Online!) \$\endgroup\$ Commented Jun 1 at 20:05
1
\$\begingroup\$

Scala 2, 30 bytes

_.partition("aiueoAIUEO"toSet)

Attempt This Online!

\$\endgroup\$
1
\$\begingroup\$

AWK, 23 bytes

Using flags -vIGNORECASE=1 -vRS=[aiueo]+.

{printf RT;printf$0>FS}

Prints vowels to stdout and consonants to a file called (single space).

Attempt This Online!

\$\endgroup\$
1
\$\begingroup\$

05AB1E (legacy), 10 (or 7) bytes

žMžN‚Du+€Ã

Try it online or verify multiple test cases at once.

If outputting just a single group when the input only contains vowels or only consonants, it could be 7 bytes in the new version of 05AB1E with a group-by builtin:

.¡žMslå

Try it online or verify multiple test cases at once.

Explanation:

žM         # Push the lowercase vowels constant excluding y
  žN       # Push the lowercase consonants constant including y
    ‚      # Pair the two together
     D     # Duplicate
      u    # Uppercase the strings in the copy
       +   #†Element-wise append them
        €  # Map over both strings:
         Ã #  Keep just those characters from the (implicit) input-string
           # (after which the resulting pair is output implicitly)

†: This is the reason for the legacy version of 05AB1E, which is built in Python, where + can be used to append strings. Whereas in the new version of 05AB1E, built in Elixir, + is only used for numeric calculations.

.¡         # Group the characters in the (implicit) input by:
  žM       #  Push the lowercase vowels constant excluding y
    s      #  Swap so the current character is at the top of the stack
     l     #  Convert it to lowercase
      å    #  Check whether it's in the vowels constant
           # (after which the list of lists of characters is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

Brachylog, 10 bytes

{ḷ∈Ṿ|l}ᵍcᵐ

Try it online!

Explanation

{      }ᵍ      Group by: group letters together if they give the same output
 ḷ∈Ṿ             The letter lowercased is in "aeiou", the output is then "aeiou"
     |           Else (the letter is a consonant)
      l          The output is the length of "aeiou" = 5
         cᵐ    Map concatenate to get 2 strings instead of lists of chars
\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 69 bytes

The solution is straightforward containing just two calls to the same method. Smarter would be of course to replace them with a loop like for(char j:{"","^"})r+=s.replaceAll("(?i)["+j+"aeiou]","") but I don't see how to overcome that verbosity ))

s->s.replaceAll("(?i)[^aeiou]","")+" "+s.replaceAll("(?i)[aeiou]","")

Try it online!

\$\endgroup\$
1
\$\begingroup\$

jq, 46 bytes

./""|group_by(inside("aeiouAEIOU"))[]|join("")

Try it online!

group_by takes any filter, so we group by whether each character is inside the string of all vowels.

\$\endgroup\$
1
\$\begingroup\$

Perl 5 -pF[^AEIOUaeiou], 19 bytes

say@F;s/[aeiou]//ig

Try it online!

\$\endgroup\$
1
\$\begingroup\$

J from Jsoftware, 29 bytes

(e.(#;]#~[=0:)[)&'aeiouAEIOU'

J from Jsoftware, 32 bytes

((e.#[);[#~0:=e.)&'aeiouAEIOU'
\$\endgroup\$
1
\$\begingroup\$

Google Sheets, 50 bytes

Assumes the string is in A1 and it returns the result in two horizontally adjacent cells.

=SORT(REGEXREPLACE(A1,"(?i)["&{"^",""}&"aeiou]",))

Demo

enter image description here

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I tried this but the (?i) at the end doesn't seem to work. \$\endgroup\$
    – z..
    Commented Jun 12 at 10:12
  • 1
    \$\begingroup\$ You're correct. Sorry, my test material was bad. \$\endgroup\$ Commented Jun 12 at 13:47
0
\$\begingroup\$

Batch 151 bytes

@Echo off&Set $=For /f "Delims=" %%G in ('cmd.exe/u/c ^^^"Echo(%1^^^"^^^|find/v ""^^^|findstr/li# "a e i o u"'^)Do ^<nul Set/p=%%G
%$:#=%
Echo(
%$:#=V%

Input is as a parameter from the command line.

How: $ is defined with a macro that enacts tho following logic:

cmd.exe/u/c ^"Echo(%1^"^|find/v "" - Splits the stringt into individual characters

findstr/li# "a e i o u" - print characters matching aeiou if # has been removed during the macros expansion; or prints characters not matching aeiou if # has been substituted with V during expansion.

\$\endgroup\$
-1
\$\begingroup\$

PowerShell Core, 50 bytes

$args|group{$_-in("aeiou"|% t*y)}|%{-join$_.Group}

Try it online!

Takes the input string using splatting
Returns two strings

$args                        # The string as chars
|group{$_-in("aeiou"|% t*y)} # Arranged in groups checking if each char is a vowel or not
|%{-join$_.Group}            # Joined in a string for each group
\$\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.