28
\$\begingroup\$

Your program must find all the words in this wordlist that contain all the vowels (a e i o u y). There are easy ways to do this, but I am looking for the shortest answer. I will take any language, but I'd like to see Bash.

Here is an example (could be much improved):

cat wordlist.txt | grep "a" | grep "e" | grep "i" | grep "o" | grep "u" | grep "y"

Your score is the length of the code.

-5 points for counting all occurrences of the word.

Lowest score wins.

\$\endgroup\$
16
  • 11
    \$\begingroup\$ such profile. many picture. very doge. wow. \$\endgroup\$
    – Doorknob
    Feb 15, 2014 at 4:04
  • 2
    \$\begingroup\$ 17 answers and counting! I'd like to see more questions like yours on cg, doc. Often I'll see something interesting here, but don't have the several hours of time needed to produce a decent solution... \$\endgroup\$ Feb 15, 2014 at 19:00
  • 2
    \$\begingroup\$ Yes, but it can't be a language dedicated to finding vowels. \$\endgroup\$
    – TheDoctor
    Feb 15, 2014 at 20:33
  • 1
    \$\begingroup\$ @TheDoctor Shakes fist \$\endgroup\$
    – Jason C
    Feb 15, 2014 at 20:38
  • 2
    \$\begingroup\$ if it has a bonus, then it isn't code-golf. Use code-challenge instead. \$\endgroup\$ Feb 24, 2014 at 19:51

40 Answers 40

15
\$\begingroup\$

GolfScript, 19 characters

n%{'aeiouy'&,6=},n*

Usage:

golfscript vowels.gs < wordlist.txt

Output:

abstemiously
authoritatively
behaviourally
[...]
uninformatively
unintentionally
unquestionably
unrecognisably

If you also want to output the count at the end you can use

n%{'aeiouy'&,6=},.n*n@,

which is four characters longer.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I like it! It may be 4 chars longer, but that gets you a -5 pt bonus \$\endgroup\$
    – TheDoctor
    Feb 15, 2014 at 14:34
11
\$\begingroup\$

Python - 46 characters

filter(lambda x:set(x)>=set("AEIOUY"),open(f))

Readable version: It's already pretty readable :-)

\$\endgroup\$
8
\$\begingroup\$

APL, 21 - 5 = 16

(,≢)w/⍨∧⌿'aeiouy'∘.∊w

Expects to find the list of words as w. Returns a list of the words that contain all the vowels, plus their count. Tested with ngn apl. Here's an example.

Explanation

         'aeiouy'∘.∊w   # generate a truth table for every vowel ∊ every word
       ∧⌿               # reduce with ∧ along the rows (vowels)
    w/⍨                 # select the words that contain all the vowels
(,≢)                    # hook: append to the list its own tally
\$\endgroup\$
8
\$\begingroup\$

Ruby 38

Edit 34: Best so far (from @O-I):

a.split.select{|w|'aeiouy'.count(w)>5} 

Edit 1: I just noticed the question asked for 'y' to be included among the vowels, so I've edited my question accordingly. As @Nik pointed out in a comment to his answer, "aeiouy".chars is one character less than %w[a e i o u y], but I'll leave the latter, for diversity, even though I'm risking nightmares over the opportunity foregone.

Edit 2: Thanks to @O-I for suggesting the improvement:

s.split.select{|w|'aeiouy'.delete(w)==''}

which saves 11 characters from what I had before.

Edit 3 and 3a: @O-I has knock off a few more:

s.split.select{|w|'aeiouy'.tr(w,'')==''}

then

s.split.reject{|w|'aeiouy'.tr(w,'')[1]}

and again (3b):

a.split.select{|w|'aeiouy'.count(w)>5} 

I am a mere scribe!

Here are two more uncompettive solutions:

s.split.group_by{|w|'aeiouy'.delete(w)}['']       (43)
s.gsub(/(.+)\n/){|w|'aeiouy'.delete(w)==''?w:''} (48)

Initially I had:

s.split.select{|w|(w.chars&%w[a e i o u y]).size==6}

s is a string containing the words, separated by newlines. An array of words from s that contains all five vowels is returned. For readers unfamiliar with Ruby, %w[a e i o u y] #=> ["a", "e", "i", "o", "u", "y"] and & is array intersection.

Suppose

s = "abbreviations\nabduction\n"
s.split #=> ["abbreviations", "abduction"] 

In the block {...}, initially

w             #=> "abbreviations"
w.chars       #=> ["a", "b", "b", "r", "e", "v", "i", "a", "t", "i", "o", "n", "s"]
w.chars & %w[a e i o u y] #=> ["a", "e", "i", "o"]
(w.chars & %w[a e i o u y]).size == 6 #=> (4 == 6) => false,

so "abbreviations" is not selected.

If the string s may contain duplicates, s.split.select... can be replaced by s.split.uniq.select... to remove duplicates.

