# Count the number of vowels in each word of a string

This is a rather easy challenge.

# Challenge

Input will contain a string (not null or empty) of maximum length 100. Output the number of vowels in each word of the string, separated by spaces.

# Rules

• The string will not be more than 100 characters in length.
• The string will only contain alphabets A-Z , a-z and can also contain spaces.
• Input must be consumed from the stdin or command line arguments.
• Output must be outputted in the stdout.
• You can write a full program, or a function that takes input from the stdin and outputs the result.
• The vowels that your program/function needs to count are aeiou and AEIOU.

# Test Cases

This is the first test case     --> 1 1 1 1 1 2
one plus two equals three       --> 2 1 1 3 2
aeiou AEIOU                     --> 5 5
psst                            --> 0
the quick brown fox jumped over the lazy dog --> 1 2 1 1 2 2 1 1 1


# Scoring

This is , so the shortest submission (in bytes) wins.

• Is there a reason why you insist on a rather restrictive I/O format? Not every language can (conveniently) interact with STDIN and STDOUT. We have defaults for this (which you are of course free to override if you wish), which also allow command-line argument, function argument, return value etc. (They can also be found in the tag wiki.) – Martin Ender May 21 '15 at 10:58
• @MartinBüttner , "Is there a reason why you insist on a rather restrictive I/O format?" -- No. I just like stdin with stdout. I don't like to "get input" via the function arguments. command-line arguments seems ok. I've added it into the post. – Spikatrix May 21 '15 at 11:04
• WIKIPEDIA: The name "vowel" is often used for the symbols that represent vowel sounds in a language's writing system, particularly if the language uses an alphabet. In writing systems based on the Latin alphabet, the letters A, E, I, O, U, and sometimes Y are all used to represent vowels. However, not all of these letters represent vowels in all languages. What do YOU mean by vowels? – edc65 May 21 '15 at 14:37
• Is a single trailing space okay? – Alex A. May 21 '15 at 15:19
• Use the Sandbox for Proposed Challenges. – mbomb007 May 22 '15 at 1:09

# Pyth, 17 bytes

jdml@"aeiou"dcrzZ


Straightforward solution. Try it online: Demonstration or Test harness

### Explanation:

               z   input
r Z  convert to lower-case
c     split at spaces
m                map each word d to:
@"aeiou"d         filter d for chars in "aeiou"
l                  length
jd                 join by spaces and implicitly print

• It always amuses me when people write a Pyth solution and call it "Straightforward" (Though this one is admittedly easier to grasp than most) +1 – Christopher Wirt Jun 19 '15 at 18:28

# C, 113 108 103 96 bytes

Thanks @andrea-biondo for a particularly nice 5 byte saving.

main(a,v,c)char**v;{do{for(a=0;c=*v[1]++%32;2016%(c+27)||a++);printf("%d ",a);}while(v[1][-1]);}


This still feels sort of bloated so hopefully I can get it down quite some bytes later tonight.

The interesting part is perhaps that

!(124701951%((c-65&31)+33))


will be 1 if c is an (upper or lower case) ASCII vowel, and 0 for other characters a-zA-Z. The subexpression c-65&31 maps 'a' and 'A' to 0, 'b' and 'B' to 2, etc. When we add 33 the vowels correspond to the numbers 33, 37, 41, 47, 53 respectively, all of which are (conveniently) prime. In our range only such numbers will divide 124701951 = 33*37*41*47*53, ie only for vowels will the remainder of 124701951%(...) be zero.

EDIT: In this way one can consider the expression !(n%((c-65&31)+s)) where (n,s) = (124701951, 33) as determining whether the character c is a vowel. In the comments @andrea-biondo pointed out that the pair (n,s) = (2016,28) can also be used in this expression to determine vowelhood. I'll leave the current explanation in terms of primes above, but the reason this shorter pairing works is again because in the range 28--53 the only numbers with prime factors entirely in the set of prime factors of 2016 are 28, 32, 36, 42, 48, which correspond precisely to the vowels.

EDIT2: Another 5 bytes saved since (c-65&31)+28 can be shortened to c%32+27.

EDIT3: Converted to a do-while loop to finally get it below 100 bytes.

Test cases:

$./vowelc "This is the first test case" 1 1 1 1 1 2$ ./vowelc "one plus two equals three"
2 1 1 3 2
$./vowelc "aeiou AEIOU" 5 5$ ./vowelc "psst"
0

• OMG! This is just awesome! You can save more bytes by using a; outside main. This way, you reduce some bytes as you don't need to declare a in main(...) and also, don't need to initialize a from the loop. – Spikatrix May 21 '15 at 14:11
• @CoolGuy: a is re-initialized at every loop, so you can't initialize it once to zero by declaring global. I wrote a small bruteforcer to find the smallest (n, s) pair such that n%((c-65&31)+s) is zero for vowels and non-zero for consonants (a-z, A-Z). I found (2016, 28) and it seems to work well: !(2016%((c-65&31)+28)) is 5 chars shorter. Anyway, very nice solution :) – Andrea Biondo May 21 '15 at 19:22

# CJam, 21 19 bytes

r{el_"aeiou"--,Sr}h


How it works:

r{               }h    e# Read the first word and enter a do-while loop
el_                  e# Convert the word into lower case and take a copy of it
"aeiou"           e# All small caps vowels
-          e# Remove all vowels from the copied word
-         e# Remove all non-vowels from the original word
,        e# At this point, we have a string with all vowels of the word
e# Simply take its length
S       e# Put a space after the number of vowel
r      e# Read the next word. This serves as the truthy condition for the
e# do-while loop for us as if there are no word left, this returns
e# null/falsy and the do-while loop is exited


Try it online here

# R, 44 43 bytes

cat(nchar(gsub("[^aeiou]","",scan(,""),T)))


Ungolfed + explanation:

# Read a string from STDIN. scan() automatically constructs a vector
# from input that contains spaces. The what= argument specifies that
# a string will be read rather than a numeric value. Since it's the
# second specified argument to scan(), we can simply do scan(,"").

s <- scan(what = "")

# For each word of the input, remove all consonants using gsub(),
# which is vectorized over its input argument.

g <- gsub("[^aeiou]", "", s, ignore.case = TRUE)

# Print the number of remaining characters in each word to STDOUT
# using cat(), which automatically separates vector values with a
# single space.

cat(nchar(g))


# Perl, 3534 31

