19
\$\begingroup\$

How to determine if a number is odd or even without mod -or- bitwise operations?

This challenge is grossly inefficient, but challenges your ability to think outside the box for a creative solution.

EDIT:

Please create a function. Also, while regex is a fun response, the function should accept any valid number.

BACKGROUND: This question stems from my earliest programming days. The homework for our first day of class was to write a simple program that printed 'odd' or 'even'. Being the brat I was, I didn't read the book we had for the class where it simply showed us how to use % to determine that. I spent about a half hour pacing back in forth in my room trying to think of a way to do this and had remembered from the lecture that numbers can lose and gain precision as they are cast from one primitive type to another. Therefore, if you took the number, divided it by two and then multiplied it back didn't equal the original number, then you would know that the number was odd.

I was stunned the next day, while our instructor was evaluating our programs, that he thought that it was the most original, if inefficient, way of solving the problem.

\$\endgroup\$

closed as off topic by dmckee Mar 16 '13 at 19:22

Questions on Code Golf Stack Exchange are expected to relate to programming puzzles or code golf within the scope defined by the community. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about reopening questions here. If this question can be reworded to fit the rules in the help center, please edit the question.

  • 3
    \$\begingroup\$ Should we create a function or a program? How should IO happen if we have to do a program? Please, elaborate further. \$\endgroup\$ – Juan Apr 28 '11 at 3:10
  • 2
    \$\begingroup\$ What objective criterion will determine the accepted answer? Code size? Something else? \$\endgroup\$ – PleaseStand Apr 28 '11 at 3:47
  • \$\begingroup\$ Is it definitely a number? Should it give false positives for a string? \$\endgroup\$ – William Apr 30 '11 at 1:22
  • \$\begingroup\$ This has been around for quite a long time, but there doesn't seem to be a winning condition of any kind, which to my mind means there is no game here. \$\endgroup\$ – dmckee Mar 16 '13 at 19:22

50 Answers 50

2
\$\begingroup\$

Mathematica

Edit: This is the unimaginative check that many folks, including me, use. If an integer ends in 0,2,4, 6,or 8, it is even, otherwise odd.

f[n_?IntegerQ] := Print[n, " is ", 
If[MemberQ[{0, 2, 4, 6, 8}, IntegerDigits[n][[-1]]], "even.", "odd."]]

Original solution:

The following is even more unimaginative and uselessly slow for "large" integers, but in principle, it works.

If an integer has 2 is its lowest prime factor, it is even.

