# 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!

### Discussion 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
where
add (evens, odds) = (sum evens, sum odds)
| evens == odds = "Even and Odd are the same"
| evens > odds  = "Even is greater than Odd"
| otherwise     = "Odd is greater than Even"


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

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.

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

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))));
}


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"
}


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


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

Graph memes would be too... Edgy.

Sorry :)

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"
]


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")



Golang

I assumed string of numbers was an array.

package main

import "fmt"

func evenOrOdd(numbers 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 := int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
evenOrOdd(numbers)
}


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

F#

module DailyChallenge

open System.Text.RegularExpressions

let tuple2Map f (x, y) = (f x, f y)

let (|Greater|Smaller|Equal|) (x, y) =
if x > y then Greater
elif x < y then Smaller
else Equal

let evenOrOdd (nums : string) : string =
nums.Split(' ')
|> Array.partition (fun n -> Regex.Match(n, "$").Success) |> tuple2Map (Array.sumBy (int)) |> function | Greater -> "Even is greater than Odd" | Smaller -> "Odd is greater than Even" | Equal -> "Even and Odd are the same"  Tried to have a bit of fun with this one: • Input strings are assumed to be of the form "1 2 3" etc. • To save a map call for converting the strings to numbers, I used regular expressions for the partitioning. • Implemented a little helper called tuple2Map for applying a function to both elements of a 2-tuple. • Used an active pattern for deciding which of the sums is greater. Tests: module DailyChallengeTest open FsUnit.Xunit open Xunit open DailyChallenge [<Fact>] let evens > odds() = evenOrOdd "1 2" |> should equal "Even is greater than Odd" [<Fact>] let evens < odds() = evenOrOdd "1 2 3" |> should equal "Odd is greater than Even" [<Fact>] let evens = odds() = evenOrOdd "1 3 4" |> should equal "Even and Odd are the same"  My solution in js  const evenOrOdd = (str) => { const evenCount = (${str}.match(//g) || '').length,
oddCount = (\${str}.match(//g) || '').length;
return (evenCount === oddCount) ? 'Even and Odd are the same' : (evenCount > oddCount ) ? 'Even is greater than Odd' : 'Odd is greater than Even';
};



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"
}


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


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";
}


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');  