DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #35 - Find the Outlier

In this challenge, you'll be given an array with a length of at least three, containing (possibly quite large) integers. The array is either comprised of entirely odd integers or even integers with one exception. Write a method that returns the integer that is not like the others.

Example:
findOutlier([2, 4, 0, 100, 4, 11, 2602, 36]) => 11

Additional practice arrays:
[160, 3, 1719, 19, 11, 13, -21]
[4, 8, 15, 16, 24, 42]
[16, 6, 40, 66, 68, 28]

Good luck, happy coding~!


This challenge comes from user obnounce. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Latest comments (31)

Collapse
 
d3press3dd profile image
Anthony Rosman

this only iterates the array 3 times, and with that you can know if the number is even or odd and with the find it will only iterate until it finds it, when it finds it it will stop and so I will not have to iterate over the array in case it has 10000000000 elements and it is in a close position.

what do you guys think?

function findOutlier(integers){
  //your code here
  let isEven = 0;
  let isOdd = 0;
  let outlier;
  for (let i = 0; i < 3; i++) {
    if (Math.abs(integers[i]) % 2 === 0) {
      isEven += 1;
    } else {
      isOdd += 1;
    }
  }
  if (isEven < isOdd) {
   return integers.find(number => Math.abs(number) % 2 === 0);
  } else {
    return integers.find(number => Math.abs(number) % 2 !== 0);
  }  
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
mrdulin profile image
official_dulin

Go:

func FindOutlier(integers []int) int {
  var m = map[string][]int{
    "odd": []int{},
    "even": []int{},
  }
  for _, i := range integers {
    if i % 2 == 0 {
      m["even"] = append(m["even"], i)
    } else {
      m["odd"] = append(m["odd"], i)
    }
  }
  if len(m["even"]) == 1 {
    return m["even"][0]
  } 
  return m["odd"][0]
}
Collapse
 
peter279k profile image
peter279k

Here is the simple solution with PHP:

function find($integers) {
  $evenArray = [];
  $oddArray = [];

  foreach ($integers as $integer) {
    if ($integer % 2 === 0) {
      $evenArray[] = $integer;
    } else {
      $oddArray[] = $integer;
    }
  }

  if (count($evenArray) === 1) {
    return $evenArray[0];
  }

  return $oddArray[0];
}
Collapse
 
matrossuch profile image
Mat-R-Such

Python

def find_outlier(integers):
    a= sum(map(int,[integers[0]%2,integers[1]%2,integers[2]%2]))
    if a == 0 or a== 1:
       for i in integers:
           if i % 2 == 1:   return i
    else:
        for i in integers:
            if i % 2 == 0:   return i
Collapse
 
oscherler profile image
Olivier “Ölbaum” Scherler

Erlang.

  • If the first two numbers have the same parity, I search the rest of the array for the other parity;
  • If they have different parities, I rotate them with the third number and check the resulting three-element array.
-module( outlier ).

-include_lib("eunit/include/eunit.hrl").

outlier( [ A, B, C | Rest ] ) ->
    case { abs( A rem 2 ), abs( B rem 2 ) } of
        { S, S } -> outlier( [ C | Rest ], 1 - S );
        { _, _ } -> outlier( [ B, C, A ] )
    end.
outlier( [ A | _ ], S ) when abs( A rem 2 ) == S ->
    A;
outlier( [ _ | Rest ], S ) ->
    outlier( Rest, S ).    

outlier_test_() -> [
    ?_assertEqual( 11, outlier( [ 2, 4, 0, 100, 4, 11, 2602, 36 ] ) ),
    ?_assertEqual( 160, outlier( [ 160, 3, 1719, 19, 11, 13, -21 ] ) ),
    ?_assertEqual( 15, outlier( [ 4, 8, 15, 16, 24, 42 ] ) ),

    ?_assertEqual( 2, outlier( [ 1, 2, 3, 5 ] ) ),
    ?_assertEqual( 1, outlier( [ 1, 2, 4, 6 ] ) ),
    ?_assertEqual( 2, outlier( [ 2, 1, 3, 5 ] ) ),
    ?_assertEqual( 1, outlier( [ 2, 1, 4, 6 ] ) ),

    ?_assertError( function_clause, outlier( [ 16, 6, 40, 66, 68, 28 ] ) ),
    ?_assertError( function_clause, outlier( [ 16, 6 ] ) )
].
Collapse
 
hectorpascual profile image
Héctor Pascual

Python :

def find_outlier(array):
    odd = [i for i in array if i%2 == 0]
    even = [i for i in array if i%2]

    if not even or not odd:
        return "ERROR"
    elif len(even) > len(odd):
        return odd[0]
    else:
        return even[0]
Collapse
 
asg5704 profile image
Alexander Garcia

Not elegant, but it'll do the job.

const findOutlier = (arr) => {
 const firstPass = arr.filter(el => el % 2 === 0)
 const secondPass = arr.filter(el => el % 2 !== 0)

 if(firstPass.length === 1) {
   return firstPass[0]
 }
 return secondPass[0]
}
Collapse
 
ra9 profile image
Carlos Nah • Edited

Here's my code:
I believe I could have used filters on the arrays method but just decided to follow the long step.



  const findOutlier = (arr) => {
    const evens = [];
    const odds = [];
    for(let i in arr) {
        const isEven = arr[i] % 2 === 0;
        const isOdd = !isEven;
        if(isEven){
            evens.push(arr[i]);
        }
        if(isOdd) {
            odds.push(arr[i])
        } 
    }

    if(odds.length === 0 || evens.length === 0) {
        return null;
    }

    return  odds.length  < evens.length ? odds[0] : evens[0];
  }

  console.log([
      [160, 3, 1719, 19, 11, 13, -21],
      [4, 8, 15, 16, 24, 42],
      [16, 6, 40, 66, 68, 28]
  ].map(findOutlier));

Here's my code:
I believe I could have used filters on the arrays method but just decided to follow the long step.



  const findOutlier = (arr) => {
    const evens = [];
    const odds = [];
    for(let i in arr) {
        const isEven = arr[i] % 2 === 0;
        const isOdd = !isEven;
        if(isEven){
            evens.push(arr[i]);
        }
        if(isOdd) {
            odds.push(arr[i])
        } 
    }

    if(odds.length === 0 || evens.length === 0) {
        return null;
    }

    return  odds.length  < evens.length ? odds[0] : evens[0];
  }

  console.log([
      [160, 3, 1719, 19, 11, 13, -21],
      [4, 8, 15, 16, 24, 42],
      [16, 6, 40, 66, 68, 28]
  ].map(findOutlier));

Here's my code:
I believe I could have used filters on the arrays method but just decided to follow the long step.



  const findOutlier = (arr) => {
    const evens = [];
    const odds = [];
    for(let i in arr) {
        const isEven = arr[i] % 2 === 0;
        const isOdd = !isEven;
        if(isEven){
            evens.push(arr[i]);
        }
        if(isOdd) {
            odds.push(arr[i])
        } 
    }

    if(odds.length === 0 || evens.length === 0) {
        return null;
    }

    return  odds.length  < evens.length ? odds[0] : evens[0];
  }

  console.log([
      [160, 3, 1719, 19, 11, 13, -21],
      [4, 8, 15, 16, 24, 42],
      [16, 6, 40, 66, 68, 28]
  ].map(findOutlier));

Collapse
 
mwlang profile image
Michael Lang

Ruby Language

With specs!

def outlier values
  o = values.partition(&:odd?).sort_by(&:size)[0]
  o[0] if o.size == 1
end

require "spec"

describe "#name_shuffler" do
  it { expect(outlier [2, 4, 0, 100, 4, 11, 2602, 36]).to eq 11}
  it { expect(outlier [160, 3, 1719, 19, 11, 13, -21]).to eq 160}
  it { expect(outlier [4, 8, 15, 16, 24, 42]).to eq 15}
  it { expect(outlier [16, 6, 40, 66, 68, 28]).to eq nil}
end

output

>> rspec outlier.rb
....

Finished in 0.0052 seconds (files took 0.15152 seconds to load)
4 examples, 0 failures
Collapse
 
vanbliser profile image
Ayogu Blossom Israel

array = [500,502,1002,1234,601]
odd = even = i = 0
oddValue = evenValue = 0
a = len(array)
while (i < a):
if (array[i] % 2):
oddValue = array[i]
odd += 1
else:
evenValue = array[i]
even += 1
i += 1
if (odd > even == 1):
print(evenValue)
elif (odd == 1):
print(oddValue)
else:
print("Wrong list of numbers")

Collapse
 
vanbliser profile image
Ayogu Blossom Israel

array = [500,502,1002,1234,601]
odd = even = i = 0
oddValue = evenValue = 0
a = len(array)
while (i < a):
if (array[i] % 2):
oddValue = array[i]
odd += 1
else:
evenValue = array[i]
even += 1
i += 1
if (odd > even == 1):
print(evenValue)
elif (odd == 1):
print(oddValue)
else:
print("Wrong list of numbers")

Collapse
 
frncesc profile image
Francesc Busquets

This is my proposal:

function findOutlier(arr){
  const even=[], odd=[];
  arr.find(n => {
    (n%2 ? even : odd).push(n);
    return even.length ? odd.length > 1 : odd.length ? even.length > 1 : false;    
  });
  return even.length === 1 ? even[0] : odd.length === 1 ? odd[0] : null;
}

In this case, Array.find will stop looping when both the even and odd arrays have at least one item.

There is only one loop on the array values, and this loop stops just when the "strange element" is found.

At the end, the group with just one element has the solution.

In the last test, an array formed entirely by even numbers, null is returned.

Collapse
 
muhammadhasham profile image
Muhammad Hasham

With JS

function findOutlier(arr){
let checker = {even:[],odd:[]}
arr.forEach((item) => item%2==0 ? checker['even'].push(item) : checker['odd'].push(item));
return checker['even'].length < checker['odd'].length ? checker['even'][0] : checker['odd'][0];
}

findOutlier([2, 4, 0, 100, 4, 11, 2602, 36])

Explanation:

  1. Using an object which stores even and odd numbers.
  2. just returning the one with less number.
Collapse
 
room_js profile image
JavaScript Room

Dart solution:

findOutlier(List nums) {
  var odds = new List();
  var evens = new List();
  nums.forEach((num) => num % 2 == 0 ? evens.add(num) : odds.add(num));

  if (odds.length == 0 || evens.length == 0) { return null; }

  return (odds.length < evens.length ? odds : evens)[0];
}

Link to the online playground: dartpad.dartlang.org/d5e83e228c72d...

Collapse
 
hanachin profile image
Seiei Miyagi

ruby 2.7

def findOutlier(a) a.group_by(&:even?).each_value { return @1 if @2.nil? }; nil end
p [
  [2, 4, 0, 100, 4, 11, 2602, 36],
  [160, 3, 1719, 19, 11, 13, -21],
  [4, 8, 15, 16, 24, 42],
  [16, 6, 40, 66, 68, 28]
].map(&self.:findOutlier)

# [11, 160, 15, nil]