11
$\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$
4
  • 3
    $\begingroup$ Like this: ConstantArray[#1, #2] & @@@ Partition[Flatten[{S, First[S]}], 2, 1] $\endgroup$ Apr 6, 2017 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$
    – ZaMoC
    Apr 6, 2017 at 22:57
  • 7
    $\begingroup$ @Anjan, ConstantArray @@@ Partition[S, 2, 1, 1] is shorter; Table @@@ Partition[S, 2, 1, 1] even more so. $\endgroup$ Apr 6, 2017 at 23:38
  • $\begingroup$ @J.M I agree yours is very short. Thanks. $\endgroup$ Apr 7, 2017 at 3:44

9 Answers 9

18
$\begingroup$

Another one:

MapThread[ConstantArray, {S, RotateLeft[S]}]
$\endgroup$
9
$\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$
7
$\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$
4
$\begingroup$
list = {3, 4, 6, 1, 2, 5};

Table @@@ Partition[list, 2, 1, 1]

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

$\endgroup$
3
$\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$
3
$\begingroup$
BlockMap[Apply[Table], #, 2, 1] & @ S
{{3, 3, 3, 3}, {4, 4, 4, 4, 4, 4}, {6}, {1, 1}, {2, 2, 2, 2, 2}}
$\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$
1
$\begingroup$

Another alternative using Table and Mod:

Table[ConstantArray @@ {#[[i]], #[[Mod[i + 1, Length@#, 1]]]}, {i, Length@#}] &@S

(*{{3, 3, 3, 3}, {4, 4, 4, 4, 4, 4}, {6}, {1, 1}, {2, 2, 2, 2, 2}, {5, 5, 5}}*)
$\endgroup$

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .