РЕДАКТИРОВАТЬ::
Эй, оказывается, происходит слишком много итераций. Ни петель, ни ветвлений.
По-прежнему работает с отрицательным n для правого вращения и положительным n для левого вращения для любого размера n, без мутаций
function rotate(A,n,l=A.length) {
const offset = (((n % l) + l) %l)
return A.slice(offset).concat(A.slice(0,offset))
}
Вот код версии гольфа для хихиканья
const r = (A,n,l=A.length,i=((n%l)+l)%l)=>A.slice(i).concat(A.slice(0,i))
РЕДАКТИРОВАТЬ1 :: *
и мутаций.
Так что, оказывается, у меня была ветка, где она мне не нужна. Вот рабочее решение. отрицательное число = повернуть вправо на | число | положительное число = повернуть влево на число
function r(A,n,l=A.length) {
return A.map((x,i,a) => A[(((n+i)%l) + l) % l])
}
Уравнение ((n%l) + l) % l
отображает точно положительные и отрицательные числа любых сколь угодно больших значений n
ОРИГИНАЛ
Поверните влево и вправо. Повернуть влево с положительным n
, повернуть вправо с отрицательным n
.
Работает для неприлично больших входов n
.
Нет режима мутации. В этих ответах слишком много мутаций.
Кроме того, меньше операций, чем большинство ответов. Ни хлопка, ни толчка, ни стыковки, ни сдвига.
const rotate = (A, num ) => {
return A.map((x,i,a) => {
const n = num + i
return n < 0
? A[(((n % A.length) + A.length) % A.length)]
: n < A.length
? A[n]
: A[n % A.length]
})
}
или
const rotate = (A, num) => A.map((x,i,a, n = num + i) =>
n < 0
? A[(((n % A.length) + A.length) % A.length)]
: n < A.length
? A[n]
: A[n % A.length])
rotate([...Array(5000).keys()],4101)
rotate([...Array(5000).keys()],-4101000)
[...Array(5000).keys()].forEach((x,i,a) => {
console.log(rotate(a,-i)[0])
})
[...Array(5000).keys()].forEach((x,i,a) => {
console.log(rotate(a,i*2)[0])
})
Пояснение:
сопоставить каждый индекс A со значением при смещении индекса. В этом случае
offset = num
если offset < 0
тогда offset + index + positive length of A
будет указывать на обратное смещение.
если offset > 0 and offset < length of A
тогда просто сопоставьте текущий индекс с индексом смещения A.
В противном случае сложите по модулю смещение и длину, чтобы сопоставить смещение в границах массива.
Взять, к примеру, offset = 4
и offset = -4
.
Когда offset = -4
, и A = [1,2,3,4,5]
для каждого индекса offset + index
сделает величину (или Math.abs(offset)
) меньше.
Давайте сначала объясним расчет индекса отрицательного n. A[(((n % A.length) + A.length) % A.length)+0]
и был запуган. Не надо. Мне потребовалось 3 минуты в Repl, чтобы разобраться.
- Мы знаем, что
n
это отрицательно, потому что это так n < 0
. Если число больше диапазона массива, n % A.length
отобразит его в диапазоне.
n + A.length
прибавьте это число к, A.length
чтобы компенсировать n правильной суммы.
- Мы знаем, что
n
это отрицательно, потому что это так n < 0
. n + A.length
добавить это число кA.length
чтобы компенсировать n правильной суммы.
Затем сопоставьте его с диапазоном длины A по модулю. Второй модуль необходим для отображения результата расчета в индексируемый диапазон.
Первый индекс: -4 + 0 = -4. A.length = 5. A.length - 4 = 1. A 2 равно 2. Сопоставьте индекс от 0 до 2.[2,... ]
- Следующий индекс -4 + 1 = -3. 5 + -3 = 2. 2 равно 3. Отобразить индексы с 1 по 3.
[2,3... ]
- И т.п.
Тот же процесс применяется к offset = 4
. Когда offset = -4
, и A = [1,2,3,4,5]
для каждого индекса offset + index
увеличивают величину.
4 + 0 = 0
. Сопоставьте A [0] со значением A [4].[5...]
4 + 1 = 5
, 5 выходит за пределы при индексировании, поэтому сопоставьте A 2 со значением в оставшейся части 5 / 5
, равным 0. A 2 равным = значение в A [0].[5,1...]
- повторение.
months[new Date().getMonth()]
для получения названия текущего месяца?