Is it an Odd Word?

28

2

Challenge

Given a single word as input, determine if the word is odd or even.

Odd and Even words

Assume the general rules:

odd + odd = even
even + odd = odd
odd + even = odd
even + even = even

In the alphabet, the odd letters are:

aeiou

And the even letters are:

bcdfghjklmnpqrstvwxyz

The same applies to capital letters (AEIOU are odd and BCDFGHJKLMNPQRSTVWXYZ are even).

You then 'add' each of the letters in the word together. For example, the word cats is equivalent to:

even + odd + even + even

Which simplifies to:

odd + even

Which simplifies further to:

odd

So the word cats is odd.

Examples

Input:  trees
Output: even

Input:  brush
Output: odd

Input:  CAts
Output: odd

Input:  Savoie
Output: even

Input:  rhythm
Output: even

Rules

All input will be a single word which will only contain alphabetical characters.

If the word is odd, output a truthy value. If the word is even, output a falsey value.

Winning

The shortest code in bytes wins.

Beta Decay

Posted 2016-09-20T17:50:13.303

Reputation: 21 478

1Could you add an example of a word without any odd letters. – Hedi – 2016-09-20T18:50:11.650

@Hedi I've added one, rhythm – Beta Decay – 2016-09-20T19:37:24.807

7

Excuse you. Odd Word™ has been trademarked already by JLee. This is an unauthorized use of the term. :P

– Deusovi – 2016-09-20T20:58:10.113

2This is begging for a pure regex submission – Rohan Jhunjhunwala – 2016-09-20T21:19:38.130

2Is the input guaranteed to only contain alphabetical characters? – James – 2016-09-20T23:07:12.567

@DJMcMayhem Whoops, I thought I clarified that :) – Beta Decay – 2016-09-21T06:03:17.410

The answer is no. Only numbers are odd. – still_dreaming_1 – 2016-09-21T13:11:52.720

Got a hint for everybody... The ASCII values of the vowels in question are always odd. No doubt someone will exploit that for a few bytes ;). – Magic Octopus Urn – 2016-09-21T20:46:42.237

Is it possible to arrive at the answer by simply knowing the number of odd and even characters (vowels and consonants)? – rnso – 2016-10-12T15:43:54.080

Answers

7

05AB1E, 6 bytes

lžMÃgÉ

Explanation

l       # convert to lower case
 žMÃg   # count odd letters
     É  # true if odd else false

Try it online!

Emigna

Posted 2016-09-20T17:50:13.303

Reputation: 50 798

18

EXCEL, 79 bytes:

=MOD(SUMPRODUCT(LEN(A1)-LEN(SUBSTITUTE(LOWER(A1),{"a","e","i","o","u"},""))),2)

input:
This function can be placed anywhere EXCEPT A1
Put your word in question into A1.

Output: 0 if even, 1 if odd.

user56309

Posted 2016-09-20T17:50:13.303

Reputation:

13

JavaScript (ES6), 34 41 33 32 bytes

Saved 1 bytes thanks to Arnauld:

s=>~s.split(/[aeiou]/i).length&1
  • Odd word : returns 1
  • Even words : returns 0


Previous solutions:

33 bytes thanks to Arnauld:

s=>s.split(/[aeiou]/i).length&1^1
  • Odd word : returns 1
  • Even words : returns 0

Another way without bitwise operators:

s=>++s.split(/[aeiou]/i).length%2

41 bytes:

(s,a=s.match(/[aeiou]/ig))=>a&&a.length%2
  • Odd word : returns 1
  • Even words with odd letters : returns 0
  • Even words with no odd letters : returns null

42 bytes to return 0 instead of null:

(s,a=s.match(/[aeiou]/ig))=>a?a.length%2:0

34 bytes, breaks on words with no odd letters:

f=s=>s.match(/[aeiou]/ig).length%2

Saved 2 bytes thanks to Shaun H

s=>s.match(/[aeiou]/ig).length%2

Hedi

Posted 2016-09-20T17:50:13.303

Reputation: 1 857

1This method breaks when word has no vowels. That said: f= isn't needed, and calling exec on the regex object is shorter. s=>/[aeiou]/ig.exec(s).length%2 – Shaun H – 2016-09-20T18:27:05.810

I don't have the same result with exec with the g flag. – Hedi – 2016-09-20T18:53:31.410

dammit brain yeah ignore that, f= still isn't needed though – Shaun H – 2016-09-20T18:58:55.387

Could you do s=>s.split(/[aeiou]/i).length&1^1? – Arnauld – 2016-09-20T19:44:45.213

1s=>~s.split(/[aeiou]/i).length&1 is actually one byte shorter. – Arnauld – 2016-09-20T20:51:38.250

Eww, ++...length%2? I'd have written that ...length%2<1. – Neil – 2016-09-20T21:26:36.983

@Hedi how does the logic on this work? I'm trying to make sense of this... – WallyWest – 2016-09-21T06:02:51.243

@WallyWest the split(...).length is the number of gap between odd letters (may be even letters or empty string). If we just did %2 the result would be falsy for odd words and truthy for even words. The ~ inverts the bits of its operand (~x == -x-1) so if x was even ~x is odd. The &1 does the same as %2 (except that negative value %2 gives -0 or -1). – Hedi – 2016-09-21T06:27:09.950

8

Brain-Flak 206 196 192 178 + 3 = 181 bytes

Try it Online!

([]<{({}[((((((()()())){}){}){}){}){}()]){({}[({}())]){({}[({})]){({}[({}()())]){({}[({})]){({}<>)(<>)}}}}}{}{}}><>[[]]<>()()){(({}[<>(())<>()()])){{}({}())((<>)<>)}{}}{}<>({}<>)  

This requires the -c flag to run in ASCII mode adding an extra 3 bytes to the length of the program.

Ungolfed

([]<
{({}[(((((()()()){}){}){}){}){}()])
 {
  ({}[()()()()])
  {
   ({}[()()()()])
   {
    ({}[(()()()){}])
    {
     ({}[(()()()){}])
     {
      ({}<>)
      (<>)
     }
    }
   }
  }
 }
 {}
}
><>[[]]<>)
(<(()()<>)>)<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<{}><>)

