DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #81 - Even or Odd

Given a string of numbers confirm whether the total of all the individual even numbers are greater than the total of all the individual odd numbers. Always a string of numbers will be given.

If the sum of even numbers is greater than the odd numbers return:

Even is greater than Odd

If the sum of odd numbers is greater than the sum of even numbers return:

Odd is greater than Even

If the total of both even and odd numbers are identical return:

Even and Odd are the same


This challenge post comes from slater at CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Top comments (19)

Collapse
 
avalander profile image
Avalander • Edited

Haskell

Since I'm not entirely sure what a string of numbers means, I just assumed the function gets a list of integers.

import Data.List (partition)

fight :: [Int] -> String
fight = answer . add . partition even
  where
    add (evens, odds) = (sum evens, sum odds)
    answer (evens, odds)
      | evens == odds = "Even and Odd are the same"
      | evens > odds  = "Even is greater than Odd"
      | otherwise     = "Odd is greater than Even"
Collapse
 
aminnairi profile image
Amin

Could you explain what add (evens, odd) is (data type) and what does this piece do please?

Collapse
 
avalander profile image
Avalander • Edited

Sure! Let's start at partition, since we pass its output to add. Partition takes a predicate function and returns a tuple ([Int], [Int]) with the items of the list for which the predicate is true in the first position and the items for which the predicate is false in the second position. In this case, in the first position we'll have all the even numbers and in the second all the odd numbers, since we're using even as predicate.

Then add receives this tuple, which I destructure for convenience, and applies the function sum to both elements, which sums all the items in each list.

And the function signature for add would look like this.

add :: ([Int], [Int]) -> (Int, Int)

Lastly, answer takes the output of add and checks the conditions in the guards (the | <condition> thing) and returns the string for the first condition that matches or the string after otherwise if none matches.

Thread Thread
 
aminnairi profile image
Amin

Awesome, thanks for your answer! I didn't know the add function could take a tuple. Good to know!

Collapse
 
brightone profile image
Oleksii Filonenko • Edited

Elixir:

defmodule Day81 do
  require Integer

  @spec even_or_odd(String.t()) :: String.t()
  def even_or_odd(string) do
    {even, odd} =
      string
      |> String.graphemes()
      |> Enum.map(&String.to_integer/1)
      |> Enum.split_with(&Integer.is_even/1)

    {even, odd} = {Enum.sum(even), Enum.sum(odd)}

    cond do
      even > odd -> "Even is greater than Odd"
      odd > even -> "Odd is greater than Even"
      true -> "Even and Odd are the same"
    end
  end
end
Collapse
 
aminnairi profile image
Amin

I read graphmemes instead of graphemes, I should probably stop browsing the internet for today...

Collapse
 
brightone profile image
Oleksii Filonenko

Graph memes would be too... Edgy.

Sorry :)

Collapse
 
savagepixie profile image
SavagePixie • Edited

Some JavaScript

const evenVsOdd = str => {
   const evens = str.split('').filter(x => x % 2 == 0).reduce((a, b) => a + parseInt(b), 0)
   const odds = str.split('').filter(x => x % 2 != 0).reduce((a, b) => a + parseInt(b), 0)

   return evens > odds ? "Even is greater than Odd"
      : evens == odds ? "Even and Odd are the same"
      : "Odd is greater than Even"
}
Collapse
 
idanarye profile image
Idan Arye

Rust

Rather than keeping two sums, we can negate one of the options (I chose to negate the evens) and compare the sum to 0:

use std::cmp::Ordering;

fn compare_even_to_odd(numbers: impl Iterator<Item = i64>) -> String {
    let comparison = numbers.map(|number| if number % 2 == 0 {
            - number
        } else {
            number
        }
    ).sum::<i64>().cmp(&0);
    match comparison {
        Ordering::Less => "Even is greater than Odd".to_owned(),
        Ordering::Equal => "Even and Odd are the same".to_owned(),
        Ordering::Greater => "Odd is greater than Even".to_owned(),
    }
}
fn main() {
    println!("{}", compare_even_to_odd((&[1, 3, 4]).iter().map(|a| (*a))));
}
Collapse
 
aminnairi profile image
Amin

Elm

module EvenOdd exposing (evenOdd)


