@@ -668,6 +668,7 @@ Params:
668668 slice = input slice
669669Returns:
670670 1-dimensional slice composed of diagonal elements
671+ See_also: $(LREF antidiagonal)
671672+/
672673Slice! (packs[0 ] == 1 ? kind : Universal, 1 ~ packs[1 .. $], Iterator)
673674 diagonal
@@ -758,20 +759,6 @@ version(mir_test) unittest
758759 assert (a.diagonal == d);
759760}
760761
761- // / Matrix, antidiagonal
762- @safe @nogc pure nothrow version(mir_test) unittest
763- {
764- import mir.ndslice.dynamic : dropToHypercube, reversed;
765- // -------
766- // | 0 1 2 |
767- // | 3 4 5 |
768- // -------
769- // ->
770- // | 1 3 |
771- static immutable d = [1 , 3 ];
772- assert (iota(2 , 3 ).universal.dropToHypercube.reversed! 1. diagonal == d);
773- }
774-
775762// / 3D, main diagonal
776763@safe @nogc pure nothrow version(mir_test) unittest
777764{
@@ -844,6 +831,61 @@ version(mir_test) unittest
844831 assert (slice == d);
845832}
846833
834+ /+ +
835+ Returns a 1-dimensional slice over the main antidiagonal of an 2D-dimensional slice.
836+ `antidiagonal` can be generalized with other selectors such as
837+ $(LREF blocks) (diagonal blocks) and $(LREF windows) (multi-diagonal slice).
838+
839+ It runs from the top right corner to the bottom left corner.
840+
841+ Pseudo_code:
842+ ------
843+ auto antidiagonal = slice.dropToHypercube.reversed!1.diagonal;
844+ ------
845+
846+ Params:
847+ slice = input slice
848+ Returns:
849+ 1-dimensional slice composed of antidiagonal elements.
850+ See_also: $(LREF diagonal)
851+ +/
852+ Slice! (Universal, 1 ~ packs[1 .. $], Iterator)
853+ antidiagonal
854+ (SliceKind kind, size_t [] packs, Iterator)
855+ (Slice! (kind, packs, Iterator) slice)
856+ if (packs[0 ] == 2 )
857+ {
858+ import mir.ndslice.dynamic : dropToHypercube, reversed;
859+ return slice.dropToHypercube.reversed! 1. diagonal;
860+ }
861+
862+ // /
863+ @safe @nogc pure nothrow version(mir_test) unittest
864+ {
865+ // -----
866+ // | 0 1 |
867+ // | 2 3 |
868+ // -----
869+ // ->
870+ // | 1 2 |
871+ static immutable c = [1 , 2 ];
872+ import std.stdio ;
873+ assert (iota(2 , 2 ).antidiagonal == c);
874+ }
875+
876+ // /
877+ @safe @nogc pure nothrow version(mir_test) unittest
878+ {
879+ // -------
880+ // | 0 1 2 |
881+ // | 3 4 5 |
882+ // -------
883+ // ->
884+ // | 1 3 |
885+ static immutable d = [1 , 3 ];
886+ assert (iota(2 , 3 ).antidiagonal == d);
887+ }
888+
847889/+ +
848890Returns an n-dimensional slice of n-dimensional non-overlapping blocks.
849891`blocks` can be generalized with other selectors.
@@ -3076,53 +3118,22 @@ auto magic(size_t length)
30763118@safe pure nothrow
30773119version (mir_test) unittest
30783120{
3079- auto isMagic (S)(S matrix)
3121+ bool isMagic (S)(S matrix)
30803122 {
30813123 import mir.math.sum;
3082- import mir.ndslice.algorithm: all;
3083- import mir.ndslice.allocation: slice;
3084- import mir.ndslice.dynamic: transposed, reversed;
3085- import mir.ndslice.topology: flattened, universal, diagonal;
3086-
3087- // check shape
3088- if (matrix.length == 0 )
3089- return false ;
3090- if (matrix.length! 0 != matrix.length! 1 )
3091- return false ;
3092-
3093- // checks that matrix is composed of consequent elements from interval 1:N^2.
3094- auto n2 = matrix.elementsCount;
3095- enum bc = size_t .sizeof * 8 ;
3096- auto flags = slice! size_t (n2 / bc + (n2 % bc != 0 ))
3097- .bitwise[0 .. n2];
3098- foreach (elem; matrix.flattened)
3099- {
3100- assert (elem > 0 );
3101- assert (elem <= n2);
3102- flags[elem - 1 ] = true ;
3103- }
3104- if (! flags.all)
3105- return false ;
3106-
3107- // calculate magic number
3124+ import mir.ndslice: magic, byDim, map, repeat, diagonal, antidiagonal;
31083125 auto n = matrix.length;
3109- auto c = n * (n * n + 1 ) / 2 ;
3110-
3111- // each row sum should equal magic number
3112- foreach (row; matrix)
3113- if (row.sum != c)
3114- return false ;
3115- // each columns sum should equal magic number
3116- foreach (col; matrix.universal.transposed)
3117- if (col.sum != c)
3118- return false ;
3119- // each diagonal sum should equal magic number
3120- if (matrix.diagonal.sum != c)
3121- return false ;
3122- if (matrix.universal.reversed! 0. diagonal.sum != c)
3123- return false ;
3124-
3125- return true ;
3126+ auto c = n * (n * n + 1 ) / 2 ; // magic number
3127+ return // check shape
3128+ matrix.length! 0 > 0 && matrix.length! 0 == matrix.length! 1
3129+ && // each row sum should equal magic number
3130+ matrix.byDim! 0. map! sum == c.repeat(n)
3131+ && // each columns sum should equal magic number
3132+ matrix.byDim! 1. map! sum == c.repeat(n)
3133+ && // diagonal sum should equal magic number
3134+ matrix.diagonal.sum == c
3135+ && // antodiagonal sum should equal magic number
3136+ matrix.antidiagonal.sum == c;
31263137 }
31273138
31283139 assert (isMagic(magic(1 )));
0 commit comments