digitalmars.D.learn - Rotate array in writefln?
- Chris Katko (14/14) Apr 17 2018 I need to rotate an array by 90 degrees, or have writefln figure
- Stefan Koch (2/16) Apr 18 2018 You can transpose the matrix :)
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (24/38) Apr 18 2018 Generally, the solution would be std.range.transposed. However,
- Chris Katko (6/49) Apr 19 2018 That makes sense why transpose wouldn't work for my arrays!
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (13/18) Apr 19 2018 Yup. Static arrays can't be ranges, since popFront must mutate
- Steven Schveighoffer (17/61) Apr 19 2018 A version without allocating:
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
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
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
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: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!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 19 2018
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
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: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. -SteveI 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); }
Apr 19 2018