compareEvensOdds : ( Int, Int ) -> String
compareEvensOdds ( evens, odds ) =
    case compare evens odds of
        GT ->
            "Even is greater than Odd"

        LT ->
            "Odd is greater than Even"

        _ ->
            "Even and Odd are the same"


evenOdd : String -> String
evenOdd =
    String.split ""
        >> List.map (String.toInt >> Maybe.withDefault 0)
        >> List.partition (modBy 2 >> (==) 0)
        >> Tuple.mapBoth List.sum List.sum
        >> compareEvensOdds

Tests

module EvenOddTest exposing (suite)

import EvenOdd exposing (evenOdd)
import Expect exposing (equal)
import Test exposing (Test, describe, test)


suite : Test
suite =
    describe "Even or odd"
        [ test "Evens should be greater than odds with 12" <|
            \_ ->
                evenOdd "12" |> equal "Even is greater than Odd"
        , test "Odds should be greater than evens with 123" <|
            \_ ->
                evenOdd "123" |> equal "Odd is greater than Even"
        , test "Evens & odds should be equal with 112" <|
            \_ ->
                evenOdd "112" |> equal "Even and Odd are the same"
        ]
Collapse
 
eddiehale3 profile image
Eddie Hale

Golang

I assumed string of numbers was an array.

package main

import "fmt"

func evenOrOdd(numbers [10]int) {
    evenSum := 0
    oddSum := 0

    for i := 0; i < len(numbers); i++ {
        check := numbers[i] % 2

        if check == 0 {
            evenSum += evenSum + numbers[i]
        } else {
            oddSum += oddSum + numbers[i]
        }
    }

    if evenSum > oddSum {
        fmt.Println("Even is greater than Odd")
    } else if evenSum < oddSum {
        fmt.Println("Odd is greater than Even")
    } else if evenSum == oddSum {
        fmt.Println("Even and Odd are the same")
    }
}

func main() {
    numbers := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    evenOrOdd(numbers)
}
Collapse
 
earlware profile image
EarlWare

A Swift solution:

import Foundation


/*
 evenOrOdds takes a list of numbers and outputs which total is greater, all odds, or all evens.

 @param numList: [Int] list of integers of any length

 @return String describing which value is greater or even they are equal.
 */
func evenOrOdds(_ numList:[Int]) -> String {
    let evenWin = "Even is greater than Odd"
    let oddWin  = "Odd is greater than Even"
    let draw    = "Even and Odd are the same"

    var accum = 0

    for num in numList {
        if num % 2 == 0 {
            accum += num
        } else {
            accum -= num
        }
    }

    if accum > 0 {
        return evenWin
    } else if accum < 0 {
        return oddWin
    }

    return draw
}




// utility function to generate a list of Ints
func genRandoms() {
    var randomGen = SystemRandomNumberGenerator.init()
    var randomList = [Int](repeating: 1, count: 100)

    for index in 0..<randomList.count {
        randomList[index] = Int(bitPattern: randomGen.next(upperBound: UInt(bitPattern: 500)))
    }

    print(randomList)
}


let example1 = [104, 258, 303, 66, 310, 363, 41, 180, 299, 208, 355, 135, 234, 214, 243, 350, 494, 408, 37, 438, 335, 101, 489, 449, 44, 136, 285, 408, 432, 350, 343, 271, 9, 286, 304, 451, 26, 388, 303, 259, 212, 434, 241, 20, 199, 201, 55, 318, 110, 48, 135, 359, 345, 277, 424, 23, 249, 348, 419, 301, 409, 316, 163, 81, 319, 440, 466, 185, 57, 102, 230, 446, 454, 369, 21, 284, 7, 161, 136, 113, 471, 2, 217, 350, 361, 334, 437, 421, 29, 290, 123, 326, 360, 142, 330, 354, 325, 140, 312, 116]

let example2 = [407, 461, 144, 458, 246, 103, 5, 241, 166, 75, 300, 215, 430, 424, 325, 283, 81, 420, 405, 485, 266, 23, 71, 42, 290, 189, 364, 382, 368, 203, 89, 317, 26, 465, 94, 84, 133, 223, 204, 189, 430, 400, 273, 476, 222, 246, 455, 137, 258, 470, 428, 242, 173, 285, 428, 147, 105, 306, 211, 489, 383, 414, 93, 433, 257, 449, 485, 183, 160, 302, 307, 227, 5, 361, 188, 18, 356, 442, 16, 409, 309, 152, 94, 319, 264, 147, 247, 359, 25, 364, 58, 144, 218, 16, 401, 62, 391, 110, 399, 24]

