7
$\begingroup$

I have the following list.

data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

I want to replace (rotate) each element using a for loop. In the first step, the first element is rotated. In the second step, the first two elements are rotated. Then after 4 steps of the loop, the output should look like:

example after 4 steps

I tried several options, for example:

ReplacePart[data, 
 Thread[data[[1 ;; 3]] -> Rotate[data[[1 ;; 3]], 90 Degree]]]

But this replacement doesn't give me the output I want. How can I perform this sequence of rotations?

$\endgroup$
2
  • 6
    $\begingroup$ The question arises: what for? $\endgroup$
    – user64494
    Jun 27, 2023 at 10:12
  • 1
    $\begingroup$ …Well, why do you mention for loop? You don't even use it yourself. $\endgroup$
    – xzczd
    Jun 29, 2023 at 6:04

11 Answers 11

3
$\begingroup$

With a for loop:

data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} ;
size = Length[data] ;
table = {} ;
For[
  i = 1,
  i <= size,
  i++,
  data[[i]] = Rotate[data[[i]], 90 Degree] ;
  AppendTo[table, data] ;
] ;
Grid[table, Frame->All]
$\endgroup$
7
$\begingroup$

Will this work? Or do you have to use Thread? How about using a loop?

Mathematica graphics

ClearAll["Global`*"]
data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
newData=First@Last@Reap@Do[
   z=Rotate[data[[#]],90 Degree]&/@Range[n];
   Sow[Join[z,data[[n+1;;]]]],
{n,1,Length@data}
];
Grid[newData,Frame->All]
$\endgroup$
7
$\begingroup$
f = ReplaceList[ {a__, b___} :> Join[Map[Rotate[#, π/2] &]@{a}, {b}]];

f @ data // MatrixForm

enter image description here

Take[f @ data, 5] // MatrixForm

enter image description here

Alternatively, define a function with two arguments specifying the input list and desired number of rows to take:

ClearAll[g]
g = ReplaceList[{a__, b___} /; Length[{a}] <= #2 :> 
      Join[Map[Rotate[#, π/2] &] @ {a}, {b}]] @ # &;


g[data, 7] // MatrixForm

enter image description here

$\endgroup$
6
$\begingroup$

Let's package up a function to rotate a given number of elements in a list:

RotateElems[count_, list_] := MapAt[Rotate[#, Pi/2] &, list, List /@ Range@count]

Now we can generate a table of partially rotated lists:

Table[RotateElems[i, data], {i, Length@data}]

You can use Grid for display if you want:

Grid[Table[RotateElems[i, data], {i, Length@data}], Frame -> All]

enter image description here

You could add an argument to RotateElems to specify the amount of rotation.

$\endgroup$
6
$\begingroup$

Another way using LowerTriangularize:

rotateMat[lst_?VectorQ] := Module[{mat, pos},mat = ConstantArray[lst, Length[lst]];
pos = Join @@ (Position[LowerTriangularize[mat], #] & /@ lst);
ReplacePart[mat, Thread[pos -> Map[Rotate[#, π/2] &, Extract[mat, pos]]]]]

For example:

data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

rotateMat[data] // MatrixForm

enter image description here

$\endgroup$
6
$\begingroup$

Here's a solution with SubsetMap:

f[expr_Rotate] := expr
f[expr_] := Rotate[expr, 90 Degree]
SetAttributes[f, Listable]

With[{n = 10, step = 5}, SubsetMap[f, Range@n, ;; #] & /@ Range@step] // 
 Grid[#, Frame -> All] &

enter image description here

$\endgroup$
6
$\begingroup$
data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

Rest@FoldList[MapAt[Rotate[#,90 Degree]&,#1,#2]&,data,Range[4]]//MatrixForm

Matrix of results as tiff

As a Grid

Grid[Rest@FoldList[MapAt[Rotate[#,90 Degree]&,#1,#2]&,data,Range[Length@data]],
     Frame->All]

Another way

Rest@FoldList[ReplaceAt[#1,x_->Rotate[x,90 Degree],#2]&,data,Range@Length@data]
  //Grid[#,Frame->All]&

Just for Fun

MapAt[Rotate[#,90 Degree]&, data,Transpose[{#}]]&/@Range@Range@Length@data
  //Grid[#, Frame->All]&

Or

ReplaceAt[data,x_->Rotate[x,90 Degree],Transpose[{#}]]&/@Range@Range@Length@data
  //Grid[#,Frame->All]&

enter image description here

$\endgroup$
5
$\begingroup$

Shoutout to @E. Chan-López for the idea to use *Triangularize.

data = ConstantArray[Range[10], 10];
rotatedData = Map[Rotate[#, \[Pi]/2] &, data, {-1}];
LowerTriangularize@rotatedData + UpperTriangularize[data, 1] // Grid[#, Frame -> All] &

enter image description here

$\endgroup$
5
$\begingroup$

Probably the simplest way:

Table[If[i >= j, Rotate[j, 90 Degree], j], {i,1,5}, {j,1,8}] // Grid

enter image description here

$\endgroup$
3
$\begingroup$

Using MapIndexed:

Clear["Global`*"];
n = 10;
m = 10;
mat = ConstantArray[Range[n], m];
f = If [Last@#2 <= First@#2, Style[Rotate[#1, π/2], Red], #1] &;
res = MapIndexed[f, mat, {2}];
MatrixForm /@ {mat, res}

enter image description here


g = If [EvenQ[Last@#2 + First@#2], Style[Rotate[#1, π/4], Red], 
    Style[Rotate[#1, -π/4], Blue]] &;
resg = MapIndexed[g, mat, {2}];
MatrixForm /@ {mat, resg}

enter image description here


$\endgroup$
2
$\begingroup$

Using MapAt and Splice (new in 12.1)

n = 3;

MapAt[
  Rotate[#, Pi/2] &,
  ConstantArray[Range[n], n],
  Table[Splice @ Table[{i, j}, {i, j, n}], {j, n}]] // MatrixForm

enter image description here

$\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.