Just noticed I could save 1 char by replacing size==6 with size>5.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ ...size=5 is a bug - should be ...size==5 \$\endgroup\$
    – Uri Agassi
    Feb 15, 2014 at 14:04
  • \$\begingroup\$ Thanks, @Uri, for pointing out the typo in the first line, which I've fixed (not a bug--see line above 'so "abbreviations" is not selected'). \$\endgroup\$ Feb 15, 2014 at 18:00
  • \$\begingroup\$ @CarySwoveland You can save yourself 11 characters by doing this: s.split.select{|w|'aeiouy'.delete(w)==''} \$\endgroup\$
    – O-I
    Feb 15, 2014 at 22:33
  • \$\begingroup\$ That's great, @O-I. I've done an edit and found a place that in the grey cells. \$\endgroup\$ Feb 15, 2014 at 22:46
  • \$\begingroup\$ @CarySwoveland This will save 1 more character: s.split.select{|w|'aeiouy'.tr(w,'')==''}. I'm pretty sure you can get this under 40 characters if you use nil logic and the 'right' String method. Still looking... \$\endgroup\$
    – O-I
    Feb 15, 2014 at 22:58
7
\$\begingroup\$

GolfScript, 20 chars − 5 = 15 points

n%{'aeiouy'\-!},.,+`

Based on Howard's solution, but using a shorter test (\-! saves one char over &,6=), shorter length-appending (.,+ = 3 chars) and shorter output formatting (nobody said the output had to be newline-separated, so ` saves one char over n*).

Here's the output, given the lowercase word list as input (linebreaks inserted for readability):

["abstemiously" "authoritatively" "behaviourally" "consequentially" "counterrevolutionary"
"disadvantageously" "educationally" "encouragingly" "eukaryotic" "evolutionarily"
"evolutionary" "exclusionary" "facetiously" "gregariously" "heterosexuality" "homosexuality"
"importunately" "inconsequentially" "instantaneously" "insurrectionary" "intravenously"
"manoeuvrability" "neurologically" "neurotically" "ostentatiously" "pertinaciously"
"precariously" "precautionary" "questionably" "revolutionary" "simultaneously"
"supersonically" "tenaciously" "uncomplimentary" "uncontroversially" "unconventionally"
"undemocratically" "unemotionally" "unequivocally" "uninformatively" "unintentionally"
"unquestionably" "unrecognisably" 43]