say map{lc=~y/aeiou//.$"}split  30 characters +1 for -n. Like a lot of Perl code, this works from right to left. split will split the inputted line on whitespace. map will run the code between {} on each word that was split. lc makes the word lower case. =~y/aeiou// will give us the count of vowels. .$" will append a space to the word. say then prints all the words!

Run with:

echo 'aeiou AEIOU' | perl -nE'say map{lc=~y/aeiou//.$"}split'  # Python 3, 65 bytes print(*[sum(c in'aeiouAEIOU'for c in w)for w in input().split()])  Very straightforward, fairly readable. w stands for word, c stands for character. # Perl: 30 characters (Kind of forces the rules: the numbers in the output are separated with as many spaces as the input words were.) s|\w+|@{[$&=~/[aeiou]/gi]}|ge


Sample run:

bash-4.3$while read s; do printf '%-30s --> ' "$s"; perl -pe 's|\w+|@{[$&=~/[aeiou]/gi]}|ge' <<< "$s"; done < test-case.txt
This is the first test case    --> 1 1 1 1 1 2
one plus two equals three      --> 2 1 1 3 2
aeiou AEIOU                    --> 5 5
psst                           --> 0


### Perl: 27 characters

(Just to show how short would be if I didn't forget about y///'s return value. Again. Now go and upvote chilemagic's answer which reminded me about y///'s return value. Again.)

s|\w+|lc($&)=~y/aeiou//|ge  • Dang this beats my answer. This s!\w+!lc($&)=~y/aeiou//!ge gets it down to 27 bytes (26 characters +1 for the -p. – hmatt1 May 21 '15 at 14:42
• Yes, thanks. I can't count on my fingers anymore how many times I forgot y///. :( – manatwork May 21 '15 at 14:45

# Ruby, 38 bytes

$><<$*.map{|x|x.count'AIUEOaiueo'}*' '


Usage:

mad_gaksha@madlab /tmp/ $ruby t.rb This is the first test case 1 1 1 1 1 2  # JavaScript (ES6), 68 I/O via popup. Run the snippet in Firefox to test. // As requested by OP alert(prompt().replace(/\w+/g,w=>w.replace(/[^aeiou]/ig,'').length)) // Testable f=s=>s.replace(/\w+/g,w=>w.replace(/[^aeiou]/ig,'').length) test=[ ['This is the first test case','1 1 1 1 1 2'] ,['one plus two equals three','2 1 1 3 2'] ,['aeiou AEIOU', '5 5'] ] out=x=>O.innerHTML+=x+'\n' test.forEach(t=>{ r=f(t[0]) out('Test '+ ['Fail','OK'][0|r==t[1]] +'\nInput: '+ t[0] +'\nOutput: '+r +'\nCheck: '+t[1]+'\n') }) <pre id=O></pre> # Rebol - 70 print map-each n split input" "[c: 0 find-all n charset"aeiou"[++ c]c]  ## PowerShell, 35 bytes %{($_-replace"[^aeiou]",'').length}


Kinda boring, but actually competing for once? (PowerShell is case insentitive by default, woo)

• FYI, you needto call this like echo <word> | code, where <word> is your word or phrase – Pureferret Dec 21 '15 at 9:17

# Bash - 85

while read l;do for w in $l;do x=${w//[^aouieAOUIE]};echo -n ${#x}\ ;done;echo;done  ## Explanation • read l read one line from input • for w in l splits the line into words using whitespace separator • x=${w//[^aouieAOUIE]/} deletes all except vowels from the word
• ${#x} is the length of resulting string === number of vowels • Feels somehow overdone. The requirement says the input will contain only letters and spaces. So why you prepared it to process multiple input lines? Without while..do..done would be shorter. Also not needed the last / in the pattern substitution. And a single literal space is shorter escaped than quoted. read l;for w in$l;do x=${w//[^aouieAOUIE]};echo -n${#x}\ ;done;echo – manatwork May 23 '15 at 15:25
• I agree but the rule says 'You can write a full program, or a function that takes input from the stdin and outputs the result.' So I've decided to make the full program. I will edit the solution to save two bytes)) Thanks! – xuesheng May 23 '15 at 15:57

# Julia, 767269 65 bytes

for w=split(readline()) print(count(i->i∈"aeiouAEIOU",w)," ")end


Ungolfed + explanation:

# Read a string from STDIN and split it into words

# For each word in the string...
for w in s
# Get the number of vowels of any case in the word
c = count(i -> i ∈ "aeiouAEIOU", w)

# Print the number of vowels identified
print(c, " ")
end


This will include a single trailing space, which I'm told is legit.

# Mathematica, 95 bytes

Not going to win any contests, but...

Print@StringRiffle[ToString[#~StringCount~Characters@"aeiouAEIOU"]&/@StringSplit@InputString[]]

• Do you know of any online compilers where I could test this? – Spikatrix May 21 '15 at 10:58
• There aren't any, but you can get a free trial here. – LegionMammal978 May 21 '15 at 23:49
• @CoolGuy You can run Mathematica (Wolfram Language) code online if you get a free account here. (Not sure InputString exists in the web interface though, it's a dialog in Mathematica.) – user11030 May 22 '15 at 10:46
• @Calle In Mathematica scripts, InputString takes the next line of input. – LegionMammal978 May 22 '15 at 21:52
• ok, I see. Well still not sure if it will work in the cloud notebook but at least now I know why it's being used for stdin. – user11030 May 22 '15 at 22:03

# golflua, 55 bytes

~@W I.r():l():gm("%w+")_,c=W:g("[aeiou]",'')I.w(c,' ')$ Basic pattern matching of vowels after forced lowercase. An (ungolfed) Lua equivalent would be line=io.read() for word in line:lower():gmatch("%w+") do _,c=word:gsub("[aeiou]",'') io.write(c," ") end  • As an aside, for the Lua version, it'd actually be 2 characters shorter to use gsub('[aeiouAEIOU]','') and skip out on lower(). – Kyle Kanos May 22 '15 at 15:17 ## R, 139 bytes Read/write stdout() is terrible s=function(x,y)strsplit(x,y)[[1]] write(unlist(Map(function(x)sum(x%in%s("AIUEOaiueo","")),Map(s,s(readLines("stdin")," "),"")),),stdout())  • R is not so bad. ;) You can use cat() rather than write(..., stdout()). – Alex A. May 21 '15 at 15:45 # Python 3, 72 bytes Inspired by @randomra's answer. It's the same length slightly longer, but using regex instead of list comprehension. It's also less readable. import re print(*map(len,re.sub("[^aeiou ]","",input(),0,2).split(" ")))  • Save 7 bytes: import re;print(*map(len,re.sub("[^aeiou ]","",input()).split())). (Use newline instead of ; if you want.) – mbomb007 May 22 '15 at 19:11 • @mbomb007 It needs to be case insensitive (2 is the case insensitive flag) and split by " " so there can be 0 length stuff – user34736 May 23 '15 at 7:18 • Ah, my tests weren't extensive enough to notice that. – mbomb007 May 29 '15 at 2:31 # PHP - 94 foreach(explode(' ',$argv[1]) as$d){preg_match_all('/[aeiou]/i',$d,$v);echo count($v[0]).' ';}


Ungolfed version

$a = explode(' ',$argv[1]);
foreach($a as$d) {
preg_match_all('/[aeiou]/i', $d,$v);
echo count($v[0]).' '; }  # Objective-C, 223 bytes -(void)p:(NSString*)s{NSArray*a=[s componentsSeparatedByString:@" "];for(NSString*w in a){int c=0;for(int i=0;i<w.length;i++){if([@"aeiouAEIOU"containsString:[w substringWithRange:NSMakeRange(i,1)]]){c++;}}NSLog(@"%d",c);}}  Not the most compact language, but it works. Uncompressed version: - (void)p:(NSString*)s{ NSArray*a=[s componentsSeparatedByString:@" "]; for (NSString*w in a) { int c=0; for (int i=0;i<w.length;i++) { if ([@"aeiouAEIOU" containsString: [w substringWithRange:NSMakeRange(i, 1)]]) { c++; } } NSLog(@"%d",c); } }  # Matlab, 73 bytes Your challenge is not very clear (but it is interesting). I'm assuming • By "vowel" you mean a, e, i, o, u. • The string does not contain leading or trailing spaces Code: diff(find(regexprep([' ' input('','s') ' '],'[^aeiouAEIOU ]','')==' '))-1  # rs, 50 bytes This doesn't quite count; rs was uploaded around 2 weeks after this was posted. However, evidently this wouldn't win anything anyway, so it's still cool. *[aeiou]/_ (^| )[^_\s]+ |$/ 0
[^_\s0]/
(_+)/(^^\1)


Live demo.

The implementation is rather straightforward:

*[aeiou]/_            Replace all vowels with underscores.
(^| )[^_\s]+ |$/ 0 Replace words that have no vowels with a zero. [^_\s0]/ Remove all other letters. (_+)/(^^\1) Convert the underscore sequences into numbers (e.g. '___' to 3).  # Perl, 60 45 $/=" ";while(<>){$n=()=/[aeiou]/gi;print"$n "


Thanks to kirbyfan64sos for saving me 15 bytes - that really helped!
Note there's an extra space at the end of the output.

• You can remove the call to split by setting adding $/=" ";, and you can shorted the loop prefix to while(<>). With those two changes, the code becomes $/=" ";while(<>){$n=()=/[aeiou]/gi;print"$n "}, saving 14 bytes! – kirbyfan64sos Jun 18 '15 at 19:54

f=interact$unwords.map(show.length).filter(elem"aeiouAEIOU").words  Straightforward implementation, not sure if there is anything to golf here. # KDB(Q), 30 bytes {sum@'lower[" "vs x]in"aeiou"}  # Explanation  " "vs x / split x string by space lower[ ] / lower case in"aeiou" / check vowel sum@' / sum each booleans { } / lambda  # Test q){sum@'lower[" "vs x]in"aeiou"}"This is the first test case" 1 1 1 1 1 2i  # Smalltalk - 66 72 This is in Smalltalk/X; the names for stdin and stdout may be different in squeak/pharo. Stdin nextLine subStrings do:[:w|(w count:[:c|c isVowel])print.' 'print]  In Smalltalk/X (and many other dialects), symbols understand #value:, so it can be abbreviated to 66 chars:  Stdin nextLine subStrings do:[:w|(w count:#isVowel)print.' 'print]  If coded as a function which get the string as argument "s": [:s|s subStrings do:[:w|(w count:#isVowel)print.' 'print]]  Of course, in real code, one would use a utility function "f", which returns a vector of the counts, and print that. However, the output format is then not exactly what the challenge asked for: f := [:s|s subStrings collect:[:w|(w count:#isVowel)]]. (f value: Stdin nextLine) print.  # Python 2, 76 bytes I made this before I saw any other solution, then checked to find two P3 solutions that are shorter :( Darn P2 limitations. print' '.join(sum(y in'aeiouAEIOU'for y in x)for x in raw_input().split())  ## PowerShell, 65 bytes ($input-split'\s'|%{($_-split''-match'a|e|i|o|u').count})-join' '  test by using the pattern below after saving as vowels.ps1 "the quick brown fox" | vowels.ps1  This way it is an actual script and not just a code snippet thereby satisfying constraint: "Input must be consumed from the stdin or command line arguments." # Jelly, 7 bytes Ḳf€ØcL€  Try it online! Found with help from Mr. Xcoder in chat ## Explanation Ḳf€ØcL€ - Main link. Argument: s (a string) e.g. "aeiou AEIOU" Ḳ - Split the input on spaces ["aeiou", "AEIOU"] Øc - Generate the string "AEIOUaeiou" f€ - Filter out consonants from €ach ["aeiou", "AEIOU"] L€ - Length of €ach [5, 5]  If the output must be space-separated, then append a K to the end # SAS, 72 data;infile stdin;file stdout;input c$@@;x=countc(c,'aeiou','i');put x@;

public class a{public static void Main(string[] a){Console.Write(string.Join(" ",Console.ReadLine().Split(' ').Select(x=>x.ToCharArray().Count(y=>"aeoui".ToCharArray().Contains(y)))));}}

• This fails for the third test case. Your program doesn't seem to count AEIOU. – Spikatrix Jun 20 '15 at 6:05