Explanation

First store the stack height for future purposes

([]<...>

Then while the stack is not empty (assumes that none of the characters is zero)

{...}

Subtract ninety seven (and store 3 for later optimizations)

({}[((((((()()())){}){}){}){}){}()])

If it is not zero (i.e. not a)

{...}

Subtract 4 (and store 4 for later optimizations)

({}[({}())])

If it is not zero (i.e. not e)

{...}

Subtract 4 (and store 4 for later optimizations)

({}[({})])

If it is not zero (i.e. not i)

{...}

Subtract 6 (and store 6 for later optimizations)

({}[({}()())])

If it is not zero (i.e. not o)

{...}

Subtract 6 (store 6 because the program expects one later)

({}[({})])

If it is not zero (i.e. not u)

{...}

Move the remainder to the other stack and put a zero on the active stack to escape all of the ifs

({}<>)(<>)

Once all of the ifs have been escaped remove the zero and the six

{}{}

Once all the characters have been processed subtract the height of the offset from the originally stored height.

...<>[[]]<>)

Mod by two

{(({}[<>(())<>()()])){{}({}())((<>)<>)}{}}{}<>({}<>) 

Post Rock Garf Hunter

Posted 2016-09-20T17:50:13.303

Reputation: 55 382

I think -c is only +1 byte since ever Perl answer also only adds 1 byte / flag. – ThreeFx – 2016-09-21T06:10:07.397

1@ThreeFx That's because perl -pe'code' is only one byte longer than perl -e'code'. – Dennis – 2016-09-21T07:07:14.337

8

C, 42 bytes

f(char*s){return*s&&2130466>>*s&1^f(s+1);}

This works with GCC 4.x on a x86-64 CPU. Results may vary with different setups.

Test it on repl.it.

At the cost of 5 more bytes, undefined behavior can be avoided, so the code should work as long as ints are at least 32 bits wide.

f(char*s){return*s&&2130466>>(*s&31)&1^f(s+1);}

How it works

Modulo 32, the character codes of all odd letters are 1, 5, 9, 15, and 21. 2130466 is the 32-bit integer that has set bits at these positions and unset bits at all others.

When f is called on a string, it first checks if the first character of the string is a null byte (string terminator). If it is, *s yields 0 and f returns 0. Otherwise, *s yield the character code of a letter and the right argument of the logical AND (&&) is executed.

For >>, GCC generates a shift instruction. On a x86-64 CPU, the corresponding instruction for a 32-bit integer ignores all but the lower 5 bits of the right argument, which avoids reducing *s modulo 32. The right shift and the following bitwise AND with 1 extracts the bit of 2130466 that corresponds to the letter, which will be 1 if and only if the letter is odd.

Afterwards, we increment the pointer s (effectively discarding the first letter), call f recursively on the beheaded string, and take the bitwise XOR of the result from above and the result of the recursive call.

Dennis

Posted 2016-09-20T17:50:13.303

Reputation: 196 637

Great bit wise work! – Keyu Gan – 2016-09-21T17:42:31.343

erees Return 0 in Ideone, is it right? – RosLuP – 2016-09-21T18:40:59.633

@RosLuP No, that's not correct. It works on my computer and on repl.it though (possibly because the version of GCC is quite different).

– Dennis – 2016-09-21T18:49:24.240

Yeah, it's definitely the compiler. With clang 3.7, it works on Ideone as well.

– Dennis – 2016-09-21T18:57:14.327

7

sed 44 (42 + 1 for -n) 43

-1 thanks to Neil

s/[aeiou][^aeiou]*[aeiou]//gi
/[aeiou]/Ico

Prints o for odd and nothing for even

Riley

Posted 2016-09-20T17:50:13.303

Reputation: 11 345

s/[aeiou][^aeiou]*[aeiou]//gi might save you a byte, if I've counted correctly. – Neil – 2016-09-20T21:23:50.800

@Neil Yep! I wish sed could do non-greedy search. – Riley – 2016-09-20T21:44:06.163

7

Python, 41 bytes

lambda s:sum(map(s.count,"aeiouAEIOU"))%2

xnor

Posted 2016-09-20T17:50:13.303

Reputation: 115 687

6

Haskell, 38 37 bytes

odd.length.filter(`elem`"aeiouAEIOU")

Thanks to Angs for one byte!

BlackCap

Posted 2016-09-20T17:50:13.303

Reputation: 3 576

Truthy for odd, so you have to use odd instead of even. Saves one byte! – Angs – 2016-10-12T08:55:22.873

@Angs clever :) – BlackCap – 2016-10-13T07:16:45.953

6

Jelly, 13 12 11 bytes

-1 byte thanks to @Luis Mendo (use to replace %2)
-1 byte thanks to @Dennis (use a string compression)

Œlf“¡ẎṢɱ»LḂ

All test cases are at TryItOnline

How?

Œlf“¡ẎṢɱ»LḂ - Main link takes an argument - s
Œl          - lowercase(s)
   “¡ẎṢɱ»   - string of lowercase vowels (compression using the words a and eoui)
  f         - filter - keep only the vowels
         L  - length - the number of vowels
          Ḃ - Bit (modulo 2)

Non-competing, 5 bytes (since I just added the function Øc)

fØcLḂ

Test cases also at TryItOnline

Same as above, but Øc yields the Latin alphabet's vowels, 'AEIOUaeiou'

Jonathan Allan

Posted 2016-09-20T17:50:13.303

Reputation: 67 804

1I think you can replace %2 by – Luis Mendo – 2016-09-20T21:11:59.910

7euoi is a cry of impassioned rapture in ancient Bacchic revels, so you can use the dictionary and get the vowels as “¡ẎṢɱ». – Dennis – 2016-09-20T21:53:01.360

@Dennis - LOL of course! – Jonathan Allan – 2016-09-20T21:59:33.087