(Ps. Technically, given that the challenge only says the code has to work for this specific input, n%{'aeiouy'\-!},`43 would be one character shorter yet. I consider that cheating, though.)


Explanation:

  • n% splits the input on newlines into an array.
  • { }, is a "grep" operator, executing the code between the braces for each element of the array and selecting those for which it returns a true value.
    • Inside the loop, 'aeiouy'\- takes the literal string aeiouy and removes from it every character found in the candidate word. The ! then logically negates the resulting string, yielding 1 (true) if the string is empty and 0 (false) if it's not.
  • .,+ makes a copy of the filtered array, counts the number of words in it, and appends the result to the original array.
  • Finally, ` un-evals the array, converting it into a string representation of its contents. (Without it, the words in the array would simply be concatenated in the output, yielding an unreadable mess.)
\$\endgroup\$
2
  • \$\begingroup\$ Congrats!! smallest answer!!!! \$\endgroup\$
    – TheDoctor
    Feb 19, 2014 at 13:59
  • \$\begingroup\$ abstemiously and facetiously are the only word with all 6 vowels in order. Just thought I'd share that with you. I found it cool. \$\endgroup\$
    – dberm22
    Sep 14, 2015 at 20:19
6
\$\begingroup\$

Haskell - 67

main=interact$unlines.filter(and.flip map "aeiouy".flip elem).lines
\$\endgroup\$
1
  • 2
    \$\begingroup\$ This is code-golf , you should try to make the code shorter, for instance, by removing whitespace... \$\endgroup\$
    – mniip
    Feb 15, 2014 at 18:04
6
\$\begingroup\$

Ruby - 28 characters (or 27 if y is excluded from vowels)

("ieaouy".chars-s.chars)==[]

The complete command to run is (48 chars):

ruby -nle 'p $_ if ("ieaouy".chars-$_.chars)==[]'

EDIT: replaced puts with p as suggested by @CarySwoveland

\$\endgroup\$
4
  • \$\begingroup\$ Nice one, @Nik. %w[a e i o u] would save 1 char, p for puts, 3 more. \$\endgroup\$ Feb 15, 2014 at 18:55
  • \$\begingroup\$ Thanx, @CarySwoveland! I forgot about p, i rarely use it. As for %w[], if y is included in the set of vowels, the version with chars is still shorter. \$\endgroup\$
    – Nik O'Lai
    Feb 15, 2014 at 19:39
  • \$\begingroup\$ @NikO'Lai "aeiouy".delete(s)=='' might save you a few characters. \$\endgroup\$
    – O-I
    Feb 15, 2014 at 22:44
  • \$\begingroup\$ Very nice! Post it as ur own solution, @O-I. I will upvote it \$\endgroup\$
    – Nik O'Lai
    Feb 15, 2014 at 23:11
4
\$\begingroup\$

AWK - 29

/a/&&/e/&&/i/&&/o/&&/u/&&/y/

To run: Save the lowercase word list to wordlist.txt. Then, do:

mawk "/a/&&/e/&&/i/&&/o/&&/u/&&/y/" wordlist.txt

If your system does not have mawk, awk can be used as well.

You can also run it from a file by saving the program to program.awk and doing mawk or awk -f program.awk.

\$\endgroup\$
1
  • \$\begingroup\$ Choosing right order accelerate the job: '/y/&&/u/&&/i/&&/o/&&/a/&&/e/' !! \$\endgroup\$ Mar 27, 2014 at 20:28
4
\$\begingroup\$

Python, 45 characters

[w for w in open(f) if set('aeiouy')<=set(w)]
\$\endgroup\$
3
\$\begingroup\$

k [22-5=17 chars]

I have renamed the file "corncob_lowercase.txt" to "w"

Count the words [22 chars]

+/min'"aeiouy"in/:0:`w

Output

43

Find all words [25 chars]

x@&min'"aeiouy"in/:x:0:`w

Overall 43 words containing all the vowels (a e i o u y)

Output

"abstemiously"
"authoritatively"
"behaviourally"
..
..
"unintentionally"
"unquestionably"
"unrecognisably"
\$\endgroup\$
0
3
\$\begingroup\$

Javascript/JScript 147(152-5), 158(163-5) or 184(189-5) bytes:

Here is my Javascript and JScript horribly "ungolfyfied" version (164 152 152-5=147 bytes):

function(s,k,z,x,i,c,r){c='aeiouy'.split('');r=[];for(k in s=(s+'').split(/\b/)){i=0;for(z in c)i+=s[k].indexOf(c[z])>=0;i==6&&(r[r.length]=s[k]);}return r;}

function(s,k,z,x,i,c,r){c='aeiouy'.split('');r=[];for(k in s=(s+'').split(/\b/)){i=6;for(z in c)i-=!!s[k].search(c[z]);i&&(r[r.length]=s[k]);}return r;}

Thank you @GaurangTandon for the search() function, which saved me a byte!

RegExp based with HORRIBLE performance, but support both upper and lowercase (163-5=158 bytes):

function(s,k,z,x,i,c,r){c='aeiouy'.split('');r=[];for(k in s=(s+'').split(/\b/)){i=0;for(z in c)i+=RegExp(c[z],'i').test(s[k]);i==6&&(r[r.length]=s[k]);}return r;}

RegExp based with BETTER performance, BUT takes a lot more bytes (189-5=184 bytes):

function(s,k,z,x,i,c,r,l){l=[];r=[];for(z in c='aeiouy'.split(''))l[z]=RegExp(c[z],'i');for(k in s=(s+'').split(/\b/)){i=0;for(z in c)i+=l[z].test(s[k]);i==6&&(r[r.length]=s[k]);}return r;}


This one if just for the fun (175-5 bytes) and won't count as an answer:

function(s,k,z,x,i,c,r){c='aeiouy'.split('');r=[];for(k in s=(s+'').split(/\b/)){i=0;for(z in c)i+=s[k].indexOf(c[z])>=0;i==6&&(r[r[r.length]=s[k]]=1+(r[s[k]]||0));}return r;}

It's based on the 1st answer, but has a 'twist': You can know how many times a word has been found.

You simply do like this:

var b=(function(s,k,z,x,i,c,r){c='aeiouy'.split('');r=[];for(k in s=(s+'').split(/\b/)){i=0;for(z in c)i+=s[k].indexOf(c[z])>=0;i==6&&(r[r[r.length]=s[k]]=1+(r[s[k]]||0));}return r;})('youaie youaie youaie youaie a word');

b.youaie //should be 4

Since that length doesn't have all vowels, it wont be deleted and still would be an answer for the bonus.


How do you call it?

"Simple": You wrap the function inside () and then add ('string goes here'); to the end.

Like this: (function(s,k,z,x,i,c,r){c='aeiouy'.split('');r=[];for(k in s=(s+'').split(/\b/)){i=0;for(z in c)i+=s[k].indexOf(c[z])>=0;i==6&&(r[r.length]=s[k]);}return r;})('a sentence youyoy iyiuyoui yoiuae oiue oiuea');

This example will return an array only with 1 string: yoiuae

I know that this is the worst solution, but works!


Why am i counting -5?

Well, Javascript/JScript arrays have a property (length) in arrays which tells the number of elements that it have.

After being confirmed in the question, the bonus of -5 is for telling the number of words.

Since the number of words is in that property, automatically I have the score of -5.

\$\endgroup\$
2
  • \$\begingroup\$ Might be interested in search() instead of indexOf() saves 1 char. \$\endgroup\$ Feb 17, 2014 at 5:16
  • \$\begingroup\$ Further, As far as I can see, in your shortest version, you do not need the .split() on "aeiouy". JS loops over an array and string in the same way. (Removing it saves you ~10 chars) \$\endgroup\$ Feb 18, 2014 at 11:23
2
\$\begingroup\$

Ruby 39 38

Currently the shortest Ruby entry when counting the whole program including input and output.

Saved a char by using map instead of each:

$<.map{|w|w*5=~/a.*e.*i.*o.*u/m&&p(w)}

Another version, 39 characters with prettier output:

puts$<.select{|w|w*5=~/a.*e.*i.*o.*u/m}

Both programs take input from stdin or as a file name passed as a command line argument:
$ ruby wovels.rb wordlist.txt

It costs 3 extra characters to inclyde y as a wovel.

\$\endgroup\$
5
  • \$\begingroup\$ Anyway to use Enumerable#grep to shorten this? e.g., s.split.grep /a*e*i*o*u*y/ assuming s is a string of the words separated by newlines. \$\endgroup\$
    – O-I
    Feb 15, 2014 at 23:15
  • \$\begingroup\$ @O-I An interesting idea, but it would need some fiddling because the regex has the wovels in a fixed order. That's why i repeat the string 5 times before matching it, with .* between the wovels. \$\endgroup\$
    – daniero
    Feb 15, 2014 at 23:52
  • \$\begingroup\$ Could you clarify? Suppose s = "aeiouy\neiouay\nyuaioe\n". Then s.split.grep /a*e*i*o*u*y/ returns ["aeiouy", "eiouay", "yuaioe"] for me. Testing in pry Ruby 2.0.0. Great solution, by the way. \$\endgroup\$
    – O-I
    Feb 15, 2014 at 23:58
  • \$\begingroup\$ @O-I Oh wow, I assumed that grep used the =~ operator, but apparently it uses ===. My suspicion was that it would also match strings not containing all wovels, because for instance /e*a*i*o*u*y/=~"eioy" works. I really don't understand what the === between a regex and an operator actually does. Great find; I'd suggest you post it as an answer yourself. edit I was right: try with for instance "heya". \$\endgroup\$
    – daniero
    Feb 16, 2014 at 0:26
  • \$\begingroup\$ I think you are right that the regex needs tweaking, though. I'm finding edge cases that don't contain all vowels that are leaking through. Maybe too good to be true. \$\endgroup\$
    – O-I
    Feb 16, 2014 at 0:37
2
\$\begingroup\$

Mathematica (65 or 314)

Two very different approaches, the better one was proposed by Belisarius in the comments to my initial response. First, my brutish effort, which algorithmically generates every possible regular expression that matches a combination of six vowels (including "y"), and then checks every word in the target wordlist against every one of these 720 regular expressions. It works, but it's not very concise and it's slow.

b = Permutations[{"a", "e", "i", "o", "u","y"}]; Table[
 Select[StringSplit[
  URLFetch["http://www.mieliestronk.com/corncob_lowercase.txt"]], 
  StringMatchQ[#, (___ ~~ b[[i]][[1]] ~~ ___ ~~ 
      b[[i]][[2]] ~~ ___ ~~ b[[i]][[3]] ~~ ___ ~~ 
      b[[i]][[4]] ~~ ___ ~~ b[[i]][[5]]~~ ___ ~~ b[[i]][[6]] ~~ ___)] &], {i, 1, 
  Length[b]}]

