EDITAR::
Ei, acontece que há muita iteração acontecendo. Sem loops, sem ramificação.
Ainda funciona com n negativo para rotação à direita e n positivo para rotação à esquerda para qualquer tamanho n, sem mutação
function rotate(A,n,l=A.length) {
const offset = (((n % l) + l) %l)
return A.slice(offset).concat(A.slice(0,offset))
}
Aqui está a versão do código de golfe para risos
const r = (A,n,l=A.length,i=((n%l)+l)%l)=>A.slice(i).concat(A.slice(0,i))
EDIT1 :: *
Implementação sem ramificações e sem mutação.
Então, ei, descobri que eu tinha um galho que não precisava. Aqui está uma solução de trabalho. num negativo = girar para a direita por | num | num positivo = girar para a esquerda por num
function r(A,n,l=A.length) {
return A.map((x,i,a) => A[(((n+i)%l) + l) % l])
}
A equação ((n%l) + l) % l
mapeia números exatamente positivos e negativos de quaisquer valores arbitrariamente grandes de n
ORIGINAL
Gire para a esquerda e para a direita. Gire para a esquerda com positivo n
, gire para a direita com negativo n
.
Funciona para entradas obscenamente grandes de n
.
Sem modo de mutação. Muita mutação nessas respostas.
Além disso, menos operações do que a maioria das respostas. Sem estalo, sem empurrar, sem emenda, sem mudança.
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]
})
}
ou
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])
})
Explicação:
mapeie cada índice de A para o valor no deslocamento do índice. Nesse caso
offset = num
se o offset < 0
then offset + index + positive length of A
irá apontar para o deslocamento inverso.
se, offset > 0 and offset < length of A
então, simplesmente mapeie o índice atual para o índice de deslocamento de A.
Caso contrário, module o deslocamento e o comprimento para mapear o deslocamento nos limites da matriz.
Tomemos por exemplo offset = 4
e offset = -4
.
Quando offset = -4
, e A = [1,2,3,4,5]
, para cada índice, offset + index
tornará a magnitude (ou Math.abs(offset)
) menor.
Vamos explicar o cálculo do índice de n negativo primeiro. A[(((n % A.length) + A.length) % A.length)+0]
e foi intimidado. Não sinta. Levei 3 minutos em um Repl para resolver isso.
- Sabemos que
n
é negativo porque o caso é n < 0
. Se o número for maior do que o intervalo do Array, n % A.length
irá mapeá-lo para o intervalo.
n + A.length
adicione esse número para A.length
compensar na quantidade correta.
- Sabemos que
n
é negativo porque o caso é n < 0
. n + A.length
adicione esse número aA.length
compensar na quantidade correta.
Próximo Mapeie-o para a faixa de comprimento de A usando módulo. O segundo módulo é necessário para mapear o resultado do cálculo em uma faixa indexável
Primeiro índice: -4 + 0 = -4. A.length = 5. a.length - 4 = 1. A 2 é 2. Mapa índice de 0 a 2.[2,... ]
- Próximo índice, -4 + 1 = -3. 5 + -3 = 2. A 2 é 3. Índice do mapa 1 a 3.
[2,3... ]
- Etc.
O mesmo processo se aplica a offset = 4
. Quando offset = -4
, e A = [1,2,3,4,5]
, para cada índice, offset + index
aumentará a magnitude.
4 + 0 = 0
. Mapeie A [0] para o valor em A [4].[5...]
4 + 1 = 5
, 5 está fora dos limites durante a indexação, então mapeie A 2 para o valor no restante de 5 / 5
, que é 0. A 2 = valor em A [0].[5,1...]
- repetir.
months[new Date().getMonth()]
para obter o nome do mês atual?