2@Dennis How exactly does that work? Is it just base-compression to get the index of a word in a giant dictionary? Where does the 'a' come from? – James – 2016-09-21T00:32:03.513

2

@DJMcMayhem it's a base 250 compression using a dictionary (which I believe was just taken from Dennis's computer) with separation between short (less than 6 char) and long words. Some code to automate the process of making compressed strings was written by Lynn. The unused 6 bytes are Jelly's string identifying characters “”«»‘’ (there is also which is for a two-char string, but that is used within compressed strings).

– Jonathan Allan – 2016-09-21T01:04:25.143

6

Python, 42 bytes

lambda s:sum(c in"aeiouAEIOU"for c in s)%2

Not a whole lot to explain here. An unnamed function that returns 0 or 1.

James

Posted 2016-09-20T17:50:13.303

Reputation: 54 537

6

Brain-Flak, 524, 446, 422 bytes

{(<((((()()()()){}){}){}<>)>)<>{({}[()])<>(({}[({})]())){{}(<({}({}))>)}{}<>}{}<>([(((({}<{}<>>))))]()){(<{}>)<>({}[()])<>}<>({}())<>{}([{}]()()()()()){(<{}>)<>({}[()])<>}<>({}())<>{}(((()()())){}{}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}(((()()()()())){}{}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}((((()()()){}())){}{}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}}(<(()())>)<>{({}[()])<>(({}[({})]())){{}(<({}({}))>)}{}<>}{}<>({}<{}<>>)

Try it online!

Ungolfed, more readable version:

{((((()()()()){}){}){})(<({}<>)>)<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<{}><>)((((({})))))
(())
({}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}
(()()()()())
({}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}
(()()()()()()()()())
({}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}
(()()()()()()()()()()()()()()())
({}[{}]){(<{}>)<>({}[()])<>}<>({}())<>{}
(()()()()()()()()()()()()()()()()()()()()())
({}[{}])
{(<{}>)<>({}[()])<>}<>({}())<>{}}<>(()())(<({}<>)>)<>{({}[()])<>(({}()[({})])){{}(<({}({}))>)}{}<>}{}<>({}<{}><>){{}([()])
(<><>)}({}{}())

James

Posted 2016-09-20T17:50:13.303

Reputation: 54 537

The Ungolfed version doesn't seem to work (can't fit TIO link in comment ;_;) – Post Rock Garf Hunter – 2016-09-21T00:49:28.427

6"more readable" 'nough said – Rohan Jhunjhunwala – 2016-09-21T00:52:44.023

4

Python 3, 53 Bytes

This can probably be golfed further:

lambda n:[x in 'aeiou' for x in n.lower()].count(1)&1

L. Steer

Posted 2016-09-20T17:50:13.303

Reputation: 57

Remove spaces between in and 'aeiou' and for, and use sum to save 8 bytes: lambda n:sum(x in'aeiou'for x in n.lower())&1 (although as you can see from DJMcMayhem's post using all ten vowels is also shorter) – Jonathan Allan – 2016-09-20T20:41:42.143

1Thanks for the tips! I noticed the extra spaces a little bit after posting, but in all honesty, @DJMcMayhem and I had identical approaches with his being the best version I can imagine for a Python solution. I didn't know about the sum() command before this golf so once again I learned something! Have a nice day :) – L. Steer – 2016-09-21T02:48:08.300

4

C 52 bytes

h(o){o=strpbrk(o,"aeiouAEIOU");return o?1^h(o+1):0;}

the main and the result:

main()
{int   k;
 char *a[]={"trees","brush","CAts","Savoie","rhythm", 0};

 for(k=0;a[k];++k)
     printf("[%s]=%s\n", a[k], h(a[k])?"odd":"even");
}

/*
91
[trees]=even
[brush]=odd
[CAts]=odd
[Savoie]=even
[rhythm]=even

*/

RosLuP

Posted 2016-09-20T17:50:13.303

Reputation: 3 036

i try to use int as pointers but it not compile where the use of inirection *... the solution printed first here was wrong... – RosLuP – 2016-09-21T15:28:04.700

h(o){return~-o?1^h(1+strpbrk(o,"aeiouAEIOU")):1;} saves 3 bytes. – Dennis – 2016-09-21T16:52:19.397

s;h(o){s=~-o?1^h(1+strpbrk(o,"aeiouAEIOU")):1;} the result is in the global variable s... – RosLuP – 2016-09-21T18:56:10.863

Unfortunately, that's not allowed. Functions have to be reusable, and this will break if you use it more than once. Also, saving the output in a variable is not allowed, unless you take the location as user input. – Dennis – 2016-09-21T19:11:22.340

I think in this case reuse is possible becausr the start value of s now is not important...ok ok now i think something can go wrong... Thanks – RosLuP – 2016-09-21T19:19:26.943

Unfortunately, storing the output in a variable is not considered a valid form of output. The code I proposed is exactly as long as yours and complies with our rules for I/O.

– Dennis – 2016-09-21T19:28:57.543

3

Pyth, 14 bytes

%l@"aeiou"rQ02

Try it Online!

Explanation:

  @"aeiou"       Grab only the vowels
          rQ0      From lowercased input
 l                 Get the length of this
%            2     And mod 2 to check for oddness

Steven H.

Posted 2016-09-20T17:50:13.303

Reputation: 2 841

3

Ruby, 30 bytes

->w{w.scan(/[aeiou]/i).size%2}

m-chrzan

Posted 2016-09-20T17:50:13.303

Reputation: 1 390

3

Vim, 32, 31, 29 keystrokes

:s/[^aeiou]//gi
C<C-r>=len(@")%2<cr>

Since the V interpreter is backwards compatible, you can try it online! right here.

One Three bytes saved thanks to m-chrzan!

James

Posted 2016-09-20T17:50:13.303

Reputation: 54 537

1Can you do s/.../gi instead of s/\c.../g? – m-chrzan – 2016-09-20T18:46:19.303

@m-chrzan Woah, awesome tip. Thanks! – James – 2016-09-20T18:48:22.940

Also, '<C-r>"' -> @". – m-chrzan – 2016-09-20T18:57:00.783

@m-chrzan Wow, thanks. You should consider posting on the vim tips thread. I bet you'd have some useful ones.

– James – 2016-09-20T19:00:12.670

1I found out about @" 15 minutes ago. The best vim tip I have is to use :help foo and / the documentation :P. – m-chrzan – 2016-09-20T19:10:46.633

2Well, since we're talking about golf, :h foo is shorter. :P – James – 2016-09-20T19:11:40.003

3

Java, 73

boolean f(String s){return s.replaceAll("(?i)[^aeiou]","").length()%2>0;}

saw a couple other java answers, otherwise wouldn't have shared. Thanks to Phaeze for saving a byte.

dpa97

Posted 2016-09-20T17:50:13.303

Reputation: 151

1I think you can save a byte with %2>0 – None – 2016-09-20T22:41:04.600

3

dimwit, 14 bytes (non-competing)

ar[aeiou]}et}T

