www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Rotate array in writefln?

reply Chris Katko <ckatko gmail.com> writes:
I need to rotate an array by 90 degrees, or have writefln figure 
that out.

I need, say:

0 4 5 6
0 0 0 0
0 0 0 0
0 0 0 0

But it's outputting:

0 0 0 0
4 0 0 0
5 0 0 0
6 0 0 0

int [4][4] data;
file.writeln(format("%(%-(%d %)\n%)", data));
Apr 17 2018
next sibling parent Stefan Koch <uplink.coder googlemail.com> writes:
On Wednesday, 18 April 2018 at 06:54:29 UTC, Chris Katko wrote:
 I need to rotate an array by 90 degrees, or have writefln 
 figure that out.

 I need, say:

 0 4 5 6
 0 0 0 0
 0 0 0 0
 0 0 0 0

 But it's outputting:

 0 0 0 0
 4 0 0 0
 5 0 0 0
 6 0 0 0

 int [4][4] data;
 file.writeln(format("%(%-(%d %)\n%)", data));
You can transpose the matrix :)
Apr 18 2018
prev sibling parent reply Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Wednesday, 18 April 2018 at 06:54:29 UTC, Chris Katko wrote:
 I need to rotate an array by 90 degrees, or have writefln 
 figure that out.

 I need, say:

 0 4 5 6
 0 0 0 0
 0 0 0 0
 0 0 0 0

 But it's outputting:

 0 0 0 0
 4 0 0 0
 5 0 0 0
 6 0 0 0

 int [4][4] data;
 file.writeln(format("%(%-(%d %)\n%)", data));
Generally, the solution would be std.range.transposed. However, since you're using a int[4][4], that's not a range-of-ranges, and transposed don't work out of the box. This helper function should help: T[][] ror(T, size_t N1, size_t N2)(ref T[N1][N2] arr) { T[][] result = new T[][N2]; foreach (i, e; arr) { result[i] = e.dup; } return result; } unittest { import std.stdio; import std.range; int [4][4] data; data[2][3] = 4; writefln("%(%-(%d %)\n%)", data); writefln("%(%-(%d %)\n%)", data.ror.transposed); } -- Simen
Apr 18 2018
next sibling parent reply Chris Katko <ckatko gmail.com> writes:
On Wednesday, 18 April 2018 at 07:15:47 UTC, Simen Kjærås wrote:
 On Wednesday, 18 April 2018 at 06:54:29 UTC, Chris Katko wrote:
 I need to rotate an array by 90 degrees, or have writefln 
 figure that out.

 I need, say:

 0 4 5 6
 0 0 0 0
 0 0 0 0
 0 0 0 0

 But it's outputting:

 0 0 0 0
 4 0 0 0
 5 0 0 0
 6 0 0 0

 int [4][4] data;
 file.writeln(format("%(%-(%d %)\n%)", data));
Generally, the solution would be std.range.transposed. However, since you're using a int[4][4], that's not a range-of-ranges, and transposed don't work out of the box. This helper function should help: T[][] ror(T, size_t N1, size_t N2)(ref T[N1][N2] arr) { T[][] result = new T[][N2]; foreach (i, e; arr) { result[i] = e.dup; } return result; } unittest { import std.stdio; import std.range; int [4][4] data; data[2][3] = 4; writefln("%(%-(%d %)\n%)", data); writefln("%(%-(%d %)\n%)", data.ror.transposed); } -- Simen
That makes sense why transpose wouldn't work for my arrays! So you're saying if I used [][] (dynamic array) that's a range of ranges, and it would work? Why is it you have to rework your templates for static vs dynamic ranges? Thanks!
Apr 19 2018
parent Simen =?UTF-8?B?S2rDpnLDpXM=?= <simen.kjaras gmail.com> writes:
On Thursday, 19 April 2018 at 10:10:41 UTC, Chris Katko wrote:
 That makes sense why transpose wouldn't work for my arrays!

 So you're saying if I used [][] (dynamic array) that's a range 
 of ranges, and it would work?
Yup. Static arrays can't be ranges, since popFront must mutate the length, and the length is a part of the type for static arrays.
 Why is it you have to rework your templates for static vs 
 dynamic ranges? Thanks!
Unless I answered this question above, I'm not entirely sure what you're asking. Anyways, for matrix work (which seems to be what you're doing), I would suggest taking a look at https://github.com/libmir/mir-algorithm. I haven't actually used it myself, but seems to be a very good and comprehensive library for this purpose. -- Simen
Apr 19 2018
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 4/18/18 3:15 AM, Simen Kjærås wrote:
 On Wednesday, 18 April 2018 at 06:54:29 UTC, Chris Katko wrote:
 I need to rotate an array by 90 degrees, or have writefln figure that 
 out.

 I need, say:

 0 4 5 6
 0 0 0 0
 0 0 0 0
 0 0 0 0

 But it's outputting:

 0 0 0 0
 4 0 0 0
 5 0 0 0
 6 0 0 0

 int [4][4] data;
 file.writeln(format("%(%-(%d %)\n%)", data));
Generally, the solution would be std.range.transposed. However, since you're using a int[4][4], that's not a range-of-ranges, and transposed don't work out of the box. This helper function should help: T[][] ror(T, size_t N1, size_t N2)(ref T[N1][N2] arr) {     T[][] result = new T[][N2];     foreach (i, e; arr) {         result[i] = e.dup;     }     return result; } unittest {     import std.stdio;     import std.range;     int [4][4] data;     data[2][3] = 4;     writefln("%(%-(%d %)\n%)", data);     writefln("%(%-(%d %)\n%)", data.ror.transposed); }
A version without allocating: T[][N2] ror(T, size_t N1, size_t N2)(ref T[N1][N2] arr) { T[][N2] result; foreach (i, ref e; arr) { result[i] = e[]; } return result; } ... writefln("%(%-(%d %)\n%)" data.ror[].transposed); // need the slice operator here Keep in mind, you can't simply assign a variable to data.ror[], as the backing goes away immediately (OK to use as an rvalue though). And you must keep data in scope as long as you are using the result of data.ror. -Steve
Apr 19 2018