var arr1 = [1487, 1847, 4817, 4871, 7481, 7841, 8147, 8741];
var res1 = search(arr1);
console.log(res1);
// найдена 1 прогрессия. выведет:
// [
// [ 1487, 4817, 8147 ]
// ]
var arr2 = [1487, 1847, 4817, 4871, 7481, 7841, 8147, 8741, 10001];
var res2 = search(arr2);
console.log(res2);
// найдено 2 прогрессии. выведет:
// [
// [ 1487, 4817, 8147 ],
// [ 7481, 8741, 10001 ]
// ]
function search(a){
// создадим массив, в который будем заносить данные о найденых прогрессиях
var result = [];
// проверяем в цикле все числа
for(var start=0; start<a.length; start++){
for(var i=start+1; i<a.length; i++){
// вычисляем предпологаемый шаг прогрессии
var step = a[i]-a[start];
// и проверяем его.
// создаем массив, в который складываем
// числа предполагаемой прогрессии
var list = [ a[start], a[i] ];
// смотрим в цикле следующие числа
for(var j = i+1; j< a.length; j++){
// если следующее число - шаг прогрессии равно
// последнему занесенному в массив list
// то добавляем его в массив list
if( a[j]-step == list[list.length-1]){
list.push(a[j]);
}
}
// если в массиве 3 элемента или более, то считаем что
// еще одна прогрессия найдена и запоминаем ее в
// массиве с результатами
if( list.length>2){
result.push(list);
}
console.log(start, i, step, list)
}
}
// возвращаем массив результатов
return result;
}
import numpy as np
from collections import deque
from itertools import combinations
# data = np.array([1487, 1847, 4817, 4871, 7481, 7841, 8147, 8741])
np.random.seed(42)
data = np.random.randint(0, 100000, 1000)
data.sort()
# Интуитивный подход (baseline), O(n^3)
def find_evenly_spaced_v1(data):
for a, b, c in combinations(data, 3):
if b - a == c - b:
yield a, b, c
# Эмпирическая оптимизация, O(n^2)
def find_evenly_spaced_v2(data):
dataset = set(data)
for a, c in combinations(data, 2):
b, mod = divmod(a + c, 2)
if (mod == 0) and (b in dataset):
yield a, b, c
# Векторный вариант
def find_evenly_spaced_v3(data):
grid = data.reshape(-1, 1) + data.reshape(1, -1)
divs, mods = np.divmod(grid, 2)
mask = np.tri(*grid.shape, -1, dtype='bool') & np.isin(divs, data) & ~ mods.astype('bool')
for c, a in zip(*np.where(mask)):
b = divs[a, c]
a, c = data[[a, c]]
yield a, b, c