I thought this would be a fun, simple challenge to start with for a new language.

Explanation

  • a - push a new array to the matrix
  • r[aeiou]} - count occurrences of all values matching the regex "[aeiou]" in the first array (since the first array contains the input), ignoring case, and push that value to the end of the last array.
  • e - if the last number in the last array is even (which we set to the number of occurrences), perform the next operations up until a closing bracket ("}")
  • t - stop execution, clear the matrix, and set the first value to be false
  • } - end of e code block
  • T - stop execution, clear the matrix, and set the first value to be true

Try it online!

Use the Input field to enter the word.

I'll soon add documentation...

MCMastery

Posted 2016-09-20T17:50:13.303

Reputation: 783

2

PowerShell v2+, 45 42 bytes

($args[0]-replace'[^aeiouAEIOU]').Length%2

Takes input $args[0], sends it through -replace to remove all non-vowel characters, takes the resulting .length, and %2 to check whether it's odd/even.

Examples

PS C:\Tools\Scripts\golfing> 'trees','brush','CAts','Savoie','rhythm'|%{"$_ --> "+(.\is-it-an-odd-word.ps1 $_)}
trees --> 0
brush --> 1
CAts --> 1
Savoie --> 0
rhythm --> 0

AdmBorkBork

Posted 2016-09-20T17:50:13.303

Reputation: 41 581

2

Octave, 34 bytes

