This post is a little bit different from the last ones. Days 1-12 followed more or less strictly what HackerRank 30 days of code Tutorial had, but starting on day 13 there was a series of challenges that didn’t allow me to use Go. They are more specific to object-oriented languages like C++ and Java. As Go doesn’t have all the constructions these languages allow, like abstract classes, at least not without a workaround, I decided to take other challenges on HackerRank. The one for today is about statistics and I will introduce some of the concepts before showing the code solution.

Statistics: Mean, Median and Mode

These simple statistics concepts can be easily learned at Wikipedia, but I will do a quick recap here using my own words considering an array of numbers.

  • Mean - considering an array of numbers, the mean is the sum of the components divided by the length of the array: $\mu(\mathbf{x}) = \frac{1}{n}\sum_{i=1}^n x_i$. Example: the mean of $1,; 2,; 3,; 3,; 4,; 5,; 5$ is $\frac{23} {7}\approx 3.286$.
  • Median - the number in the middle of the array. There is a catch if the array has an even number of elements. In this case, the average of the two middle elements is taken. Example: $1,; 2,; 3,; 3,; 4,; 5,; 5$ has median 3 and $1,; 2,; 3,; 3,; 4,; 5,; 5,; 5$ has median 3.5.
  • Mode - the most frequent number that appears in the array. There can be many modes if there are many numbers that appear with the same frequency. Example: $1,; 2,; 3,; 3,; 4,; 5,; 5$ has modes 3 and 5 while $1,; 2,; 3,; 3,; 4,; 5,; 5,; 5$ has a single mode which is 5.

Problem description and code

This problem requires the program to read an int n indicating the number of integer elements that will be read later as part of our array. After reading the data, it should print the mean, median and mode on the screen, each one on one line. My solution is presented now.

package main

import (
  "fmt"
  "sort"
)

// no actual need for that
// but it is good to encapsulate
// data to return in the function
type Stats struct {
  mean   float64
  median float64
  mode   int
}

// Returns smallest mode of array
func GetMode(array []int) int {
  mode := 0
  occurrences := 0
  currentValue := array[0]
  currentOccurrences := 0
  n := len(array)
  for i := 0; i < n; i++ {
    if array[i] != currentValue {
      if currentOccurrences > occurrences {
        mode = currentValue
        occurrences = currentOccurrences
      }
      currentOccurrences = 1
      currentValue = array[i]
    } else {
      currentOccurrences++
    }
  }

  return mode
}

func GetStats(array []int) *Stats {
  sum := 0.0
  n := len(array)
  // sorting for median and mode
  sort.Ints(array)
  for i := 0; i < n; i++ {
    sum += float64(array[i])
  }
  mean := sum / float64(n)
  median := float64(array[n/2]+array[n/2-1]) / 2.0
  if n%2 == 1 {
    median = float64(array[n/2])
  }

  mode := GetMode(array)

  stats := new(Stats)
  stats.mean = mean
  stats.median = median
  stats.mode = mode

  return stats
}

func main() {
  var N int
  var array []int
  fmt.Scanf("%d", &N)
  array = make([]int, N)
  for i := 0; i < N; i++ {
    fmt.Scanf("%d", &array[i])
  }

  answer := GetStats(array)
  fmt.Printf("%.1f\n", answer.mean)
  fmt.Printf("%.1f\n", answer.median)
  fmt.Printf("%d\n", answer.mode)
}

One of the things that took me some time was figuring out how to do sorting properly. I tried to use sort.Sort first but I was just getting lots of compiler errors saying the int array didn’t implement the sort.Interface. It was really frustrating. Luckly I found an example quickly.

If you have any doubts or comments, please do!