# include # include # include # include "polyomino_transform.h" /******************************************************************************/ int *i4mat_copy_new ( int m, int n, int a1[] ) /******************************************************************************/ /* 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 = ( int * ) malloc ( m * n * sizeof ( int ) ); for ( j = 0; j < n; j++ ) { for ( i = 0; i < m; i++ ) { a2[i+j*m] = a1[i+j*m]; } } return a2; } /******************************************************************************/ void i4mat_flip_cols ( int m, int n, int a[] ) /******************************************************************************/ /* 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: 05 June 2010 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; } /******************************************************************************/ void i4mat_flip_rows ( int m, int n, int a[] ) /******************************************************************************/ /* 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: 05 June 2010 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; } /******************************************************************************/ void i4mat_transpose ( int m, int n, int a[] ) /******************************************************************************/ /* 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 = ( int * ) malloc ( n * m * sizeof ( int ) ); 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]; } } free ( b ); return; } /******************************************************************************/ void polyomino_print ( int m, int n, int p[], char *label ) /******************************************************************************/ /* 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. Input, char *LABEL, a title for the polyomino. */ { int i; int j; printf ( "\n" ); printf ( "%s\n", label ); printf ( "\n" ); if ( m <= 0 || n <= 0 ) { printf ( " [ NULL matrix ]" ); } else { for ( i = 0; i < m; i++ ) { for ( j = 0; j < n; j++ ) { printf ( " %d", p[i+j*m] ); } printf ( "\n" ); } } return; } /******************************************************************************/ void polyomino_transform ( int m, int n, int p[], int rotate, int reflect, int *mq, int *nq, int **q ) /******************************************************************************/ /* 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: 16 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 ); /* I want to create the array here. When calling, use &q */ *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; } /******************************************************************************/ void timestamp ( ) /******************************************************************************/ /* Purpose: TIMESTAMP prints the current YMDHMS date as a time stamp. Example: 17 June 2014 09:45:54 AM Licensing: This code is distributed under the GNU LGPL license. Modified: 17 June 2014 Author: John Burkardt Parameters: None */ { # define TIME_SIZE 40 static char time_buffer[TIME_SIZE]; const struct tm *tm; time_t now; now = time ( NULL ); tm = localtime ( &now ); strftime ( time_buffer, TIME_SIZE, "%d %B %Y %I:%M:%S %p", tm ); printf ( "%s\n", time_buffer ); return; # undef TIME_SIZE }