@(s)mod(nnz(~(s'-'aeiouAEIOU')),2)


s'-'aeiouAEIOU'    % Creates a 2D-matrix where each of the odd letters are 
                   % subtracted from the string s
~(s'-'aeiouAEIOU') % Negates that array, so the all zero elements become 1
nnz( .... )        % Counts all the non-zero elements (the odd letters)
mod(nnz( ....),2   % Takes this sum modulus 2

This is 6 bytes shorter than the traditional approach using ismember, @(s)mod(sum(ismember(s,'aeiouAEIOU')),2), and two bytes shorter than the regex approach: @(s)mod(nnz(regexpi(s,'[aeiou]')),2).

Test it here.

Stewie Griffin

Posted 2016-09-20T17:50:13.303

Reputation: 43 471

2

Java 7, 88

boolean f(char[]s){int x=0;for(char c:s)if("aeiouAEIOU".indexOf(c)>=0)++x;return x%2>0;}

Ungolfed:

  boolean f(char[] s) {
    int x = 0;
    for (char c : s) {
      if ("aeiouAEIOU".indexOf(c) >= 0) {
        ++x;
      }
    }
    return x % 2 > 0;
  }

user18932

Posted 2016-09-20T17:50:13.303

Reputation:

2

J, 20 bytes

2|+/@e.&'aeiouAEOIU'

Straight-forward approach

Explanation

2|+/@e.&'aeiouAEOIU'  Input: string S
     e.&'aeiouAEOIU'  Test each char in S for membership in 'aeiouAEOIU'
  +/@                 Sum those values
2|                    Take it modulo 2 and return

miles

Posted 2016-09-20T17:50:13.303

Reputation: 15 654

Haha, I just posted a J answer (now deleted) 1 byte longer than this. Nice job! – Conor O'Brien – 2016-09-21T01:01:42.263

Where is the command for "take input"? – RosLuP – 2016-09-22T05:51:18.570

@RosLuP This is a verb (function) that takes a single argument as input. J uses tacit programming so commands are chained together and pass values implicitly – miles – 2016-09-22T06:12:14.690

2

C# 64 62 56 50 Bytes

s=>1>s.Split("aeiouAEIOU".ToCharArray()).Length%2;
  • We are already using linq, so Contains saves 2 bytes over IndexOf
  • Using the method overload of Count saves 6 bytes
  • Thanks to @Milk for suggesting a neat method and saving 6 more bytes

An anonymous function that takes a string and counts the odd letters then returns true if there is an odd number of them or false if there is not.

This new solution splits the string on any of the characters in the given char array. The mechanics of this flip the meaning of the %2 result; 0 is now odd and 1 even hence the 1>.

Try it online here!

user19547

Posted 2016-09-20T17:50:13.303

Reputation:

It's only 50 bytes to use string.Split() to count the vowels and you don't need LINQ. s=>1>s.Split("aeiouAEIOU".ToCharArray()).Length%2; – milk – 2016-09-21T00:11:21.190

@milk Thanks for that, very neat solution. – None – 2016-09-22T16:12:50.077

2

Japt, 7 bytes

1&Uè"%v

Test it online! Outputs 1 for odd, 0 for even.

How it works

         // Implicit: U = input string
  Uè     // Count the number of matches of the following regex in the input:
    "%v  //   /[AEIOUaeiou]/g
1&       // Take only the first bit (convert 1, 3, 5, etc. to 1, and others to 0)
         // Implicit output

ETHproductions

Posted 2016-09-20T17:50:13.303

Reputation: 47 880

2

PHP, 41 bytes

<?=count(spliti("[aeiou]",$argv[1]))%2-1;

This outputs -1 for truthy and 0 for falsey.

user59178

Posted 2016-09-20T17:50:13.303

Reputation: 1 007

2

Mathematica, 44 bytes

OddQ@StringCount[#,Characters@"aeiouAEIOU"]&

Gives True for an odd string and False for an even one.

Julien Kluge

Posted 2016-09-20T17:50:13.303

Reputation: 283

1+1 to any man or woman learning mathematica – Magic Octopus Urn – 2016-09-21T21:01:39.747

2

q, 29 bytes

{mod[sum x in "aeiouAEIOU";2]}

Liam Baron

Posted 2016-09-20T17:50:13.303

Reputation: 131

1

Clojure, 38 bytes

#(rem(count(re-seq #"(?i)[aeiou]"%))2)

Try it online!

This anonymous function outputs 1 for odd and 0 for even.

Explanation

#"(?i)[aeiou]" ; This is a regular expression that matches a capital or lowercase vowel.
re-seq ; Returns a lazy sequence that contains all of the regex's matches from the input string.
count ; Returns the length of that sequence.
rem ; Returns the remainder when that length is divided by 2

TheGreatGeek

Posted 2016-09-20T17:50:13.303

Reputation: 111

1

Brachylog, 11 bytes

ḷ{∈Ṿ&}ˢl%₂1

Try it online!

The predicate succeeds if the input is odd and fails if it is even.

       l       The number of letters
ḷ              in the lowercased input
 {  &}ˢ        which are
  ∈            members of
   Ṿ           "aeiou"
        %₂     mod 2
          1    is equal to 1.

Unrelated String

Posted 2016-09-20T17:50:13.303

Reputation: 5 300

1

Java (JDK), 53 52 51 bytes

s->{return(s+"#").split("(?i)[AEIOU]").length%2<1;}

Try it online!

Edit: Saved a byte 2 bytes thanks to @JonathanFrech

Sara J

Posted 2016-09-20T17:50:13.303

Reputation: 2 576

1return 1>(... to return(...<1 possibly? – Jonathan Frech – 2019-03-03T15:45:25.360

1Also, could you not use (?i)[aeiou] instead of [aeiouAEIOU]? – Jonathan Frech – 2019-03-03T15:53:09.340

1

Bash, 36 bytes

x=${1,,//[aeiou]/}
((1&${#1}&${#x}))

Try it online!

Zsh, 30 bytes

((1&$#1&${#${1:l}//[aeiou]/}))

Try it online!

Accepts input as its first argument. Exits with nonzero if even, exits zero if odd.

We barely beat out the bash+coreutils solution!

x=${1,,//[aeiou]/}  # lowercase first argument, then remove all [aeiou]
((1&${#1}&${#x}))
  1&     &          # bitwise-and 1 with
    ${#1} ${#x}     # length of first parameter and length of stripped parameter
((             ))   # if nonzero, exit 0 (truthy in shell)

The Zsh solution is very similar, but uses the ability to nest parameter expansions to save an assignment.

GammaFunction

Posted 2016-09-20T17:50:13.303

Reputation: 2 838

1

Retina, 19 bytes

Mi`[aeiou]
[13579]$

Try it online! (The first line enables a linefeed-separated test suite.)

The first line counts the vowels in the input. The second line checks that the result is odd.

Martin Ender

Posted 2016-09-20T17:50:13.303

Reputation: 184 808

1

MATL, 8, 7 bytes

13Y2mso

Try it online!

Explanation:

13Y2    % Push the string 'aeiouAEIOU', a predefined literal. 
    m   % For each char of the input that is in that string, push a one. For every other element, push a zero.
     s  % Sum this array
      o % Mod 2

James

Posted 2016-09-20T17:50:13.303

Reputation: 54 537

1

Pyke, 10 bytes

l1~Vm/s 2%

Try it here!

Blue

Posted 2016-09-20T17:50:13.303

Reputation: 26 661

1

Actually, 17 bytes

Golfing suggestions welcome. Try it online!

ù╝"aeiou"`╛c`MΣ1&

Ungolfing

                    Implicit input s.
ù╝                  Add s.lower() to register 1.
  "aeiou"`  `M      Push the string "aeiou" and map the following function over it.
          ╛         Push register 1 to stack.
           c        Count the occurrences of "a", then "e", etc.
              Σ     Sum the counts of these occurrences.
               1&   x&1 == x%2.
                    Implicit return.

Sherlock9

Posted 2016-09-20T17:50:13.303

Reputation: 11 664

You don't have to output the actual words even and odd. Anything that is false and true in your language qualifies – Ton Hospel – 2016-09-20T19:12:18.810

Ah. Thanks @TonHospel. I had not reread the specification since I first saw in chat. Will edit my answer shortly – Sherlock9 – 2016-09-20T19:13:39.373

1

Perl, 18/19 bytes

Includes +1 for -p

Give input on STDIN, prints 0 for even, 1 for odd

#!/usr/bin/perl -p
$_=1&lc=~y;aeiou;

Must be put in a file, but the file must not have a final newline giving 18 bytes. This is admittedly abusing the perl counting rules a bit since this actually doesn't work when run in a -e commandline which implicitely adds a final \n which makes the program not work. So more honest but 19 bytes is:

#!/usr/bin/perl -p
$_=1&lc=~y;aeiou;;

Ton Hospel

Posted 2016-09-20T17:50:13.303

Reputation: 14 114

1

CJam, 18 17 bytes

0lel"aeiou"f{&,^}

Try it online!

Explanation

0                 e# Push 0
 l                e# Read line from input
  el              e# Convert to lowercase
   "aeiou"        e# Push this string
          f{   }  e# Map code block to each char of the input and the string "aeiou"
            &     e# Set intersection of each input char with the "aeiou". The result
                  e# is either that char or the empty string
             ,    e# Length. Gives 0 or 1
              ^   e# Binary XOR. Uses the initial 0 the first time
                  e# Implicitly display

Luis Mendo

Posted 2016-09-20T17:50:13.303

Reputation: 87 464

lel_"aeiou"--,1& saves a byte. – Dennis – 2016-09-21T00:20:14.870

@Dennis Thanks! That's very clever. But it's a significantly different approach, you should post it yourself – Luis Mendo – 2016-09-21T07:18:07.683

1

R, 164 bytes

I'm sure this can be done better, but it's still good practice.

f<-function(w){
l<-"aeiouAEIOU"
c<-0
for(i in 1:10){
for(j in 1:nchar(w)){
if(substr(l,i,i)==substr(w,j,j)){c<-c+1}}}
if(c%%2==0){print("F")}else{print("T")}}

input/output

> f("trees")
[1] "F"
> f("brush")
[1] "T"
> f("CAts")
[1] "T"
> f("Savoie")
[1] "F"
> f("rhythm")
[1] "F"

"F" for false and "T" for true.

Arwalk

Posted 2016-09-20T17:50:13.303

Reputation: 31

Welcome to codegolf fellow R-user. May I recommend the following approach rather to reduce it to 117 bytes: function(w){a=substr;l="aeiouAEIOU";c=0;for(i in 1:10){for(j in 1:nchar(w))if(a(l,i,i)==a(w,j,j))c=c+1};cat(c%%2!=0)}. In other words, use = for assignment rather than <-, removed some unnessecary {...} as well, aliasing the substr() function to a since you use it twice. Finally instead of printing out a T or F string, just print the logical equivalents instead with the cat() function rather than print. – Billywob – 2016-09-21T08:26:07.747

Also, I would recommend to check out my vectorized solution here. There I also use readline() rather than defining a full function which is shorter when only one input is required.

– Billywob – 2016-09-21T08:28:37.813

Thanks so much, I will look at all of your suggestions Billywob. – Arwalk – 2016-09-22T02:07:27.730

1

Bash + coreutils, 37 bytes

bc<<<!`sed s:[^aeiou]::ig\;q|wc -m`%2

The input word is taken from STDIN. Output is 1 if the word is odd, or 0 if it is even.

Explanation:

       sed s:[^aeiou]::ig\;q     # remove even letters from input and exit sed
       |wc -m                    # count remaining chars (odd letters + 1 for \n)
bc<<<!`                     `%2  # apply mod 2 and invert the boolean result

Run example:

me@LCARS:/PPCG$ ./odd_word.sh
trees
0

seshoumara

Posted 2016-09-20T17:50:13.303

Reputation: 2 878

1

Batch, 132 bytes

@echo off
set/ps=
set s=%s%%s:a=%%s:e=%%s:i=%%s:o=%%s:u=%
:l
if "%s%"=="" exit/b0
if "%s:~1%"=="" exit/b1
set s=%s:~2%
goto l

Takes input on STDIN, exits with ERRORLEVEL equal to 1 if the word is odd, 0 if it is even. Works by multiplying all the vowels by five and other letters by six, then calculating the parity of the resulting length.

Neil

Posted 2016-09-20T17:50:13.303

Reputation: 95 035

1

Turtlèd, 91 65 64 52 47 67 bytes

More bytes because now takes case insensitive input

Changed approach again

does * for even, else o for odd

(trailing space)

!-u[*+.(a,)(e,)(i,)(o,)(u,)(A,)(E,)(I,)(O,)(U,)(*d(*'ou)(o'*u))_]' 

It goes through input, writing it down on one square, each time there is a vowel, it moves down, flips the state of a the output cell, continues until EOF of input, then removes the cell where it writes down all the characters.

Destructible Lemon

Posted 2016-09-20T17:50:13.303

Reputation: 5 908

1

Lua, 47 44 43 Bytes

print(#arg[2]:gsub('[^aeiouAEIOU]','')%2>0)

Takes the input via the command line, replaces all non-vowels with nothing, (removes them), prints true if the length of that is odd, false otherwise.

Old submission

_,n=arg[2]:gsub('[aeiouAEIOU]','')print(n%2~=0)

ATaco

Posted 2016-09-20T17:50:13.303

Reputation: 7 898

1

R, 78 bytes

Solution is based on counting the number of vowels:

s=strsplit;w=s(readline(),"")[[1]];v=s("aeiouAEIOU","")[[1]];sum(w%in%v)%%2!=0

Explanation

Unfortunately most functions in R relating to strings work on vectors of characters rather than full strings, thus the solution converts input into a vector using strsplit and checks whether this contains any vowels => sum the number of vowels and check if odd/even.

Also I found that using v=s("aeiouAEIOU","")[[1]] was shorter than manually inputting a vector of vowels which would have worked if only lower or upper case letters were used.

Billywob

Posted 2016-09-20T17:50:13.303

Reputation: 3 363

1

T-SQL (SQL Server 2014), 217 bytes

Golfed

declare @ table(a char)declare @i int=1while @i<=len(@a)begin insert into @ values(SUBSTRING(@a,@i,1))set @i=@i+1 end select count(*)%2from @ where a in('a','e','i','o','u')

Usage

First declare the variable @a as a char of some sort and assign the input like so

declare @a varchar(max) = 'CAts'

Output will either be 1 for odd, or 0 for even

Ungolfed

declare @input varchar(max) = 'rhythm'

declare @temp table ( letter char(1) ) -- table to hold each letter of the word

declare @i int = 1

while @i <= len(@input) -- split each letter, and each row in @temp will have one letter
begin
    insert into @temp values (SUBSTRING(@input, @i, 1))
    set @i = @i + 1
end

-- count the vowels and mod two to get if there's an even number of vowels or an odd number
select count(*) % 2
from @temp
where letter in ('a', 'e', 'i', 'o', 'u') -- use sql's case insensitive strings

Brian J

Posted 2016-09-20T17:50:13.303

Reputation: 653

1

Groovy (39 Bytes)

{s->s.collect{/aeiou/=~it?1:0}.sum()%2}

https://groovyconsole.appspot.com/script/5195711326978048

Magic Octopus Urn

Posted 2016-09-20T17:50:13.303

Reputation: 19 422

1

Julia, 53 Bytes

f(s)=sum(map(x->x in ["aeiouAEIOU"...]?1:2,[s...]))%2

replace odd characters with 1 and even characters with 2, then sum up. if the sum is even, then the word is even.

nyro_0

Posted 2016-09-20T17:50:13.303

Reputation: 281

1

O, 27 bytes

Q_e\'a-'e-'i-'o-'u-e\;-e01?

kirbyfan64sos

Posted 2016-09-20T17:50:13.303

Reputation: 8 730

1

PHP, 91 bytes

foreach(str_split($argv[1])as$c)$n+=substr_count("AEIOU",strtoupper($c));if($n%2==0)echo 1;

Outputs 1 for even word, empty for odd word.

Test online

Testing code:

$wa = array('trees','brush','CAts','Savoie','rhythm');
foreach ($wa as $w) {
    $n = 0;
    foreach(str_split($w) as $c) 
        $n+=substr_count("AEIOU",strtoupper($c));
    if ($n%2==0) echo 1;
}

Test online

Mario

Posted 2016-09-20T17:50:13.303

Reputation: 3 043

0

Python 2, 41 bytes

lambda s:sum(map(s.count,"aAeEiIoOuU"))%2

Try it online!

Returns 0 for even, and 1 for odd.

Explanation: Counts how many total odd letters are in the word, and returns whether that number is even (0) or odd (1).

Triggernometry

Posted 2016-09-20T17:50:13.303

Reputation: 765

0

Japt v2.0a0, 5 bytes

è\v u

Try it

Shaggy

Posted 2016-09-20T17:50:13.303

Reputation: 24 623

0

Kotlin, 32 bytes

0 is false, 1 is true.

{it.count{it in "aAeEiIoOuU"}%2}

Try it online!

snail_

Posted 2016-09-20T17:50:13.303

Reputation: 1 982

0

Pepe, 131 bytes

rEeEEeeeeErEeEEeeEeErEeEEeEeeErEeEEeEEEErEeEEEeEeEREeEeeeeeEREeeEeeeeeREEREEEerrEEEEEerEEeeREEEEReeReReREEeREEEEeeeRREeeeReEEEEReEE

Ouputs 0 for odd, 1 for even.

Try it online!

u_ndefined

Posted 2016-09-20T17:50:13.303

Reputation: 1 253

0

Powershell, 39 bytes

($args|sls "[aeiou]"-a).Matches.Count%2

Explanation:

  • Takes arguments from the predefined $args;
  • Selects all matches to vowel characters (sls is alias for Select-String. By default, matches are not case-sensitive);
  • Takes the Matches.Count, and %2 to check whether it's odd/even.

Test script:

$f = {

($args|sls "[aeiou]"-a).Matches.Count%2

}

@(
    ,("trees", $false)
    ,("brush", $true)
    ,("CAts", $true)
    ,("Savoie", $false)
    ,("rhythm", $false)

) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result"
}

Output:

True: 0
True: 1
True: 1
True: 0
True: 0

mazzy

Posted 2016-09-20T17:50:13.303

Reputation: 4 832

0

Z80Golf, 34 bytes

0000                restart:      
0000   cd 03 80               call   $8003   
0003   30 05                  jr   nc,letter   
0005                done:        
0005   78                     ld   a,b   
0006   e6 01                  and   1   
0008   ff                     rst   $38   
0009   76                     halt      
000a                letter:      
000a   e6 1f                  and   $1f   
000c   3d                     dec   a   
000d   28 10                  jr   z,vowel   
000f   d6 04                  sub   4   
0011   28 0c                  jr   z,vowel   
0013   d6 04                  sub   4   
0015   28 08                  jr   z,vowel   
0017   d6 06                  sub   6   
0019   28 04                  jr   z,vowel   
001b   d6 06                  sub   6   
001d   20 e1                  jr   nz,restart   
001f                vowel:       
001f   04                     inc   b   
0020   18 de                  jr   restart   

Try it online!

Lynn

Posted 2016-09-20T17:50:13.303

Reputation: 55 648

0

Pip, 9 bytes

-XV Na%:2

Try it online!

 XV        Regex matching [aeiou]
-          Case-insensitive
    N      Count matches in
     a     Command-line argument
      %:2  Mod 2 (the : helps with parsing)

DLosc

Posted 2016-09-20T17:50:13.303

Reputation: 21 213

0

><>, 47 bytes

0i1+48*%:?v~2%n>~!
26a28*2b* \
r&:{=&+r  >l3(?v

Try it online!

Emigna

Posted 2016-09-20T17:50:13.303

Reputation: 50 798

0

Java 8: 88 bytes

s->s.chars().map(c->"aeiouAEIOU".contains((char)c+"")?-1:1).reduce(1,(x,y)->x*y)<0;

Try it online!

Dang it, I didn't see the older Java solution that used regex. Good job.

Benjamin Urquhart

Posted 2016-09-20T17:50:13.303

Reputation: 1 262

0

Java 143 bytes

Output is a boolean which is true if the word is odd.

public static boolean isOdd(char c){
return c=='a'||c=='e'||c=='i'||c=='o'||c=='u';
}


public static boolean isOdd(String k){
  boolean y=false;
  for(char x:k.toLowerCase().toCharArray())
    if(isOdd(x))
      y=(y?false:true);
  return y;
}

Golfed:

boolean i(String k){boolean y=false;for(char c:k.toLowerCase().toCharArray())if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u')y=!y;return y;}

Edit:

  • Fixed Case-sensitivity

Roman Gräf

Posted 2016-09-20T17:50:13.303

Reputation: 2 915

Did you run this against the third test case? – None – 2016-09-20T19:33:40.033

0

PHP, 43 Bytes

<?=preg_match_all("#[aeiou]#i",$argv[1])%2;

Jörg Hülsermann

Posted 2016-09-20T17:50:13.303

Reputation: 13 026

1Following the rules directly, just preg_match_all("#[aeiou]#i",$argv[1])%2 qualifies. – alanaktion – 2016-09-21T05:43:01.063

0

Go, 93 bytes

func(s string)int{n:=0;for _,c:=range s{for _,d:=range"aeiouAEIOU"{if c==d{n++}}};return n%2}

cia_rana

Posted 2016-09-20T17:50:13.303

Reputation: 441

0

Retina, 24 21 bytes

i`[aeiou]
1
T`Ll`
11

(there's a mandatory additional empty line, but formatting ignores it)

Returns 1 for odd words, and void for even ones.

Try it online!

Cedric Reichenbach

Posted 2016-09-20T17:50:13.303

Reputation: 448

0

Java, 59 bytes

s->s.chars().map(c->"aeiouAEIOU".indexOf(c)<0?0:1).sum()%2;

Ungolfed test program

public static void main( String[] args )
{
    Function<String, Integer> func = s -> s.chars().map( c -> "aeiouAEIOU".indexOf( c ) < 0 ? 0 : 1 ).sum() % 2;

    System.out.println( func.apply( "cat" ) );
}

Shaun Wild

Posted 2016-09-20T17:50:13.303

Reputation: 2 329

0

Dyalog APL, 17 bytes

2|≢⍞∩'aeiouAEIOU'

TryAPL online!

Adám

Posted 2016-09-20T17:50:13.303

Reputation: 37 779

0

R, 49 bytes

f=function(x)nchar(gsub("[^aeiou]","",x,i=T))%%2==0

Examples:

> f("cats")
[1] FALSE

> f("Savoie")
[1] TRUE

If it doesn't need a function and I can assume x is the input:

36 bytes:

!nchar(gsub("[^aeiou]","",x,i=T))%%2

If I can allow an output of 0 for even and 1 for odd:

35 bytes:

nchar(gsub("[^aeiou]","",x,i=T))%%2

Explanation

I'm substituting all vowels with blank character, ignoring case (i=T). This works because the i is enough to unambigiously identify the ignore.case argument and T is short for TRUE. Then count the odd characters and see if there's a remainder. If a number isn't a good response, I use ! (not) to coerce the 0/1 to TRUE/FALSE.

sebastian-c

Posted 2016-09-20T17:50:13.303

Reputation: 121

0

Lithp, 56 bytes, non-competing

#S::((& 1 (~ (length (split S (regex "[aeiou]" "i"))))))
  • Odd words: returns 1
  • Even words: returns 0

Non-competing because this was one of my test cases for developing my language. It was modified extensively after this challenge was posted to support running code such as this.


This is the same logic as the JavaScript response above. The language is a simplistic Lisp-like dialect with a fairly small interpreter.

Ungolfed:

(
    (var F #S::(
        (var L (split S (regex "[aeiou]" "i")))
        (& 1 (~ (length L)))
    ))
    (print (call F "brush"))
)

There is not currently an online repl to test this in, but there is a variation of this challenge in one of the provided examples that can be run with the interpreter.

Andrakis

Posted 2016-09-20T17:50:13.303

Reputation: 361

0

Racket 127 bytes

(if(= 0(modulo(for/sum((i(map(λ(i)(ormap(λ(x)(equal? i x))(string->list"aieouAEIOU")))(string->list s))))(if i 1 0))2))#f #t)

Ungolfed:

(define(f s)
  (let* ((vl (string->list "aieouAEIOU"))
         (od (λ(i) (ormap (λ (x) (equal? i x)) vl)))
         (ol (map od (string->list s)))
         (s (count (λ(i) i) ol ))
         (m (modulo s 2)))
    (if (= m 0) "even" "odd")
  ))

A longer (240 bytes) but more direct version:

(let*((vl(string->list"aieouAEIOU"))(od(λ(i)(ormap(λ(x)(equal? i x))vl))))(let lp((l(string->list s))
(st #t)(d 0))(cond((null? l)(if d"odd""even"))(st(lp(cdr l)#f(if(od(car l))#t #f)))
(else(lp(cdr l)#f(if(equal? d(od(car l)))#f #t))))))

Ungolfed:

(define (f s)
  (let* ((vl (string->list "aieouAEIOU"))
         (od (λ (i) (ormap (λ (x) (equal? i x)) vl) )))
    (let loop ((l (string->list s))
               (starting #t)
               (odd 0))
      (cond
        ((null? l) 
         (if odd "odd" "even"))
        (starting
         (loop (rest l) #f
               (if(od (first l))
                  #t #f )))
        (else 
         (loop (rest l) #f 
               (if (equal? odd
                           (od (first l)))
                   #f #t)))))))

Testing:

(f "trees")
(f "brush")
(f "CAts")
(f "Savoie")
(f "rhythm")

Output:

"even"
"odd"
"odd"
"even"
"even"

rnso

Posted 2016-09-20T17:50:13.303

Reputation: 1 635

0

Java, 128 bytes

boolean f(String k){return k.chars().flatMap(i->"aeiouAEIOU".contains(((char)i)+"")?IntStream.of(1):IntStream.of(0)).sum()%2>0;}

There's definitely a better way than using Instream.of(0) and Instream.of(1).

416E64726577

Posted 2016-09-20T17:50:13.303

Reputation: 123

0

Ruby, 30 bytes

->w{w.count('aeiouAEIOU')%2>0}

Returns true for an odd word and false for an even word. The existing Ruby solution returns 0 for even words, which is a truthy value in Ruby.

Lee W

Posted 2016-09-20T17:50:13.303

Reputation: 521

0

Elixir, 45 bytes

&rem(length(Regex.scan(~r/[aeiou]/i,&1)),2)>0

Anonymous function defined using the capture operator. If the number of vowels is odd, the specified word is odd, so the function returns true.

Full program with test cases:

s=&rem(length(Regex.scan(~r/[aeiou]/i,&1)),2)>0
# test cases
IO.puts s.("trees") # false
IO.puts s.("brush") # true
IO.puts s.("CAts")  # true
IO.puts s.("Savoie")    # false
IO.puts s.("rhythm")    # false

Try it online on ElixirPlayground !

adrianmp

Posted 2016-09-20T17:50:13.303

Reputation: 1 592