Moving a range of elements into an array to a new location can be thought of as a rotating wider range that includes the moved elements at one edge and the destination. The rotation is enough to bring the displaced elements into position and push the others away.
, . , , :
function rotate!(v,n::Int)
l = length(v)
l>1 || return v
n = n % l
n = n < 0 ? n+l : n
n==0 && return v
for i=1:gcd(n,l)
tmp = v[i]
dst = i
src = dst+n
while src != i
v[dst] = v[src]
dst = src
src += n
if src > l
src -= l
end
end
v[dst] = tmp
end
return v
end
move!(A,rng,loc) = begin
rotate!(view(A,min(first(rng),loc):max(last(rng),length(rng)+loc-1)),first(rng)-loc)
return A
end
A = collect(1:9)
@show move!(A,1:3,2) == [4,1,2,3,5,6,7,8,9]
@show move!(A,9:9,3) == [4,1,9,2,3,5,6,7,8]
@show move!(A,3:6,5) == [4,1,6,7,9,2,3,5,8]
. , view , rotate! .