# include # include # include # include # include "pentominoes.h" /******************************************************************************/ int *i4rows_copy_new ( int m, int n, int a1[] ) /******************************************************************************/ /* Purpose: I4MROWS_COPY_NEW copies an I4ROWS to a "new" I4MAT. Discussion: An I4ROWS is an MxN array of I4's, stored by (I,J) -> [I*N+J]. Licensing: This code is distributed under the GNU LGPL license. Modified: 21 April 2018 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 I4ROWS_COPY_NEW[M*N], the copy of A1. */ { int *a2; int i; int j; a2 = ( int * ) malloc ( m * n * sizeof ( int ) ); for ( i = 0; i < m; i++ ) { for ( j = 0; j < n; j++ ) { a2[i*n+j] = a1[i*n+j]; } } return a2; } /******************************************************************************/ int *i4rows_zeros_new ( int m, int n ) /******************************************************************************/ /* Purpose: I4ROWS_ZEROS_NEW returns a new zeroed I4ROWS. Discussion: An I4ROWS is a doubly dimensioned array of I4 values, stored as a vector in row-major order. Licensing: This code is distributed under the GNU LGPL license. Modified: 21 April 2018 Author: John Burkardt Parameters: Input, int M, N, the number of rows and columns. Output, int I4ROWS_ZEROS_NEW[M*N], the new zeroed matrix. */ { int *a; int i; int j; a = ( int * ) malloc ( m * n * sizeof ( int ) ); for ( i = 0; i < m; i++ ) { for ( j = 0; j < n; j++ ) { a[i*n+j] = 0; } } return a; } /******************************************************************************/ void pentomino_matrix ( char name, int *p_m, int *p_n, int **p ) /******************************************************************************/ /* Purpose: PENTOMINO_MATRIX returns a 0/1 matrix defining a particular pentomino. Licensing: This code is distributed under the GNU LGPL license. Modified: 21 April 2018 Author: John Burkardt Parameters: Input, char NAME, is 'f', 'i', 'l', 'n', 'p', 't', 'u', 'v', 'w', 'x', 'y' or 'z'. Output, int *P_M, *P_N, the number of rows and columns of the representation. Output, int P[P_M*P_N], a matrix of 0's and 1's that indicates the shape of the pentomino. */ { int f_mat[3*3] = { 0, 1, 1, 1, 1, 0, 0, 1, 0 }; int i_mat[5] = { 1, 1, 1, 1, 1 }; int l_mat[4*2] = { 1, 0, 1, 0, 1, 0, 1, 1 }; int n_mat[2*4] = { 1, 1, 0, 0, 0, 1, 1, 1 }; int p_mat[3*2] = { 1, 1, 1, 1, 1, 0 }; int t_mat[3*3] = { 1, 1, 1, 0, 1, 0, 0, 1, 0 }; int u_mat[2*3] = { 1, 0, 1, 1, 1, 1 }; int v_mat[3*3] = { 1, 0, 0, 1, 0, 0, 1, 1, 1 }; int w_mat[3*3] = { 1, 0, 0, 1, 1, 0, 0, 1, 1 }; int x_mat[3*3] = { 0, 1, 0, 1, 1, 1, 0, 1, 0 }; int y_mat[2*4] = { 0, 0, 1, 0, 1, 1, 1, 1 }; int z_mat[3*3] = { 1, 1, 0, 0, 1, 0, 0, 1, 1 }; if ( name == 'f' || name == 'F' ) { *p_m = 3; *p_n = 3; *p = i4rows_copy_new ( *p_m, *p_n, f_mat ); } else if ( name == 'i' || name == 'I' ) { *p_m = 5; *p_n = 1; *p = i4rows_copy_new ( *p_m, *p_n, i_mat ); } else if ( name == 'l' || name == 'L' ) { *p_m = 4; *p_n = 2; *p = i4rows_copy_new ( *p_m, *p_n, l_mat ); } else if ( name == 'n' || name == 'N' ) { *p_m = 2; *p_n = 4; *p = i4rows_copy_new ( *p_m, *p_n, n_mat ); } else if ( name == 'p' || name == 'P' ) { *p_m = 3; *p_n = 2; *p = i4rows_copy_new ( *p_m, *p_n, p_mat ); } else if ( name == 't' || name == 'T' ) { *p_m = 3; *p_n = 3; *p = i4rows_copy_new ( *p_m, *p_n, t_mat ); } else if ( name == 'u' || name == 'U' ) { *p_m = 2; *p_n = 3; *p = i4rows_copy_new ( *p_m, *p_n, u_mat ); } else if ( name == 'v' || name == 'V' ) { *p_m = 3; *p_n = 3; *p = i4rows_copy_new ( *p_m, *p_n, v_mat ); } else if ( name == 'w' || name == 'W' ) { *p_m = 3; *p_n = 3; *p = i4rows_copy_new ( *p_m, *p_n, w_mat ); } else if ( name == 'x' || name == 'X' ) { *p_m = 3; *p_n = 3; *p = i4rows_copy_new ( *p_m, *p_n, x_mat ); } else if ( name == 'y' || name == 'Y' ) { *p_m = 2; *p_n = 4; *p = i4rows_copy_new ( *p_m, *p_n, y_mat ); } else if ( name == 'z' || name == 'Z' ) { *p_m = 3; *p_n = 3; *p = i4rows_copy_new ( *p_m, *p_n, z_mat ); } else { printf ( "\n" ); printf ( "PENTOMINO_MATRIX - Fatal error!\n" ); printf ( " Illegal name = '%c'\n", name ); printf ( " Legal names: f, i, l, n, p, t, u, v, w, x, y, z.\n" ); exit ( 1 ); } return; } /******************************************************************************/ void pentomino_plot ( int p_m, int p_n, int p[], char *label ) /******************************************************************************/ /* Purpose: PENTOMINO_PLOT plots a particular pentomino in a 5x5 grid. Licensing: This code is distributed under the GNU LGPL license. Modified: 22 April 2018 Author: John Burkardt Parameters: Input, int P_M, P_N, the number of rows and columns of the representation. Input, int P[P_M*P_N], a matrix of 0's and 1's. 1 <= P_M, P_N <= 5. There should be exactly 5 values of one. Input, char *LABEL, a title for the plot. */ { char color[16]; int *color_index; char command_filename[80]; FILE *command_unit; int i; int i_reverse; int j; int k; int m = 5; int n = 5; char plot_filename[80]; sprintf ( command_filename, "%s_commands.txt", label ); sprintf ( plot_filename, "%s.png", label ); /* Initially, the grid is entirely white (color 0) */ color_index = i4rows_zeros_new ( m, n ); /* Place the pentomino on the grid, so that it is "snug" in the upper left corner. */ for ( i = 0; i < p_m; i++ ) { for ( j = 0; j < p_n; j++ ) { color_index[i*n+j] = p[i*p_n+j]; } } /* Create the command file. */ command_unit = fopen ( command_filename, "wt" ); fprintf ( command_unit, "# %s\n", command_filename ); fprintf ( command_unit, "#\n" ); fprintf ( command_unit, "# Usage:\n" ); fprintf ( command_unit, "# gnuplot < %s\n", command_filename ); fprintf ( command_unit, "#\n" ); fprintf ( command_unit, "set term png\n" ); fprintf ( command_unit, "set output '%s'\n", plot_filename ); fprintf ( command_unit, "set title '%s'\n", label ); /* Get a plot of TRUE SQUARES. */ fprintf ( command_unit, "set xrange [ 0 : 5 ]\n" ); fprintf ( command_unit, "set yrange [ 0 : 5 ]\n" ); fprintf ( command_unit, "set size square\n" ); fprintf ( command_unit, "unset border\n" ); fprintf ( command_unit, "unset tics\n" ); fprintf ( command_unit, "set nokey\n" ); k = 0; for ( i = 0; i < m; i++ ) { for ( j = 0; j < n; j++ ) { k = k + 1; if ( color_index[i*n+j] == 0 ) { strcpy ( color, "white" ); } else if ( color_index[i*n+j] == 1 ) { strcpy ( color, "black" ); } i_reverse = m - 1 - i; fprintf ( command_unit, "set object %d rect from %d, %d to %d, %d back\n", k, j, i_reverse, j + 1, i_reverse + 1 ); fprintf ( command_unit, "set object %d rect fc rgb '%s' fillstyle solid 1.0\n", k, color ); } } /* If you don't have some bogus PLOT command here, all the previous work results in no plot all. Way to go, gnuplot! Here, we plot the function y = -1, which is out of range and won't show up. */ fprintf ( command_unit, "plot -1 with lines\n" ); fclose ( command_unit ); printf ( " PENTOMINO_PLOT created command file '%s'\n", command_filename ); /* Free memory. */ free ( color_index ); 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 }