f[n_?IntegerQ]:= Print[n, " is ", If[FactorInteger[n][[1, 1]] == 2, "Even", "Odd"]
\$\endgroup\$
1
\$\begingroup\$

Are we allowed to submit utterly terrible ways to do this? If so...

C

#include <stdio>

void oddOrEven(int number)
{
   char test[128];
   sprintf(test, "%d", number);

   int index = strlen(test) - 1;

   if((test[index]=='0')||(test[index]=='2')||(test[index]=='4')||
        (test[index]=='6')||(test[index]=='8'))
   {
      printf("Even.");
   } else {
      printf("Odd.");
   }
}

I apologize for any errors, I don't have a chance to compile or test this. Fixed one bug, per comment by Joey Adams.

This answer is similar to the one posted by idealmachine

\$\endgroup\$
  • \$\begingroup\$ You'll need strlen(test) - 1 for this to work. test[index] currently refers to the null terminator of the string. \$\endgroup\$ – Joey Adams Apr 28 '11 at 15:26
  • \$\begingroup\$ @Joey Adams Thanks, I knew there'd be at least one bug. \$\endgroup\$ – thedaian Apr 28 '11 at 15:39
  • \$\begingroup\$ Considering efficiency isn't a metric here, this solution is as good as any really. \$\endgroup\$ – Neil Sep 14 '11 at 13:37
1
\$\begingroup\$

scala:

scala> def evenOrOdd (n:Int) : Unit = n match {
     | case 0 => println ("even")              
     | case 1 => println ("odd")               
     | case _ => evenOrOdd (n-2) }             
evenOrOdd: (n: Int)Unit

scala> evenOrOdd (123456789)
odd

(less than one second)

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

Perl

sub is_odd {$#{[split/\./,$_[0]/2]}}

\$\endgroup\$
  • \$\begingroup\$ What's the $#{} do? \$\endgroup\$ – drnewman Feb 14 '12 at 11:06
  • \$\begingroup\$ it dereferences the array references [] and returns the last index (i.e. N-1 since Perl indexes start at 0). This is essentially sub is_odd {$input = shift; $input /= 2; my @parts = split /\./, $input; return ( scalar(@parts) - 1) } \$\endgroup\$ – Joel Berger Feb 14 '12 at 16:26
  • 1
    \$\begingroup\$ Thanks that cleared it up, I got the $#array bit but I missed that you were turning the ouput of split into a reference with [] then dereferenceing with ${} and adding the # to get the last index, very cool. \$\endgroup\$ – drnewman Feb 14 '12 at 23:59
  • \$\begingroup\$ its essentially the babycart "operator" @{[]}, but the index of that :) mail-archive.com/fwp@perl.org/msg03595.html \$\endgroup\$ – Joel Berger Feb 15 '12 at 1:06
  • \$\begingroup\$ Cool, thanks for the clarification \$\endgroup\$ – drnewman Feb 15 '12 at 2:18
1
\$\begingroup\$

C++ (63)

Token absurd recursive solution. Even golfed!

#include <math.h>
bool o(int v){return v==0?false:!o(abs(v)-1);}
\$\endgroup\$
1
\$\begingroup\$

For C or C++, easy enough:

int Temp = 20
double Temp2 = ((double)Temp/2);
Temp2 = Temp2 - ((int)Temp/2);
if(Temp2 != 0.0)
{
    printf("It's odd!\n");
}
else
{
    printf("It's even!\n");
}
\$\endgroup\$
1
\$\begingroup\$

C#

Sorry for my previous response, I'm totally messed up today.

bool Even(int i){return i==0||!Even(i-1);}
\$\endgroup\$
1
\$\begingroup\$
function isEven(i) {
    return i == 0 || !isEven(i - (i > 0 ? 1 : -1));
}
\$\endgroup\$
1
\$\begingroup\$

return exp(sqrt(-1)*x*pi)==1?"even":"odd";

\$\endgroup\$
  • \$\begingroup\$ Nice approach, what language is this supposed to be, though? Exact complex arithmetic is quite uncommon outside CASs. \$\endgroup\$ – ceased to turn counterclockwis Feb 15 '12 at 2:51
  • \$\begingroup\$ You got me there. I use Matlab a lot, but this isn't real Matlab code. Anyway, it could also be done with a cosine function and a real argument (x*pi). And as far as exactness goes, even testing within limits would become a problem for large x. (This is my first code golf. Looks like fun!) \$\endgroup\$ – Jim Feb 15 '12 at 5:03
1
\$\begingroup\$

C++11

(for C++03, replace long long with long and -2ull with -2ul)

Yet another solution which takes advantage of the fact that integers have finite size, together with the fact that unsigned arithmetic is defined as modulo arithmetic. It also uses the fact that conversion of integer types to bool gives true iff the converted number is nonzero.

bool odd(unsigned long long n) // note: signed->unsigned conversion preserves oddity
{
  return n * (1 + -2ull / 2);
}
\$\endgroup\$
1
\$\begingroup\$

Perl

if ((int(($number/2)) * 2) == $number) { print ("even"); }
\$\endgroup\$
1
\$\begingroup\$

Bash

This script asks Wolfram|Alpha whether a number is even or odd:

#!/bin/bash

curl -s "http://www.wolframalpha.com/input/?i=even($1)" | grep 'is even' > /dev/null

if [ $? -eq 0 ]
then
    echo Yes
else
    echo No
fi
\$\endgroup\$
1
\$\begingroup\$

Haskell, Recduction from Towers of Hanoi

When moving n pegs from A to B, then for even n, the first move is A->C.
Doesn't work for n=0.

data Peg = A|B|C deriving Eq   
third :: Peg -> Peg -> Peg
third x y
    | x/=A && y/=A = A
    | x/=B && y/=B = B
    | x/=C && y/=C = C

data Move = Move Peg Peg deriving Eq

-- Move n pegs from a to b
hanoi :: Int -> Peg -> Peg -> [ Move ]
hanoi 0 _ _ = []
hanoi n a b = (hanoi (n-1) a c) ++ [Move a b] ++ (hanoi (n-1) c b) where
    c = third a b

-- n is even if the first step in moving n discs from A to B is A->C.
iseven :: Int -> Bool
iseven n = (head $ hanoi n A B) == Move A C
\$\endgroup\$
0
\$\begingroup\$

Perl

This always returns a . when the number is odd, and either an integer or nothing when it is even.

chop($_=<>/2);print chop

If you want it to actually print the word "odd" or "even" then it needs to be expanded to the following:

chop($_=<>/2);if(chop=='.'){print"Odd"}else{print"Even"}

OR, if you want the program to exit once it gives a result, this can be written as:

chop($_=<>/2);if(chop=='.'){die"Odd"}die"Even"
\$\endgroup\$
  • \$\begingroup\$ Only works with numbers greater than 18. However, changing == to eq might fix it (requires an extra space though). \$\endgroup\$ – Timwi Oct 16 '11 at 19:30
0
\$\begingroup\$

VB.Net

return (i\2)*2=i 

Notice the use of the backslash operator \ that performs a integer division and discards any reminders. The usage of a forvard slash operator / would not work for this solution.

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

Haskell

odd = (<)0.(^)(-1)
even = (>)0.(^)(-1)

J

odd =: 0>_1&^
even =: 0<_1&^

If (-1)n<0, n is odd; if (-1)n>0, n is even.

odd =: [:|[:{:@+.0j1&^
even =: [:|[:{.@+.0j1&^

Taking the imaginary/real part of in would be a neat way to do it too, but needs better thresholding than this.

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

use queue and push pop, if element remains at last, it's odd, else is even:

var q = new Queue<int>();
for (int i=0;i<n;i++)
{
   if (q.Count > 0)
     q.Pop();
   else q.Push(0);
}

if (q.Count != 0)
  return "Odd";
return "Even";
\$\endgroup\$
0
\$\begingroup\$

Python

Somebody already used this idea, but this implementation is more concise:

def even(n):return str(n)[-1]in'02468'
\$\endgroup\$
0
\$\begingroup\$

Squeak Smalltalk

Since printing in base 2 would be too obvious and a big waste of time because only the last digit counts

odd
    ^(self printStringBase: 2) last = $1

I decided to rather print in base 3 to at least scan all the digits

odd
    ^self ~= 0 and: [self = 1 or: [((self printStringBase: 3) occurrencesOf: $1) odd]]

Of course, if we have more CPU to waste, we can just enumerate

odd
    ^(1 to: self abs) inject: false into: [:odd :int | odd not]

Finally, if we are impatient, this might be a bit faster

odd
    (0 to: self abs by: 2) size - (1 to: self abs by: 2) size = 0
\$\endgroup\$
0
\$\begingroup\$

R

is.even<-function(n){
    options(warn=-1)
    res<-ifelse(sum(matrix(1:abs(n),nrow=2)==1)!=1, "Odd", "Even")
    options(warn=0)
    res
    }

The idea is to build a 2-rows matrix with the sequence 1 to the absolute value of n (to allow negative numbers). If the number is odd, the sequence has to be recycled to fill the 2 rows, so the matrix contains twice the number 1. Due to the method, it doesn't work with large numbers but it works with zero.

> is.even(0)
[1] "Even"
> is.even(467)
[1] "Odd"
> is.even(-46798)
[1] "Even"
> is.even(9999999999)
Error in 1:abs(n) : result would be too long a vector
\$\endgroup\$

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