10
$\begingroup$

I have a list

S = {3, 4, 6, 1, 2, 5};

and I want every element to be duplicated as many times as the value of the next element.

Note: the last element should be duplicated as many times as the value of the first element.

The result should look like this:

{{3, 3, 3, 3}, {4, 4, 4, 4, 4, 4}, {6}, {1, 1}, {2, 2, 2, 2, 2}, {5, 5, 5}}

$\endgroup$
  • 2
    $\begingroup$ Like this: ConstantArray[#1, #2] & @@@ Partition[Flatten[{S, First[S]}], 2, 1] $\endgroup$ – Anjan Kumar Apr 6 '17 at 22:52
  • 1
    $\begingroup$ very nice thanx.I found something that it works ,too! Table @@@ Table[{S[[i]], S[[Mod[i, 6] + 1]]}, {i, 1, Length@S}] $\endgroup$ – J42161217 Apr 6 '17 at 22:57
  • 6
    $\begingroup$ @Anjan, ConstantArray @@@ Partition[S, 2, 1, 1] is shorter; Table @@@ Partition[S, 2, 1, 1] even more so. $\endgroup$ – J. M. will be back soon Apr 6 '17 at 23:38
  • $\begingroup$ @J.M I agree yours is very short. Thanks. $\endgroup$ – Anjan Kumar Apr 7 '17 at 3:44
16
$\begingroup$

Another one:

MapThread[ConstantArray, {S, RotateLeft[S]}]
$\endgroup$
6
$\begingroup$

It's a one-liner. Use Partition to split the list up into pairs, with the offset and cyclic arguments to get what you want, and then apply ConstantArray to each pair.

ClearAll[duplicate];
duplicate[list : {___Integer}] := ConstantArray @@@ Partition[list, 2, 1, 1];

duplicate[S]
(* {{3, 3, 3, 3}, {4, 4, 4, 4, 4, 4}, {6}, {1, 1}, {2, 2, 2, 2, 2}, {5, 5, 5}}*) 
$\endgroup$
6
$\begingroup$

Update: Using Partition with its undocumented sixth argument:

Partition[#, 2, 1, {1, -1}, {}, ConstantArray] & @ {3, 4, 6, 1, 2, 5}

{{3, 3, 3, 3}, {4, 4, 4, 4, 4, 4}, {6}, {1, 1}, {2, 2, 2, 2, 2}}


Original answer:

ClearAll[f0, f1, f2]
f0 = Table @@@ ({#, {##2, #} & @@ #} &@#) &;
f1 = Developer`PartitionMap[Internal`RepetitionFromMultiplicity@{#} &, #, 2, 1, 1] &;
f2 = Developer`PartitionMap[ConstantArray @@ # &, #, 2, 1, 1] &;
f3 = Normal@SparseArray[{}, {#}, #2] & @@@ ({#, {##2, #} & @@ #} &@#) &;

f0 @ {3, 4, 6, 1, 2, 5}

{{3, 3, 3, 3}, {4, 4, 4, 4, 4, 4}, {6}, {1, 1}, {2, 2, 2, 2, 2}, {5, 5, 5}}

Equal @@ (#@{3, 4, 6, 1, 2, 5} & /@ {f0, f1, f2, f3})

True

For fun:

☺ = {#} //. {♯1___, ♯2_, ♯3___}/;♯2>1 :> {♯1, 1, ♯2 - 1, ♯3} &;
☺☺ = # (☺ /@ {##2, #} & @@ #) &;
☺☺ @ {3, 4, 6, 1, 2, 5}

{{3, 3, 3, 3}, {4, 4, 4, 4, 4, 4}, {6}, {1, 1}, {2, 2, 2, 2, 2}, {5, 5, 5}}

$\endgroup$
2
$\begingroup$

Another approach, using Inner:

s // Inner[Table, #, RotateLeft@#, List] &

(As per J.M's comment above regarding Table)

Original Post

s // Inner[NestList[# &, #1, #2 - 1] &, #, RotateLeft@#, List] &

{{3, 3, 3, 3}, {4, 4, 4, 4, 4, 4}, {6}, {1, 1}, {2, 2, 2, 2, 2}, {5, 5, 5}}

Alternatively:

s // Inner[ConstantArray, #, RotateLeft@#, List] &
$\endgroup$
1
$\begingroup$
list ={3, 4, 6, 1, 2, 5, 3};

Cases[#, {___Integer}, {2}] &@ReplaceList[list, {p___, x_Integer, y_Integer, c___} :> 
{p, ConstantArray[x, y], y, c}]

(* {{3, 3, 3, 3}, {4, 4, 4, 4, 4, 4}, {6}, {1, 1}, {2, 2, 2, 2, 2}, {5, 5, 5}} *)
$\endgroup$
1
$\begingroup$
fu = MapIndexed[ConstantArray[S[[#]], RotateLeft[S, #][[1]]] &, 
 Range[1, Length[S]]]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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