5
$\begingroup$

Example list below. All elements are in the form {1 or 0, 1 or 0, 1 or 0}, with a least one of the numbers 0 and 1 in the element (so excluding {1,1,1} and {0,0,0})

ListA = {{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, **{0, 1, 1}**, {1, 0, 1}, {1, 0, 1}, {1,
   0, 1}}

I want a command to replace any single lone entry in the sequence to be replaced with the next sequence.

In List A the single lone entry is {0, 1, 1} as before this there are three {1, 1, 0} in a succession and following the single lone entry there are three {1, 0, 1} in a succession. So I want this lone entry to be replaced by {1, 0, 1}.

I want the command to be generic so can handle any combination of lone entries, I believe there will be 6 different scenarios (assuming the element sequence either side of the lone entry are different). Another example of lone entry of {{1, 1, 0}, {1, 1, 0}, {1, 0, 1}, {0, 1, 1}, {0, 1, 1}}

Lone entries at the start and end of the lists can be ignored.

$\endgroup$

5 Answers 5

3
$\begingroup$

You may construct a pattern with Longest and utilise it with ReplaceAll.

With

listA = {{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {0, 1, 1}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}};
listB = {{1, 1, 0}, {1, 1, 0}, {1, 0, 1}, {0, 1, 1}, {0, 1, 1}};

and

loneEntry = {s : Longest[a_ ..], b_, c___} :> {s, a, c}

Then

listA /. loneEntry
{{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}}
listB /. loneEntry
{{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {0, 1, 1}, {0, 1, 1}}

Hope this helps.

$\endgroup$
4
$\begingroup$

Just for kicks:

f[{a__, a__, b__}] := a
f[{a__, b__, b__}] := b
f[{a__, b__, c__}] := c
{First@ListA} ~Join~ Map[f, Partition[ListA, 3, 1]] ~Join~ {Last@ListA}

{{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}}

$\endgroup$
2
$\begingroup$

Written for clarity over efficiency:

ListA =
  {{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {0, 1, 1}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}};

Split[ListA]

% //. {a___List, lone : {{__}}, b__List} :> {a, {b}[[1, {1}]], b}

Join @@ %
{{{1, 1, 0}, {1, 1, 0}, {1, 1, 0}}, {{0, 1, 1}}, {{1, 0, 1}, {1, 0, 1}, {1, 0, 1}}}

{{{1, 1, 0}, {1, 1, 0}, {1, 1, 0}}, {{1, 0, 1}}, {{1, 0, 1}, {1, 0, 1}, {1, 0, 1}}}

{{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}}

Other ideas:

sp = Split[ListA];

lone = Position[sp, {{__}}];
lone = DeleteCases[lone, {Length@sp}];

Scan[(sp[[#]] = sp[[# + 1, {1}]]) &, lone];

Join @@ sp

Or:

fill[{{{__}}, {x_List, ___List}}] := {x}
fill[{a_, b_}] := a

Join @@ Developer`PartitionMap[fill, Split@ListA, 2, 1, 1, {{}}]
$\endgroup$
2
$\begingroup$
Clear["Global`*"];
listA = {{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {0, 1, 1}, {1, 0, 1}, {1, 0,
    1}, {1, 0, 1}}
listB = {{1, 1, 0}, {1, 1, 0}, {1, 0, 1}, {0, 1, 1}, {0, 1, 1}};

f = SequenceReplace[{a__, b_, c__} /; b =!= Last@{a} :> {a, First@{c},
        c}][#] &;

f /@ {listA, listB}

{{{{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}, {1, 0, 1}}}, {{{1, 1, 0}, {1, 1, 0}, {0, 1, 1}, {0, 1, 1}, {0, 1, 1}}}}

$\endgroup$
1
$\begingroup$
la =
  {{1, 1, 0}, {1, 1, 0}, {1, 1, 0},
   {0, 1, 1},
   {1, 0, 1}, {1, 0, 1}, {1, 0, 1}};

Using SequenceSplit (new in 11.3)

SequenceSplit[la, a : {b_, b_ ...} :> a] /.
 {a_, {{__}}, b__} :> Catenate[{a, {Last[a]}, b}]

{{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {1, 1, 0},
{1, 0, 1}, {1, 0, 1}, {1, 0, 1}}

If the sequence would end with a single lone entry:

lb =
  {{1, 1, 0}, {1, 1, 0}, {1, 1, 0},
   {0, 1, 1},
   {1, 0, 1}, {1, 0, 1},
   {1, 1, 1}};

Replace[
 Split[SequenceCases[lb, {a_, a_ ...}], Length[#2] == 1 &],
 {a_, {{__}}} :> Splice @ Join[a, {Last @ a}],
 {1}]

{{1, 1, 0}, {1, 1, 0}, {1, 1, 0}, {1, 1, 0}, n
{1, 0, 1}, {1, 0, 1}, {1, 0, 1}}

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.