47 views (last 30 days)

Show older comments

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

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.

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])

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

Start Hunting!