let example3 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]

// used to generate a draw data set, but just explicitly defined after copying the output
//var example3 = [Int](repeating: 1, count: 50)
//example3.append(contentsOf: [Int](repeating: 2, count: 25))


print(evenOrOdds(example1),"")

print(evenOrOdds(example2),"")

print(evenOrOdds(example3),"\n")

Outputs:

Even is greater than Odd 
Odd is greater than Even 
Even and Odd are the same 

Program ended with exit code: 0

Went with accumulating by adding evens and subtracting odds so in a case where the list of values being summed up ends up greater than Int.max you don't get a runtime error...... not that these test cases are likely to total greater than 9223372036854775807.... haha

Collapse
 
ssghost profile image
Consta Chain • Edited
nums = str(input())
numi = [int(n) for n in nums]
odd = [n for n in numi if n%2 == 1]
if sum(odd) > int(sum(numi)/2):
   print("Odd is greater than Even")
elif sum(odd) < int(sum(numi)/2):
   print("Even is greater than Odd")
else:
   print("Even and Odd are the same")

Collapse
 
kvharish profile image
K.V.Harish

My solution in js


const evenOrOdd = (str) => {
  const evenCount = (`${str}`.match(/[02468]/g) || '').length,
    oddCount = (`${str}`.match(/[13579]/g) || '').length;
  return (evenCount === oddCount) ? 'Even and Odd are the same' : (evenCount > oddCount ) ? 'Even is greater than Odd' : 'Odd is greater than Even';
};

Collapse
 
jaumevn profile image
Jaume Viñas Navas • Edited

A Swift solution:

unc solution(_ numbers: [Int]) -> String {
    var odds = 0
    var evens = 0

    for number in numbers {
        if (number % 2 == 0) {
            evens += number
        } else {
            odds += number
        }
    }

    if (evens > odds) {
        return "Even is greater than Odd"
    } else if (evens < odds) {
        return "Odd is greater than Even"
    }

    return "Even and Odd are the same"
}
Collapse
 
diegolago profile image
Diego Lago

D version, assuming that the string of numbers is a string with integers separated by spaces:

import std.stdio : writeln;
import std.array : split;
import std.conv : to;
import std.algorithm.iteration : map, sum;

string compareEvenOdd(string numbers) {
    auto result = numbers
        .split()
        .map!(a => to!int(a))
        .map!(a => a % 2 == 0 ? a : -a)
        .sum();
    return result < 0 ? "Odd is greater than Even" :
          (result > 0 ? "Even is greater than Odd" :
                        "Even and Odd are the same");
}    

void main() {
    compareEvenOdd("1 2 3 4 5 6 7 8 9").writeln();
    compareEvenOdd("1 3 6 98 35").writeln();
    compareEvenOdd("1 1 2 1 1 2 1 1 2").writeln();
}

Output:

Odd is greater than Even
Even is greater than Odd
Even and Odd are the same
Collapse
 
peledzohar profile image
Zohar Peled

c#, using linq, input validations omitted:

string evenOrOdd(string digitsOnly) 
{
    var evens = digitsOnly.Count(c => Char.GetNumericValue(c) % 2 == 0);
    var odds = digitsOnly.Length - evens;
    return evens > odds ? 
        "Even is greater than Odd" : 
        evens < odds ? 
            "Odd is greater than Even" : 
            "Even and Odd are the same";
}
Collapse
 
aminnairi profile image
Amin • Edited

I just checked on Codewars the challenge, and the template for the JavaScript language is the following:

function evenOrOdd(str) {

}

and the tests are

// node 8.x.x

Test.assertEquals(evenOrOdd('12'), 'Even is greater than Odd');
Test.assertEquals(evenOrOdd('123'), 'Odd is greater than Even');
Test.assertEquals(evenOrOdd('112'), 'Even and Odd are the same');

If it can help you understand a little bit more the challenge (yes, the instructions in this article were confusing).