Ok, so I added an enhancement and some extra comments to help (hopefully) in realizing the algorithm behind the swapping:
clear all
clc
fid = fopen('Circular Shift input.txt'); % Open file where input arrays and
% circular shift key are located
C = {}; % Cell to store input arrays
SK = []; % Array to store shift keys
flag = 1; % Flag to indicate whether shift key or
% array is being extracted
fresult = {}; % Cell to store shifted arrays
n = 1;
while ~feof(fid) % Read input arrays until end of file
tline = fgetl(fid); % Read current line
if mod(flag,2) % Shift key is being identified
flag = flag + 1;
k = 0; % Identify shift left or right
if (k+1 < length(tline))
while ~isequal(tline(k+1),' ')
k = k + 1;
end
else
error('Wrong input for demanding circular shift.');
end
tline = tline(k+2:end);
if isequal('-',tline(1))
SK(n) = str2double(tline(2:end))*(-1);
disp('Shift to left');
else
SK(n) = str2double(tline);
if ~SK(n)
disp('No shift performed');
else
disp('Shift to right');
end
end
n = n + 1;
else
flag = flag + 1;
k = 0; % Identify input array
if (k+1 < length(tline))
while ~isequal(tline(k+1),' ')
k = k + 1;
end
else
error('Wrong entry of input array.');
end
tline = tline(k+2:end);
cnt = 1;
while ~isempty(tline)
k = 0;
if (k+1 < length(tline))
while (k < length(tline))&&(~isequal(tline(k+1),' '))
k = k + 1;
end
else
k = 1;
end
C{n-1}(cnt) = str2double(tline(1:k));
cnt = cnt + 1;
if (length(tline) > 1)
tline = tline(k+2:end);
else
tline = [];
end
end
if (abs(SK(n-1)) > length(C{n-1}))
% Key size exceeds length of array
if (SK(n-1) > 0)
SK(n-1) = mod(SK(n-1),length(C{n-1}));
else
SK(n-1) = -mod(abs(SK(n-1)),length(C{n-1}));
end
end
if (SK(n-1) > 0) % Peforming circular shift
N = SK(n-1);
fresult{n-1} = C{n-1};
if mod(length(C{n-1}),2) % Array has an odd number of entries
if (N <= (length(C{n-1})-1)/2) % Key is smaller than or equal to half the size of the array
for i = 1:length(C{n-1})-1
if isequal(N,SK(n-1))
N = 1;
else
N = N + 1;
end
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - SK(n-1) + N);
fresult{n-1}(end - SK(n-1) + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',num2str(i),...
',',num2str(length(C{n-1}) - SK(n-1) + N),')'));
disp(num2str(fresult{n-1}));
end
else % Key is greater than half the size of the array
for i = 1:length(C{n-1})-1
if isequal(N,SK(n-1))
N = 1;
else
N = N + 1;
end
if (i <= SK(n-1))
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - SK(n-1) + N);
fresult{n-1}(end - SK(n-1) + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',...
num2str(i),',',...
num2str(length(C{n-1}) - SK(n-1) + N),')'));
disp(num2str(fresult{n-1}));
else
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end);
fresult{n-1}(end) = temp;
disp(strcat('Step',num2str(i),': Swap (',...
num2str(i),',',num2str(length(C{n-1})),')'));
disp(num2str(fresult{n-1}));
end
end
end
else % Array has an even number of entries
if (N <= (length(C{n-1})-1)/2) % Key is smaller than or equal to half the size of the array
for i = 1:length(C{n-1})-SK(n-1)
if isequal(N,SK(n-1))
N = 1;
else
N = N + 1;
end
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - SK(n-1) + N);
fresult{n-1}(end - SK(n-1) + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',num2str(i),...
',',num2str(length(C{n-1}) - SK(n-1) + N),')'));
disp(num2str(fresult{n-1}));
end
else % Key is greater than half the size of the array
for i = 1:SK(n-1)
if isequal(N,SK(n-1))
N = 1;
else
N = N + 1;
end
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - SK(n-1) + N);
fresult{n-1}(end - SK(n-1) + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',num2str(i),...
',',num2str(length(C{n-1}) - SK(n-1) + N),')'));
disp(num2str(fresult{n-1}));
end
end
end
elseif ~SK(n-1)
fresult{n-1} = C{n-1};
else
tS = length(C{n-1}) + SK(n-1);
N = tS;
fresult{n-1} = C{n-1};
if mod(length(C{n-1}),2) % Array has an odd number of entries
if (N <= (length(C{n-1})-1)/2) % Key is smaller than or equal to half the size of the array
for i = 1:length(C{n-1})-1
if isequal(N,tS)
N = 1;
else
N = N + 1;
end
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - tS + N);
fresult{n-1}(end - tS + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',num2str(i),...
',',num2str(length(C{n-1}) - tS + N),')'));
disp(num2str(fresult{n-1}));
end
else % Key is greater than half the size of the array
for i = 1:length(C{n-1})-1
if isequal(N,tS)
N = 1;
else
N = N + 1;
end
if (i <= tS)
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - tS + N);
fresult{n-1}(end - tS + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',...
num2str(i),',',...
num2str(length(C{n-1}) - tS + N),')'));
disp(num2str(fresult{n-1}));
else
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end);
fresult{n-1}(end) = temp;
disp(strcat('Step',num2str(i),': Swap (',...
num2str(i),',',num2str(length(C{n-1})),')'));
disp(num2str(fresult{n-1}));
end
end
end
else % Array has an even number of entries
if (N <= (length(C{n-1})-1)/2) % Key is smaller than or equal to half the size of the array
for i = 1:length(C{n-1})-tS
if isequal(N,tS)
N = 1;
else
N = N + 1;
end
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - tS + N);
fresult{n-1}(end - tS + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',num2str(i),...
',',num2str(length(C{n-1}) - tS + N),')'));
disp(num2str(fresult{n-1}));
end
else % Key is greater than half the size of the array
for i = 1:tS
if isequal(N,tS)
N = 1;
else
N = N + 1;
end
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - tS + N);
fresult{n-1}(end - tS + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',num2str(i),...
',',num2str(length(C{n-1}) - tS + N),')'));
disp(num2str(fresult{n-1}));
end
end
end
end
disp('The resulting shifted array is:');
disp(num2str(fresult{n-1}));
end
end
status = fclose(fid); % Close file
Note that the most part of the code is reading a text file which has the shift keys and the input arrays entered:
while ~feof(fid) % Read input arrays until end of file
tline = fgetl(fid); % Read current line
if mod(flag,2) % Shift key is being identified
flag = flag + 1;
k = 0; % Identify shift left or right
if (k+1 < length(tline))
while ~isequal(tline(k+1),' ')
k = k + 1;
end
else
error('Wrong input for demanding circular shift.');
end
tline = tline(k+2:end);
if isequal('-',tline(1))
SK(n) = str2double(tline(2:end))*(-1);
disp('Shift to left');
else
SK(n) = str2double(tline);
if ~SK(n)
disp('No shift performed');
else
disp('Shift to right');
end
end
n = n + 1;
else
flag = flag + 1;
k = 0; % Identify input array
if (k+1 < length(tline))
while ~isequal(tline(k+1),' ')
k = k + 1;
end
else
error('Wrong entry of input array.');
end
tline = tline(k+2:end);
cnt = 1;
while ~isempty(tline)
k = 0;
if (k+1 < length(tline))
while (k < length(tline))&&(~isequal(tline(k+1),' '))
k = k + 1;
end
else
k = 1;
end
C{n-1}(cnt) = str2double(tline(1:k));
cnt = cnt + 1;
if (length(tline) > 1)
tline = tline(k+2:end);
else
tline = [];
end
end
...
This is the enhancement made for when the shift key is greater than the size of the array:
if (abs(SK(n-1)) > length(C{n-1}))
% Key size exceeds length of array
if (SK(n-1) > 0)
SK(n-1) = mod(SK(n-1),length(C{n-1}));
else
SK(n-1) = -mod(abs(SK(n-1)),length(C{n-1}));
end
end
As for the jist of the code, it lies here (note that the same code is used for a shift key with a negative value but the shift is done according to "length(array) + shift key negative value" because as George pointed out previously a shift to the left is the same as a shift to the right by a shift key of "length(array) + shift key negative value"):
if (SK(n-1) > 0) % Peforming circular shift
N = SK(n-1);
fresult{n-1} = C{n-1};
if mod(length(C{n-1}),2) % Array has an odd number of entries
if (N <= (length(C{n-1})-1)/2) % Key is smaller than or equal to half the size of the array
for i = 1:length(C{n-1})-1
if isequal(N,SK(n-1))
N = 1;
else
N = N + 1;
end
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - SK(n-1) + N);
fresult{n-1}(end - SK(n-1) + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',num2str(i),...
',',num2str(length(C{n-1}) - SK(n-1) + N),')'));
disp(num2str(fresult{n-1}));
end
else % Key is greater than half the size of the array
for i = 1:length(C{n-1})-1
if isequal(N,SK(n-1))
N = 1;
else
N = N + 1;
end
if (i <= SK(n-1))
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - SK(n-1) + N);
fresult{n-1}(end - SK(n-1) + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',...
num2str(i),',',...
num2str(length(C{n-1}) - SK(n-1) + N),')'));
disp(num2str(fresult{n-1}));
else
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end);
fresult{n-1}(end) = temp;
disp(strcat('Step',num2str(i),': Swap (',...
num2str(i),',',num2str(length(C{n-1})),')'));
disp(num2str(fresult{n-1}));
end
end
end
else % Array has an even number of entries
if (N <= (length(C{n-1})-1)/2) % Key is smaller than or equal to half the size of the array
for i = 1:length(C{n-1})-SK(n-1)
if isequal(N,SK(n-1))
N = 1;
else
N = N + 1;
end
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - SK(n-1) + N);
fresult{n-1}(end - SK(n-1) + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',num2str(i),...
',',num2str(length(C{n-1}) - SK(n-1) + N),')'));
disp(num2str(fresult{n-1}));
end
else % Key is greater than half the size of the array
for i = 1:SK(n-1)
if isequal(N,SK(n-1))
N = 1;
else
N = N + 1;
end
temp = fresult{n-1}(i);
fresult{n-1}(i) = fresult{n-1}(end - SK(n-1) + N);
fresult{n-1}(end - SK(n-1) + N) = temp;
disp(strcat('Step',num2str(i),': Swap (',num2str(i),...
',',num2str(length(C{n-1}) - SK(n-1) + N),')'));
disp(num2str(fresult{n-1}));
end
end
end
...
For the example you gave me Skafi:
rotate: -2
array: 0 1 2 3 4 5 6 7 8
The answer would be:
Shift to left
Step1: Swap (1,3)
2 1 0 3 4 5 6 7 8
Step2: Swap (2,4)
2 3 0 1 4 5 6 7 8
Step3: Swap (3,5)
2 3 4 1 0 5 6 7 8
Step4: Swap (4,6)
2 3 4 5 0 1 6 7 8
Step5: Swap (5,7)
2 3 4 5 6 1 0 7 8
Step6: Swap (6,8)
2 3 4 5 6 7 0 1 8
Step7: Swap (7,9)
2 3 4 5 6 7 8 1 0
Step8: Swap (8,9)
2 3 4 5 6 7 8 0 1
The resulting shifted array is:
2 3 4 5 6 7 8 0 1
However, this example doesn't show the power of the algorithm developed because the minimum number of operations required to conduct the shift is length(array)-1 = 8.
For this example:
rotate: 3
array: 0 1 2 3 4 5
The answer is:
Shift to right
Step1: Swap (1,4)
3 1 2 0 4 5
Step2: Swap (2,5)
3 4 2 0 1 5
Step3: Swap (3,6)
3 4 5 0 1 2
The resulting shifted array is:
3 4 5 0 1 2
So instead of needing length(array)-1 = 6 steps of swapping, only 3 are required => minimum steps required to conduct the shift.