Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
April 18, 2018 Rotate array in writefln? | ||||
---|---|---|---|---|
| ||||
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)); |
April 18, 2018 Re: Rotate array in writefln? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | 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 :)
|
April 18, 2018 Re: Rotate array in writefln? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | 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
|
April 19, 2018 Re: Rotate array in writefln? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | 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!
|
April 19, 2018 Re: Rotate array in writefln? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Katko | 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 |
April 19, 2018 Re: Rotate array in writefln? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | 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
|
Copyright © 1999-2021 by the D Language Foundation