Start learning free

LESSON 144 OF 338 · LOOPS & GLOBAL VARIABLES

Odd or Even Majority in Go: Counting with the Modulo Operator

Practice Read the full explanation

Given an array, return true if there are more odd numbers than even numbers, otherwise return false.

Example:

Input: numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
Output: true

Explanation:
There are 5 odd numbers in the array: 1, 3, 5, 7, 9
There are 4 even numbers in the array: 2, 4, 6, 8
5 is greater than 4, so our functions should return true
STEP 1 OF 5
    Ctrl + Enter to check

    GO · LOOPS & GLOBAL VARIABLES

    Odd Even in Go, explained

    Problem overview

    The function oddEven receives a slice of integers, numbers, and returns true if the slice contains more odd numbers than even numbers. Otherwise, including when the counts are equal, it returns false.

    For [1, 2, 3, 4, 5, 6, 7, 8, 9] there are five odd numbers (1, 3, 5, 7, 9) and four even numbers (2, 4, 6, 8). Five is greater than four, so the answer is true.

    Approach

    Count the odd numbers and the even numbers in a single pass, then compare the two counts. Every element is either odd or even, so each one increments exactly one of two counters. After the loop, the answer is whether the odd counter is strictly larger.

    The test for oddness uses the remainder operator %. An even number leaves remainder 0 when divided by 2, and an odd number leaves a non-zero remainder. Writing the test as "remainder is not 0" is more robust than "remainder is 1", and the reason is specific to Go and several other languages.

    Step by step

    1. Declare two counters. oddNumbers := 0 and evenNumbers := 0 each infer the type int from the literal 0.
    2. Loop over the slice with for ... range, naming the element number. The index is not needed, and Go does not allow unused variables, so it goes to the blank identifier _.
    3. Test for odd. Inside the loop, an if checks that number % 2 is not 0. When it is, increment oddNumbers.
    4. Handle even. An else branch covers the other case. Go requires else on the same line as the closing brace of the if block, as in } else {.
    5. Return the comparison. oddNumbers > evenNumbers is already a bool, so it can be returned directly without an if.

    The solution in Go

    func oddEven(numbers []int) bool {
        oddNumbers := 0
        evenNumbers := 0
        for _, number := range numbers {
            if number % 2 != 0 {
                oddNumbers += 1
            } else {
                evenNumbers += 1
            }
        }
        return oddNumbers > evenNumbers
    }
    

    The Go details worth knowing:

    • The sign of %. In Go, the result of % takes the sign of the dividend, the number on the left. So 7 % 2 is 1, but -7 % 2 is -1, not 1. A test written as number % 2 == 1 would classify every negative odd number as even. The test number % 2 != 0 works for positive and negative numbers alike, because odd numbers leave 1 or -1 and even numbers leave 0.
    • Counting both sides. Because the final comparison is strict, a tie returns false. Counting both kinds is needed only because the comparison involves both counts; you could also keep a single balance that goes up for an odd number and down for an even one, and return whether it is positive at the end.
    • += 1 or ++. Both increment a counter. The lesson uses += 1; oddNumbers++ is the more common Go style. Either is a statement and not an expression.
    • Returning a comparison. A condition like a > b already has the type bool, so if a > b { return true }; return false is just a longer way to write return a > b.

    Complexity

    Time: O(n). One pass over the n elements, with constant work for each.

    Space: O(1). Only the two counters and the loop variable are stored.

    Edge cases and common mistakes

    • Negative odd numbers. For [-1, -3, 2], the answer is true: two odd numbers against one even. Testing number % 2 == 1 would count -1 and -3 as even and wrongly return false.
    • Zero. 0 is even, and 0 % 2 is 0, so it is counted as even.
    • A tie. [1, 2] has one of each, and the result is false. Using >= would be a bug.
    • An empty or nil slice. Both counters stay 0, and 0 > 0 is false.
    • Putting else on a new line. A line that begins with else is a syntax error in Go.

    Testing

    • []int{1, 2, 3, 4, 5, 6, 7, 8, 9} gives true.
    • []int{-1, -3, 2} gives true.
    • []int{1, 2} gives false.
    • []int{} gives false.
    Keep going with GoAbout 340 step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free