EDYTOWAĆ::
Hej, więc okazuje się, że dzieje się zbyt wiele iteracji. Żadnych pętli, żadnych rozgałęzień.
Nadal działa z ujemnym n dla obrotu w prawo i dodatnim n dla obrotu w lewo dla dowolnego rozmiaru n, bez mutacji
function rotate(A,n,l=A.length) {
const offset = (((n % l) + l) %l)
return A.slice(offset).concat(A.slice(0,offset))
}
Oto wersja kodu golfowego dla chichotów
const r = (A,n,l=A.length,i=((n%l)+l)%l)=>A.slice(i).concat(A.slice(0,i))
EDIT1 :: *
Bezgałęziowa, bez mutacji implementacja.
Więc hej, okazuje się, że miałem gałąź, w której jej nie potrzebowałem. Oto działające rozwiązanie. ujemna liczba = prawy obrót o | num | dodatnia liczba = lewo obrót o num
function r(A,n,l=A.length) {
return A.map((x,i,a) => A[(((n+i)%l) + l) % l])
}
Równanie ((n%l) + l) % l
odwzorowuje dokładnie dodatnie i ujemne liczby dowolnie dużych wartości n
ORYGINAŁ
Obróć w lewo iw prawo. Obróć w lewo z dodatnim n
, obróć w prawo z ujemnymn
.
Działa w przypadku nieprzyzwoicie dużych danych wejściowych n
.
Brak trybu mutacji. Za dużo mutacji w tych odpowiedziach.
Ponadto mniej operacji niż większość odpowiedzi. Bez popu, bez pchania, bez łączenia, bez przesunięcia.
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]
})
}
lub
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])
})
Wyjaśnienie:
odwzorowuj każdy indeks A na wartość przy przesunięciu indeksu. W tym przypadku
offset = num
jeśli offset < 0
wtedyoffset + index + positive length of A
wskaże odwrotne przesunięcie.
Jeśli offset > 0 and offset < length of A
następnie po prostu zamapuj bieżący indeks na indeks przesunięcia A.
W przeciwnym razie zamodulo przesunięcie i długość, aby odwzorować przesunięcie w granicach tablicy.
Weźmy na przykład offset = 4
i offset = -4
.
Kiedy offset = -4
i A = [1,2,3,4,5]
dla każdego wskaźnika, offset + index
wielkość (lub Math.abs(offset)
) będzie mniejsza.
Wyjaśnijmy najpierw obliczenie indeksu ujemnego n. A[(((n % A.length) + A.length) % A.length)+0]
i był onieśmielony. Nie bądź. Rozpracowanie tego zajęło mi 3 minuty w replice.
- Wiemy, że
n
jest negatywny, ponieważ tak jest n < 0
. Jeśli liczba jest większa niż zakres Array, n % A.length
zamapuje ją na zakres.
n + A.length
dodaj tę liczbę do A.length
przesunięcia n do prawidłowej kwoty.
- Wiemy, że
n
jest negatywny, ponieważ tak jest n < 0
. n + A.length
dodaj tę liczbę do A.length
przesunięcia n do prawidłowej kwoty.
Następnie odwzoruj go na zakres długości A za pomocą modulo. Drugi moduł jest niezbędny do odwzorowania wyniku obliczenia na indeksowalny zakres
Pierwszy indeks: -4 + 0 = -4. A. długość = 5. A. długość - 4 = 1. A 2 to 2. Odwzoruj indeks od 0 do 2.[2,... ]
- Następny indeks, -4 + 1 = -3. 5 + -3 = 2. A 2 to 3. Odwzoruj indeks od 1 do 3.
[2,3... ]
- Itp.
Ten sam proces dotyczy offset = 4
. Kiedy offset = -4
i A = [1,2,3,4,5]
dla każdego indeksu offset + index
zwiększy wielkość.
4 + 0 = 0
. Zamapuj A [0] na wartość w A [4].[5...]
4 + 1 = 5
, 5 jest poza zakresem podczas indeksowania, więc zamapuj A 2 na wartość w pozostałej części 5 / 5
, czyli 0. A 2 = wartość w A [0].[5,1...]
- powtarzać.
months[new Date().getMonth()]
nazwy bieżącego miesiąca?