Problem: Statistics from a Large Sample

You are given a large sample of integers in the range `[0, 255]`. Since the
sample is so large, it is represented by an array `count` where `count[k]` is
the number of times that `k` appears in the sample.

Calculate the following statistics:

* `minimum`: The minimum element in the sample.
* `maximum`: The maximum element in the sample.
* `mean`: The average of the sample, calculated as the total sum of all elements divided by the total number of elements.
* `median`: 
* If the sample has an odd number of elements, then the `median` is the middle element once the sample is sorted.
* If the sample has an even number of elements, then the `median` is the average of the two middle elements once the sample is sorted.
* `mode`: The number that appears the most in the sample. It is guaranteed to be unique.

Return the statistics of the sample as an array of floating-point numbers
`[minimum, maximum, mean, median, mode]`. Answers within `10-5` of the actual
answer will be accepted.


Python solution:
import math
import itertools
import bisect
import collections
import string
import heapq
import functools
import sortedcontainers
from typing import List, Dict, Tuple, Iterator

class Solution:
  def sampleStats(self, count: List[int]) -> List[float]:
    minimum = next((i for i, num in enumerate(count) if num), None)
    maximum = next((i for i, num in reversed(list(enumerate(count))) if num), None)
    n = sum(count)
    mean = sum(i * c / n for i, c in enumerate(count))
    mode = count.index(max(count))

    numCount = 0
    leftMedian = 0
    for i, c in enumerate(count):
      numCount += c
      if numCount >= n / 2:
        leftMedian = i
        break

    numCount = 0
    rightMedian = 0
    for i, c in reversed(list(enumerate(count))):
      numCount += c
      if numCount >= n / 2:
        rightMedian = i
        break

    return [minimum, maximum, mean, (leftMedian + rightMedian) / 2, mode]


Java solution:
class Solution {
  public double[] sampleStats(int[] count) {
    final int n = Arrays.stream(count).sum();
    return new double[] {
        getMinimum(count),                                          //
        getMaximum(count),                                          //
        getMean(count, n),                                          //
        (getLeftMedian(count, n) + getRightMedian(count, n)) / 2.0, //
        getMode(count),
    };
  }

  private double getMinimum(int[] count) {
    for (int i = 0; i < count.length; ++i)
      if (count[i] > 0)
        return i;
    return -1;
  }

  private double getMaximum(int[] count) {
    for (int i = count.length - 1; i >= 0; --i)
      if (count[i] > 0)
        return i;
    return -1;
  }

  private double getMean(int[] count, double n) {
    double mean = 0;
    for (int i = 0; i < count.length; ++i)
      mean += ((long) i * (long) count[i]) / n;
    return mean;
  }

  private double getLeftMedian(int[] count, double n) {
    int numCount = 0;
    for (int i = 0; i < count.length; ++i) {
      numCount += count[i];
      if (numCount >= n / 2)
        return i;
    }
    return -1;
  }

  private double getRightMedian(int[] count, double n) {
    int numCount = 0;
    for (int i = count.length - 1; i >= 0; --i) {
      numCount += count[i];
      if (numCount >= n / 2)
        return i;
    }
    return -1;
  }

  private double getMode(int[] count) {
    int mode = -1;
    int maxCount = 0;
    for (int i = 0; i < count.length; ++i)
      if (count[i] > maxCount) {
        maxCount = count[i];
        mode = i;
      }
    return mode;
  }
}


C++ solution:
class Solution {
 public:
  vector<double> sampleStats(vector<int>& count) {
    const int n = accumulate(count.begin(), count.end(), 0);
    const double mode = ranges::max_element(count) - count.begin();
    return {
        getMinimum(count),
        getMaximum(count),
        getMean(count, n),
        (getLeftMedian(count, n) + getRightMedian(count, n)) / 2.0,
        mode,
    };
  }

 private:
  double getMinimum(const vector<int>& count) {
    for (int i = 0; i < count.size(); ++i)
      if (count[i])
        return i;
    return -1;
  }

  double getMaximum(const vector<int>& count) {
    for (int i = count.size() - 1; i >= 0; --i)
      if (count[i])
        return i;
    return -1;
  }

  double getMean(const vector<int>& count, double n) {
    double mean = 0;
    for (long i = 0; i < count.size(); ++i)
      mean += (i * count[i]) / n;
    return mean;
  }

  double getLeftMedian(const vector<int>& count, double n) {
    int numCount = 0;
    for (int i = 0; i < count.size(); ++i) {
      numCount += count[i];
      if (numCount >= n / 2)
        return i;
    }
    return -1;
  }

  double getRightMedian(const vector<int>& count, double n) {
    int numCount = 0;
    for (int i = count.size() - 1; i >= 0; --i) {
      numCount += count[i];
      if (numCount >= n / 2)
        return i;
    }
    return -1;
  }
};