MATLAB Answers

How to change a sequence of integers?

47 views (last 30 days)
S H
S H on 4 Mar 2021
Commented: S H on 5 Mar 2021
I am new to Matlab and coming up already with a tricky question. Suppose a sequence of integers
[2 1 3 4 1 1 3 1 2 1 2 2 5 3 2];
that I want to change according to the following rules:
  • When there is a one not followed or preceeded by another one, I want to replace the one, the preceeding and following number by the sum of the two numbers around the one.
  • If for two given ones, the preceeding and following numbers overlap, I want to add them allogether.
So in my example, I should obtain:
[5 5 5 4 1 1 7 7 7 7 7 2 5 3 2]
The first three numbers turn to be 5 because I add 2 + 3, according to rule 1. The next three numbers 4 1 1 remain unchanged, also according to rule 1. The then coming 5 numbers [3 1 2 1 2] should all be added together, because of rule 2. Lastly, 2 5 3 2 remain unchanged.
I cannot figure out how to do this. Perhaps there is a way of writing a recursive function that picks a one, checks if and how much numbers have to be added from the left and then looks at the right and finally sums the numbers up. Does anyone have a clue? Many thanks in advance
  3 Comments
Jan
Jan on 4 Mar 2021
Okay. So I assume you want sequences of [a,1,b,1,c,1,d,...] of any length to be considered.

Sign in to comment.

Accepted Answer

Jan
Jan on 4 Mar 2021
Edited: Jan on 4 Mar 2021
Rule 1 is easy:
x = [2 1 3 4 1 1 3 1 2 1 2 2 5 3 2];
m = strfind(x == 1, [false, true, false]);
y = x;
xm = x(m) + x(m+2);
y(m) = xm;
y(m+1) = xm;
y(m+2) = xm;
To find a similar approach for rule 2 we need a unique definition at first. See my comment above. Are the elements, which are not 1 always greater than 1 or does the input contain negative values and zeros also?
If there are not sequences with more than 2 ones surrounded by non-ones, the above approach can be expanded and run at first:
m = strfind(x == 1, [false, true, false, true, false]);
xm = x(m) + x(m+2) + x(m+4);
... etc.
[EDITED] Including rule 2:
x = [2 1 3 4 1 1 3 1 2 1 2 2 5 3 2 2,1,3,1,4,1,5];
m = strfind(x == 1, [false, true, false]); % Search for [a,1,b]
p = false(1, numel(x) + 2); % Mask [a,b,1,c,d] as
p(m+1) = true; % [false, true, true, true, false]
p(m+2) = true;
p(m+3) = true;
% x: 2 1 3 4 1 1 3 1 2 1 2 2 5 3 2 2 1 3 1 4 1 5
% p: 0 1 1 1 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 1 0
% ^ to detect initial [0 1] and final [1 0] ^
ini = strfind(p, [false, true]); % Search for starts and ends of blocks
fin = strfind(p, [true, false]) - 1;
for k = 1:numel(ini) % Loop over sequences
rep = sum(x(ini(k):2:fin(k))); % Sum values surrounding the 1s
x(ini(k):fin(k)) = rep; % Replace elements
end
% Check:
isequal(x, ...
[5 5 5 4 1 1 7 7 7 7 7 2 5 3 2 14 14 14 14 14 14 14])
  3 Comments
S H
S H on 5 Mar 2021
This is a clever way, too. Thank you!

Sign in to comment.

More Answers (0)

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!