How to change a sequence of integers?

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

I do not understand your rule 2:
"If for two given ones, the preceeding and following numbers overlap, I want to add them allogether."
"The then coming 5 numbers [3 1 2 1 2] should all be added together"
Adding all together would give 9, not 7. So you do not mean "all together" but: all but the ones. Correct?
What should happen for [2,1,3,1,4,1,5] ? What about the margins?
Yes it's all but the ones. [2,1,3,1,4,1,5] should give [14,14,14,14,14,14,14].
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

That's awesome, thank you so much!!
You are welcome. Do you see the idea: Mask the pattern and search for initial and final points. This is much easier than running a loop over the original elements and searching for the limits of the sequences:
% NOT EXHAUSTIVELY TESTED!!!
x = [2 1 3 4 1 1 3 1 2 1 2 2 5 3 2 2,1,3,1,4,1,5];
nx = numel(x);
accum = 0;
ix = 2;
while ix < nx % Not <= !
if x(ix) == 1
if x(ix - 1) ~= 1 && x(ix + 1) ~= 1
fin = ix + 1; % End point
if accum == 0 % Initial point found
ini = ix - 1; % Remember start point
accum = x(ini) + x(fin);
else % Ongoing sequence
accum = accum + x(fin);
end
ix = ix + 1; % Proceed 1 additional element
end
elseif accum ~= 0 % Flush accumulator
x(ini:fin) = accum;
accum = 0; % Reset accumulator
end
ix = ix + 1; % Proceed to next element
end
if accum ~= 0 % Flush final accumulator on demand:
x(ini:fin) = accum;
end
This loop looks like a typical C approach, while the vectorized method above is "matlabish".
This is a clever way, too. Thank you!

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB Coder in Help Center and File Exchange

Tags

Asked:

S H
on 4 Mar 2021

Commented:

S H
on 5 Mar 2021

Community Treasure Hunt

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

Start Hunting!