# include # include # include # include # include using namespace std; # include "polyomino_transform.hpp" //****************************************************************************80 int *i4mat_copy_new ( int m, int n, int a1[] ) //****************************************************************************80 // // Purpose: // // I4MAT_COPY_NEW copies an I4MAT to a "new" I4MAT. // // Discussion: // // An I4MAT is an MxN array of I4's, stored by (I,J) -> [I+J*M]. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 27 August 2008 // // Author: // // John Burkardt // // Parameters: // // Input, int M, N, the number of rows and columns. // // Input, int A1[M*N], the matrix to be copied. // // Output, int I4MAT_COPY_NEW[M*N], the copy of A1. // { int *a2; int i; int j; a2 = new int[m*n]; for ( j = 0; j < n; j++ ) { for ( i = 0; i < m; i++ ) { a2[i+j*m] = a1[i+j*m]; } } return a2; } //****************************************************************************80 void i4mat_flip_cols ( int m, int n, int a[] ) //****************************************************************************80 // // Purpose: // // I4MAT_FLIP_COLS swaps the columns of an I4MAT. // // Discussion: // // An I4MAT is an MxN array of I4's, stored by (I,J) -> [I+J*M]. // // To "flip" the columns of an I4MAT is to start with something like // // 11 12 13 14 15 // 21 22 23 24 25 // 31 32 33 34 35 // 41 42 43 44 45 // 51 52 53 54 55 // // and return // // 15 14 13 12 11 // 25 24 23 22 21 // 35 34 33 32 31 // 45 44 43 42 41 // 55 54 53 52 51 // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 22 June 2006 // // Author: // // John Burkardt // // Parameters: // // Input, int M, N, the number of rows and columns. // // Input/output, int A[M*N], the matrix whose columns are to be flipped. // { int b; int i; int j; for ( i = 0; i < m; i++ ) { for ( j = 0; j < ( n / 2 ); j++ ) { b = a[i+ j *m]; a[i+ j *m] = a[i+(n-1-j)*m]; a[i+(n-1-j)*m] = b; } } return; } //****************************************************************************80 void i4mat_flip_rows ( int m, int n, int a[] ) //****************************************************************************80 // // Purpose: // // I4MAT_FLIP_ROWS swaps the rows of an I4MAT. // // Discussion: // // An I4MAT is an MxN array of I4's, stored by (I,J) -> [I+J*M]. // // To "flip" the rows of an I4MAT is to start with something like // // 11 12 13 14 15 // 21 22 23 24 25 // 31 32 33 34 35 // 41 42 43 44 45 // 51 52 53 54 55 // // and return // // 51 52 53 54 55 // 41 42 43 44 45 // 31 32 33 34 35 // 21 22 23 24 25 // 11 12 13 14 15 // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 22 June 2006 // // Author: // // John Burkardt // // Parameters: // // Input, int M, N, the number of rows and columns. // // Input/output, int A[M*N], the matrix whose rows are to be flipped. // { int b; int i; int j; for ( j = 0; j < n; j++ ) { for ( i = 0; i < ( m / 2 ); i++ ) { b = a[ i+j*m]; a[ i+j*m] = a[m-1-i+j*m]; a[m-1-i+j*m] = b; } } return; } //****************************************************************************80 void i4mat_transpose ( int m, int n, int a[] ) //****************************************************************************80 // // Purpose: // // I4MAT_TRANSPOSE transposes an I4MAT. // // Discussion: // // An I4MAT is an MxN array of I4's, stored by (I,J) -> [I+J*M]. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 16 April 2018 // // Author: // // John Burkardt // // Parameters: // // Input, int M, the number of rows in A. // // Input, int N, the number of columns in A. // // Input, int A[M*N], the M by N matrix. // // Output, int A[N*M], the transposed matrix. // { int *b; int i; int j; b = new int[n*m]; for ( j = 0; j < n; j++ ) { for ( i = 0; i < m; i++ ) { b[j+i*n] = a[i+j*m]; } } for ( j = 0; j < n; j++ ) { for ( i = 0; i < m; i++ ) { a[j+i*n] = b[j+i*n]; } } delete [] b; return; } //****************************************************************************80 void polyomino_print ( int m, int n, int p[], string label ) //****************************************************************************80 // // Purpose: // // POLYOMINO_PRINT prints a polyomino. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 29 April 2018 // // Author: // // John Burkardt // // Parameters: // // Input, int M, N, the number of rows and columns in the representation // of the polyomino P. // // Input, int P[M*N], a matrix of 0's and 1's representing the // polyomino. The matrix should be "tight", that is, there should be a // 1 in row 1, and in column 1, and in row M, and in column N. // // Input, string LABEL, a title for the polyomino. // { int i; int j; cout << "\n"; cout << label << "\n"; cout << "\n"; if ( m <= 0 || n <= 0 ) { cout << " [ Null matrix ]\n"; } else { for ( i = 0; i < m; i++ ) { for ( j = 0; j < n; j++ ) { cout << " " << p[i+j*m]; } cout << "\n"; } } return; } //****************************************************************************80 void polyomino_transform ( int m, int n, int p[], int rotate, int reflect, int &mq, int &nq, int **q ) //****************************************************************************80 // // Purpose: // // POLYOMINO_TRANSFORM transforms a polyomino. // // Discussion: // // A polyomino can be rotated or reflected. // // This program is given a polyomino and returns the resulting polyomino // after the specified reflection and rotation. // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 17 April 2018 // // Author: // // John Burkardt // // Parameters: // // Input, int M, N, the number of rows and columns in the representation // of the polyomino P. // // Input, int P[M*N], a matrix of 0's and 1's representing the // polyomino. The matrix should be "tight", that is, there should be a // 1 in row 1, and in column 1, and in row M, and in column N. // // Input, int ROTATE, is 0, 1, 2, or 3, the number of 90 degree // counterclockwise rotations to be applied. // // Input, int REFLECT, is 0 or 1. If it is 1, then each row of the // polyomino matrix is to be reflected before any rotations are performed. // // Output, int &MQ, &NQ, the number of rows and columns of the // representation of the transformed polyomino // // Output, int Q[MQ*NQ], the representation of the transformed // polyomino. // { int k; int r; int s; mq = m; nq = n; reflect = ( reflect % 2 ); *q = i4mat_copy_new ( m, n, p ); if ( reflect == 1 ) { i4mat_flip_cols ( mq, nq, *q ); } rotate = ( rotate % 4 ); for ( k = 1; k <= rotate; k++ ) { i4mat_transpose ( mq, nq, *q ); r = mq; s = nq; mq = s; nq = r; i4mat_flip_rows ( mq, nq, *q ); } return; } //****************************************************************************80 void timestamp ( ) //****************************************************************************80 // // Purpose: // // TIMESTAMP prints the current YMDHMS date as a time stamp. // // Example: // // 31 May 2001 09:45:54 AM // // Licensing: // // This code is distributed under the GNU LGPL license. // // Modified: // // 19 March 2018 // // Author: // // John Burkardt // // Parameters: // // None // { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct std::tm *tm_ptr; std::time_t now; now = std::time ( NULL ); tm_ptr = std::localtime ( &now ); std::strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm_ptr ); std::cout << time_buffer << "\n"; return; # undef TIME_SIZE }