0
– чистый рандом. Порог = 50.–100
— без шансов. Порог = 100.0
и –100
, порог линейно меняется от 50 до 100. 0 1 0 0 1 1 1 0
0 0 1 0 1 1 1 0
1 1 1 0 0 1 1 0
1 1 0 0 1 1 1 0
[0, 1, 3]
и столбцы [1, 5, 6]
весом, соотв., 3 x 3 = 9 следующий_id, предыдущий_id
id next prev
1 2 null
2 3 1 <-- этого забираем
3 4 2
--------------
1 3 null
3 4 1
id next prev
7 8 6 <-- вставить после этого
8 9 7
--------------
7 2 6
2 8 7
8 9 2
2 + 2 + 1 = 5
строк.npm install ml-matrix
документацияimport { Matrix } from 'ml-matrix';
const matrix = new Matrix(12, 31);
x > y
, значит, x = y + ненулевое_число
. Можно так перезаписать слагаемые:m = k0
z = m + k1 = k0 + k1
y = z + k2 = k0 + k1 + k2
x = y + k3 = k0 + k1 + k2 + k3
-----------------------------
m+z+y+x = 4k0 + 3k1 + 2k2 + k3 = SUM
ki — это натуральные числа от 1. k
— вычислили x, y, z, m.k0
k1..k3
уходит минимум 6, когда все по 1,k0
остаётся диапазон [1, (SUM - 6) / 4]
k0
должен быть целым.k0
в этом диапазоне, SUM1 = SUM - 4 * k0
,3k1 + 2k2 + k3 = SUM1
k3
это весь остаток.const addUpTo = (top, n) => {
const getDiffs = (sum, n, acc = []) => {
if (n === 1) {
x = sum;
} else {
const headroom = (n - 1) * n / 2;
const cap = Math.floor((sum - headroom) / n);
if (cap < 1) throw("Impossible. " + JSON.stringify(acc));
x = 1 + Math.floor(Math.random() * cap);
}
acc.push(x);
if (n <= 1) {
return acc;
} else {
return getDiffs(sum - x * n, n - 1, acc);
}
}
return getDiffs(top, n).map((_, i, a) => a.reduce((acc, c, j) => j <= i ? acc + c : acc)).reverse();
}
addUpTo(100, 4) /*
[ 34, 30, 21, 15 ]
[ 31, 24, 23, 22 ]
[ 66, 17, 13, 4 ]
[ 47, 22, 21, 10 ]
...
*/
addUpTo(10, 4) // [ 4, 3, 2, 1 ]
addUpTo(9, 4) // ошибка, невозможно разложить
[x0, x1, ... xN]
.y_true = [f(x0), f(x1), ... f(xN)]
x
получить их «предсказания» y_pred = [Fn(x0), Fn(x1), ... Fn(xN)]
y_true - y_pred
выданных каждой из функций на наборе входных значений x
x = [1, 2, 4, 8, 16, 32, 64]
f(x) = [y0, y1, y2, y3, y4, y5, y6]
// n
[1, 2, 4, 8, 16, 32, 64]
sum = (y0 - 1)^2 + (y1 - 2)^2 + (y2 - 4)^2 + ... + (y6 - 64)^2 = sum0
// n^2
[1, 4, 16, 64, 256, 1024, 4096]
sum = (y0 - 1)^2 + (y1 - 4)^2 + (y2 - 16)^2 + ... + (y6 - 4096)^2 = sum1
// так же посчитать суммы ошибок для остальных функций:
// n * log(n), n!
sumN
укажет функцию, наиболее близкую к искомой. if (A > C) [A, C] = [C, A]; // поменять местами значения A и C
// теперь точно A < B < C
if (X < A) { // вар. 0
} else if (X == A) { // вар. 1
} else if (X < B) { // вар. 2
} else if (X == B) { // вар. 3
} else if (X < C) { // вар. 4
} else if (X == C) { // вар. 5
} else { // X > C // вар. 6
}
A > B > C
и A < B < C
вроде бы подтвердилась, поэтому оставлю первый шаг, где меняем местами A и C, чтобы последовательность точно была возрастающей.0 1 2 3 4 5 6
---o-----o-----o---
A B C
0 1 0 1 0 1 0 1
0 0 1 1 0 0 1 1
0 0 0 0 1 1 1 1
if (A > C) [A, C] = [C, A]; // поменять местами значения A и C
// теперь точно A < B < C
if (X > B) {
if (X > C) { // вар. 6
} else {
if (X == C) { // вар. 5
} else { // вар. 4
}
}
} else {
if (X > A) {
if (X == B) { // вар. 3
} else { // вар. 2
}
} else {
if (X == A) { // вар. 1
} else { // вар. 0
}
}
}
Так менее наглядно и читаемо, но сэкономили на спичках – меньше проверок.const src = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']; // массив элементов
const key = [2, 1, 0]; // номера битов для перемешивания адреса
const mapIndex = (n, key) => key.reduce((p,c,i) => p | ((1 << c & n) >> c) << i, 0);
const biject = (arr, key) => arr.map((e,i) => arr[mapIndex(i, key)]);
console.log( JSON.stringify(biject(src, key)));
// ["a","e","c","g","b","f","d","h"]
console.log( JSON.stringify(biject(src, [1,2,0])));
// ["a","e","b","f","c","g","d","h"]
{
const src = 'abcdefgh'.split('');
const N = src.length; // 8
const Prime = 37; // Prime > N
const mapIndex = (i, N, Prime) => (i * Prime) % N;
//for(let i = 0; i< 8; i++) console.log(i, mapIndex(i, N, Prime))
const shuffle = (str, Prime) => str.split('').map((e,i,a) => a[mapIndex(i, a.length, Prime)]).join('');
console.log( shuffle('abcdefgh', 17));
console.log( shuffle('abcdefgh', 19));
console.log( shuffle('abcdefgh', 23));
console.log( shuffle('abcdefgh', 29));
abcdefgh // не перемешалось
adgbehcf
ahgfedcb
afchebgd
51791
5, 5 + 1786 = 1791, третьим было бы 3577