~320 characters. A few could be saved through using alternate notation, and additional characters are lost preparing the dictionary file as a list of strings (the natural format for the dictionary in Mathematica. Other languages may not need this prep, but Mathematica does). If we omit that step, presuming it to have been handled for us, the same approach can be done in under 250 characters, and if we use Mathematica's built-in dictionary, we get even bigger savings,

Map[DictionaryLookup[(___ ~~ #[[1]] ~~ ___ ~~ #[[2]] ~~ ___ ~~ #[[3]] 
~~ ___ ~~ #[[4]] ~~ ___ ~~ #[[5]]~~ ___ ~~ #[[6]] ~~ ___) .., IgnoreCase -> True] &, 
 Permutations[{"a", "e", "i", "o", "u","y"}]]

Under 200 characters. Counting the number of words found requires only passing the result to Length[Flatten[]], which can be added around either block of code above, or can be done afterwards with, for example, Length@Flatten@%. The wordlist specified for this challenge gives 43 matches, and the Mathematica dictionary gives 64 (and is much quicker). Each dictionary has matching words not in the other. Mathematica finds "unprofessionally," for example, which is not in the shared list, and the shared list finds "eukaryotic," which is not in Mathematica's dictionary.

Belisarius proposed a vastly better solution. Assuming the wordlist has already been prepared and assigned to the variable l, he defines a single test based on Mathematica's StringFreeQ[] function, then applies this test to the word list using the Pick[] function. 65 characters, and it's about 400 times faster than my approach.

f@u_ := And @@ (! StringFreeQ[u, #] & /@ Characters@"aeiouy"); Pick[l,f /@ l]
\$\endgroup\$
5
  • \$\begingroup\$ In 65 chars: f@u_:=And@@(!StringFreeQ[u,#]&/@Characters@"aeiouy");Pick[l,f/@l] Where lis the words list \$\endgroup\$ Feb 15, 2014 at 16:03
  • \$\begingroup\$ That's because you forgot to consider the yas a vowel (as per the OP requirements!) \$\endgroup\$ Feb 15, 2014 at 16:10
  • \$\begingroup\$ @belisarius yep, I notice that after making my comment. I'm checking my results with that fixed. \$\endgroup\$ Feb 15, 2014 at 16:31
  • \$\begingroup\$ @belisarius confirmed -- your solution is much more concise and quicker than mine. Why don't you post it as its own solution? I'll up vote it. \$\endgroup\$ Feb 15, 2014 at 16:44
  • \$\begingroup\$ Thanks! If you like it, edit your answer including it. For me it's all about finding short solutions with the language, not accumulating rep:) \$\endgroup\$ Feb 15, 2014 at 16:47
2
\$\begingroup\$

Perl 6 - 35 characters

Inspired by @CarySwoveland 's Ruby solution:

say grep <a e i o u y>⊆*.comb,lines

This selects (greps) each line that returns True for <a e i o u y> ⊆ *.comb, which is just a fancy way of asking "is the Set ('a','e','i','o','u','y') a subset () of the Set made up of the letters of the input (*.comb)?"

Actually, both <a e i o u y> and *.comb only create Lists: (or (<=) if you're stuck in ASCII) turns them into Sets for you.

To get the number of lines printed, this 42 character - 5 = 37 point script will output that as well:

say +lines.grep(<a e i o u y>⊆*.comb)».say
\$\endgroup\$
2
\$\begingroup\$

C - 96 bytes

 char*gets(),*i,j[42];main(p){while(p=0,i=gets(j)){while(*i)p|=1<<*i++-96;~p&35684898||puts(j);}}

I saved several bytes of parentheses thanks to a fortunate coincidence of operator precedence.

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

Javascript - Score = 124 - 5 = 119 !!!

Edit: 17/02/14

function(l){z=[],l=l.split("\n"),t=0;while(r=l[t++]){o=0;for(i in k="aeiouy")o+=!~r.search(k[i]);if(o==0)z.push(r)}return z}

Big thanks to @Ismael Miguel for helping me cut off ~12 chars!

I removed the fat arrow notation function form because though I have seen it begin used, it doesn't work. No idea why...


To make it work:

Pass all the words separated by newline as an argument to the function as shown below.


Test:

// string is "facetiously\nabstemiously\nhello\nauthoritatively\nbye"

var answer = (function(l){z=[],l=l.split("\n"),t=0;while(r=l[t++]){o=0;for(i in k="aeiouy")o+=!~r.search(k[i]);if(o==0)z.push(r)}return z})("facetiously\nabstemiously\nhello\nauthoritatively\nbye")

console.log(answer);
console.log(answer.length);

/* output ->    
    ["facetiously", "abstemiously", "authoritatively"]
    3 // count
*/

\$\endgroup\$
21
  • \$\begingroup\$ Syntax error at line 1: expected expression, got '>' c=(s,j)=>{k="aeiouy".split(" \$\endgroup\$ Feb 15, 2014 at 19:39
  • 1
    \$\begingroup\$ You can reduce if by moving k="aeiouy".split("") to be inside the for(i in k) loop. Using ; instead of new lines saves some bytes in Windows. And yet, I don't see how it will handle a list of words. And how to make it work. \$\endgroup\$ Feb 15, 2014 at 19:55
  • \$\begingroup\$ @IsmaelMiguel I know it (fat arrow notation) does not work. But since I had seen it being used here so I used it because it saves chars. But I removed it. And I do not understand your tip, thanks though for examining code. Incorporated your bytes tip. And my new program should might clear your both doubts. Thanks for reading. :) \$\endgroup\$ Feb 16, 2014 at 16:38
  • \$\begingroup\$ Instead of k="aeiouy";o=0;for(i in k), try o=0;for(i in k='aeiouy'). and using the saves bytes, you can use them to change o+=RegExp(k[i]).test(s) into o+=RegExp(k[i],'i').test(s), taking up one more byte, but working with both upper and lowercase. \$\endgroup\$ Feb 16, 2014 at 22:32
  • \$\begingroup\$ Updated with better algorithm. Though I now understand your idea, but I do not understand why it works here and not here. Please help! Thanks :) \$\endgroup\$ Feb 17, 2014 at 5:15
2
\$\begingroup\$

Bash + coreutils, 39

eval cat`printf "|grep %s" a e i o u y`

Takes input from stdin.

\$\endgroup\$
3
  • \$\begingroup\$ This looks eligible for the 5-point bonus. \$\endgroup\$ Mar 27, 2014 at 16:36
  • \$\begingroup\$ @GlennRanders-Pehrson That bonus makes no sense to me at all ;-) \$\endgroup\$ Mar 27, 2014 at 16:43
  • \$\begingroup\$ Whether it makes sense or not, you correctly emit 86 lines when processing a file containing two copies of the wordlist. Solutions that sort and only report 43 would not get the bonus, as I understand it. \$\endgroup\$ Mar 27, 2014 at 17:18
2
\$\begingroup\$

sed 29 chars

/y/{/u/{/o/{/i/{/a/{/e/p}}}}}

Order choosed from Letter frequency on wikipedia to speed check.

On my host:

time sed -ne '/a/{/e/{/i/{/o/{/u/{/y/p}}}}}' </usr/share/dict/american-english >/dev/null 
real    0m0.046s

and

time sed -ne '/y/{/u/{/i/{/o/{/a/{/e/p}}}}}'</usr/share/dict/american-english >/dev/null 
real    0m0.030s
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Nice (+1), but I think you need to include "sed -n " in the script, for a count of 36 bytes. \$\endgroup\$ Mar 29, 2014 at 16:53
2
\$\begingroup\$

Bash (grep) - 36 bytes

g=grep;$g y|$g u|$g o|$g i|$g a|$g e

Note the order of vowels tested, least frequent first. For the test case, this runs about 3 times as fast as testing in order a e i o u y. That way the first test removes a larger number of words so subsequent tests have less work to do. Obviously this has no effect on the length of the code. Many of the other solutions posted here would benefit similarly from doing the tests in this order.

\$\endgroup\$
3
  • \$\begingroup\$ Why wc, aren't we finding, not counting? Also, do we count input code into character count? \$\endgroup\$
    – orion
    Mar 7, 2014 at 15:16
  • \$\begingroup\$ I don't really understand the bonus, "-5 points for counting all occurrences of the word". If it really means "reporting all occurrences of the word", that's what my scripts do, without the "|wc". I'm not using any "input code" because grep reads standard input, so "grep" is the "input code" and I counted it. I'll remove the "|wc" now. \$\endgroup\$ Mar 7, 2014 at 15:22
  • \$\begingroup\$ I've disclaimed the bonus. \$\endgroup\$ Mar 29, 2014 at 16:48
1
\$\begingroup\$

D - 196

import std.regex,std.stream;void main(string[]a){auto f=new File(a[1]);while(!f.eof)if(!(a[0]=f.readLine.idup).match("(?=.*a)(?=.*e)(?=.*i)(?=.*o)(?=.*u)(?=.*y).*").empty)std.stdio.writeln(a[0]);}

Un-golfed:

import std.regex, std.stream;

void main( string[] a )
{
    auto f = new File( a[1] );

    while( !f.eof )
        if( !( a[0] = f.readLine.idup ).match( "(?=.*a)(?=.*e)(?=.*i)(?=.*o)(?=.*u)(?=.*y).*" ).empty )
            std.stdio.writeln( a[0] );
}

Usage: C:\>rdmd vowels.d wordlist.txt

wordlist.txt must contain the lowercase list words.

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

Rebol (104 chars)

remove-each w d: read/lines %wordlist.txt[6 != length? collect[foreach n"aeiouy"[if find w n[keep n]]]]

Un-golfed:

remove-each w d: read/lines %wordlist.txt [
    6 != length? collect [foreach n "aeiouy" [if find w n [keep n]]]
]

d now contains list of found words. Here is an example from Rebol console:

>> ; paste in golf line.  This (REMOVE-EACH) returns the numbers of words removed from list

>> remove-each w d: read/lines %wordlist.txt[6 != length? collect[foreach n"aeiouy"[if find w n[keep n]]]]
== 58067

>> length? d
== 43
\$\endgroup\$
1
\$\begingroup\$

Smalltalk (36/57 chars)

'corncob_lowercase.txt' asFilename contents select:[:w | w includesAll:'aeiouy']

to get the count, send #size to the resulting collection. The result collection contains 43 words ('abstemiously' 'authoritatively' ... 'unquestionably' 'unrecognisably')

The code above has 77 chars, but I could have renamed the wordlist file to 'w', so I count the filename as 1 which gives a score of 57.

Is reading the file part of the problem or not? If not (see other examples), and the list of words is already in a collection c, then the code reduces to:

c select:[:w | w includesAll:'aeiouy']

which is 36 chars (with omittable whitespace removed).

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

updated: unnecessary spaces removed

Very slow but in bash (81 chars):

while read l;do [ `fold -w1<<<$l|sort -u|tr -dc ieaouy|wc -m` = 6 ]&&echo $l;done

EDIT: echo $l|fold -w1 replaced with fold -w1<<<$l as suggested by @nyuszika7h

\$\endgroup\$
4
  • \$\begingroup\$ This is code golf, you might want to minify your code a bit more. Start by removing unneeded whitespace. ;) \$\endgroup\$
    – alexia
    Feb 15, 2014 at 15:27
  • \$\begingroup\$ You can further minify the code by using fold -w1<<<$l instead of echo $l|fold -w1. Note: The current code is 84 characters, you shouldn't count the trailing newline. \$\endgroup\$
    – alexia
    Feb 16, 2014 at 10:19
  • \$\begingroup\$ Till today I knew nothing about <<<. Thank you again, @nyuszika7h. Can you tell me, where it is explained. \$\endgroup\$
    – Nik O'Lai
    Feb 16, 2014 at 10:47
  • \$\begingroup\$ mywiki.wooledge.org/BashGuide/… \$\endgroup\$
    – alexia
    Feb 16, 2014 at 10:51
1
\$\begingroup\$

JavaScript - 95 bytes

Here's my golf.

function f(s){return[var a=s.match(/^(?=.*a)(?=.*e)(?=.*i)(?=.*o)(?=.*u)(?=.*y).*/),a.length];}

And I would also like to point out that your golf doesn't seem to find all occurrences of vowels.

Ungolfed:

function countVowels(string) {
  var regex   = /^(?=.*a)(?=.*e)(?=.*i)(?=.*o)(?=.*u)(?=.*y).*/;
  var matches = string.match(regex);
  var length  = matches.length;
  return [matches, length];
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Read the spec more carefully. He's looking for words which---like facetiously---contain all the vowels in a single word. Though he does not insist that they are contained in order as in facetiously. \$\endgroup\$ Feb 15, 2014 at 3:50
  • 1
    \$\begingroup\$ Your regex is wrong. All the look-ahead are effectively checking whether the first character is a vowel. You need (?=.*a) to check whether a is somewhere in the string. \$\endgroup\$ Feb 16, 2014 at 11:34
  • \$\begingroup\$ @dmckee That's why I used lookaheads. They don't require any specific order. \$\endgroup\$
    – Claudia
    Feb 17, 2014 at 4:19
1
\$\begingroup\$

sort + uniq + sed

This one does not match repeated occurrences of a word. It also does not match the letter 'y' if is occurs at the beginning of a word.

sort wordlist.txt | uniq | sed -n '/a/p' | sed -n '/e/p' | sed -n '/i/p' | sed -n '/o/p' | sed -n '/u/p' | sed -nr '/^[^y]+y/p' 
\$\endgroup\$
1
  • \$\begingroup\$ As in your other answer, replace "sort wordlist.txt | uniq" with "sort -u wordlist.txt" to save 4 bytes. \$\endgroup\$ Feb 24, 2014 at 1:28
1
\$\begingroup\$

Bash

Not as short as the OP's , but one line in Bash:

while read p; do if [ $(sed 's/[^aeiouy]//g' <<< $p | fold -w1 | sort | uniq | wc -l) -eq 6 ] ; then echo $p; fi; done < wordlist.txt
\$\endgroup\$
2
  • \$\begingroup\$ You could save four bytes by replacing "sort | uniq" with "sort -u" \$\endgroup\$ Feb 24, 2014 at 1:26
  • \$\begingroup\$ Also you can remove the spaces from " | " and "; " to save a few more bytes \$\endgroup\$ Feb 24, 2014 at 18:55
1
\$\begingroup\$

C# - 170

using System.Linq;class P{static void Main(string[]a){System.Console.Write(string.Join(",",System.IO.File.ReadAllLines(a[0]).Where(w=>"aeiouy".All(c=>w.Contains(c)))));}}

Formatted:

using System.Linq;
class P
{
    static void Main(string[] a) { 
        System.Console.Write(
            string.Join(",", System.IO.File.ReadAllLines(a[0])
                .Where(w => "aeiouy".All(c => w.Contains(c))))); 
    }
}

Not in the mood right now to implement counting puh but should be easy. The path to the (lower-case version of the) wordlist should be passed to the program as first argument:

program.exe D:\foo\bar\corncob_lowercase.txt

Output:

abstemiously,authoritatively,behaviourally,consequentially,counterrevolutionary,
disadvantageously,educationally,encouragingly,eukaryotic,evolutionarily,evolutio
nary,exclusionary,facetiously,gregariously,heterosexuality,homosexuality,importu
nately,inconsequentially,instantaneously,insurrectionary,intravenously,manoeuvra
bility,neurologically,neurotically,ostentatiously,pertinaciously,precariously,pr
ecautionary,questionably,revolutionary,simultaneously,supersonically,tenaciously
,uncomplimentary,uncontroversially,unconventionally,undemocratically,unemotional
ly,unequivocally,uninformatively,unintentionally,unquestionably,unrecognisably

I took the liberty of outputting and comma-separating the words; neither of which is specified in the rules (which state "must find all the words", not how (and IF) to output).

Including count (+output): 192 - 5 = 187

using System.Linq;class P{static void Main(string[]a){var r=System.IO.File.ReadAllLines(a[0]).Where(w=>"aeiouy".All(c=>w.Contains(c)));System.Console.Write(string.Join(",",r)+" "+r.Count());}}

Output:

abstemiously,authoritatively,behaviourally,consequentially,counterrevolutionary,
disadvantageously,educationally,encouragingly,eukaryotic,evolutionarily,evolutio
nary,exclusionary,facetiously,gregariously,heterosexuality,homosexuality,importu
nately,inconsequentially,instantaneously,insurrectionary,intravenously,manoeuvra
bility,neurologically,neurotically,ostentatiously,pertinaciously,precariously,pr
ecautionary,questionably,revolutionary,simultaneously,supersonically,tenaciously
,uncomplimentary,uncontroversially,unconventionally,undemocratically,unemotional
ly,unequivocally,uninformatively,unintentionally,unquestionably,unrecognisably 4
3

(Note the count at the end: 43)

No output ("must find all the words"): 137 - 5 = 132

using System.Linq;class P{static void Main(string[]a){var r=System.IO.File.ReadAllLines(a[0]).Where(w=>"aeiouy".All(c=>w.Contains(c)));}}

(Bending the rules a bitm then again: not really) This finds all the words and the count is available by executing r.Count().

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

C-Sharp

I've never done this before and I'm not exactly sure what the posting procedures are. But this is what i came up with:

185 bytes

Action<string>x=(s=>s.Split('\n').ToList().ForEach(w=>{if("aeiouy".All(v=>w.Contains(v)))Console.Write(w);}));using(var s=new StreamReader(@"C:\corncob_lowercase.txt"))x(s.ReadToEnd());

wordList = a List<string> of all the words.

if you want to display a total:

219 - 5 = 214 bytes

Action<string>x=(s=>{var t=0;s.Split('\n').ToList().ForEach(w=>{if("aeiouy".All(v=>w.Contains(v))){Console.Write(w);t++;}});Console.Write(t);});using(var s=new StreamReader(@"C:\corncob_lowercase.txt"))x(s.ReadToEnd());


Expanded

// init
var words = "";
var vowels = "aeiouy";
var total = 0;

using (var stream = new StreamReader(@"C:\corncob_lowercase.txt"))
{
    // read file
    words = stream.ReadToEnd();

    // convert word to List<string>
    var wordList = words.Split('\n').ToList();

    // loop through each word in the list
    foreach (var word in wordList)

        // check if the current word contains all the vowels
        if(vowels.All (w => word.ToCharArray().Contains(w)))
        {
            // Count total
            total += 1;
            // Output word
            Console.Write(word);
        }

    // Display total
    Console.WriteLine(total);
}
\$\endgroup\$
10
  • \$\begingroup\$ Generally if the question asks for a "program", you should post your complete program including loading/initialization, etc. Great work otherwise! \$\endgroup\$ Mar 28, 2014 at 4:21
  • \$\begingroup\$ Oh ok. So in the minified version i should include everything not just the line that achieves the requirement? I thought it was the latter judging by other answers as they lacked the code to load/read the txt file. \$\endgroup\$
    – mnsr
    Mar 28, 2014 at 4:48
  • \$\begingroup\$ You'll see a variation of approaches, and given the age of the answer curation is likely not to be as strong on new answers, but in general if the question asks for a "program" it should be compilable and runnable as posted. Take the example in the question itself -- that is a complete, executable solution, that stands alone. \$\endgroup\$ Mar 28, 2014 at 4:55
  • \$\begingroup\$ ahh right. well, in that case i've updated the 2 shortened versions to be standalone. \$\endgroup\$
    – mnsr
    Mar 28, 2014 at 5:13
  • \$\begingroup\$ Great! Be sure to update the text of your answer (you mention "without loading/reading") and compute your score. \$\endgroup\$ Mar 28, 2014 at 5:40
1
\$\begingroup\$

vb.net (Score 91 = 96c - 5)*0

*0 +49c min

This creates an enumeration contain all of the words which contain all of the vowels.

Dim r=IO.File.ReadLines(a(0)).Where(Function(w)"aeiou".Intersect(w).Count=5)
Dim c=r.Count
\$\endgroup\$
2
  • \$\begingroup\$ Your program must find all the words in this wordlist. This is a) not a program but a snippet of a program and b) doesn't read/use the wordlist. \$\endgroup\$
    – RobIII
    Mar 29, 2014 at 23:31
  • \$\begingroup\$ @RobIII vb.net has a minimum 49c for a basic console program. The arguments to the program (in this case the wordlist) are the array a. Plus as some others have pointed out it is valid program in LinqPad. \$\endgroup\$ Mar 30, 2014 at 3:08
1
\$\begingroup\$

Mathematica - 136 102

Fold[Flatten@StringCases@## &, 
Flatten@Import@"http://bit.ly/1iZE9kY",
___ ~~ # ~~ ___ & /@ Characters@"aeiouy"]

The shortened link goes to http://www.mieliestronk.com/corncob_lowercase.txt

\$\endgroup\$
2
  • \$\begingroup\$ Save 28 characters with http://bit.ly/1iZE9kY. \$\endgroup\$
    – wchargin
    Feb 15, 2014 at 21:13
  • \$\begingroup\$ Save two characters with Characters["aeiou"] or more if you include y. \$\endgroup\$
    – wchargin
    Feb 15, 2014 at 21:14

Your Answer

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

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