C# Peaks
static int Peaks(int[] a)
{
    var n = a.Length;
    if (n <= 2)
    {
        return 0;
    }

    var sum = new int[n];
    var last = -1;
    var dist = 0;

    for (int i = 1; i + 1 < n; i++)
    {
        sum[i] = sum[i - 1];
        if (a[i] > a[i - 1] && a[i] > a[i + 1])
        {
            dist = Math.Max(dist, i - last);
            last = i;
            sum[i]++;
        }
    }

    sum[n - 1] = sum[n - 2];
    if (sum[n - 1] == 0)
    {
        return 0;
    }

    dist = Math.Max(dist, n - last);

    for (int i = (dist >> 1) + 1; i < dist; i++)
    {
        if (n % i == 0)
        {
            last = 0;
            int j;
            for (j = i; j <= n; j += i)
            {
                if (sum[j - 1] <= last)
                {
                    break;
                }
                last = sum[j - 1];
            }
            if (j > n)
            {
                return n / i;
            }
        }
    }

    for (last = dist; n % last != 0;)
    {
        last++;
    }

    return n / last;
}

This finds the peak positions, then tests how many equal blocks can each contain at least one peak.