# include # include # include using namespace std; # include "candy_count.hpp" //****************************************************************************80 int *candy_count_box ( int c, int l, int m, int n ) //****************************************************************************80 // // Purpose: // // candy_count_box() counts candy types in an LxMxN box. // // Discussion: // // We are given a box of candy containing C distinct types, and // asked to report how many of each type there are. // // In this case, the box is an L by M by N matrix represented as A(I,J,K). // // The box entry in row I, column J, level K will store candy type C, where // A(i,j,k) = mod ( I + J + K, C ). // // The effect of this numbering scheme is that the candy type is // constant along diagonal lines and sheets. // // The task is to determine, for a given set of C, L, M and N, // the number of candies of each type. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 24 June 2024 // // Author: // // John Burkardt // // Input: // // int c: the number of types of candy. // // int l, m, n: the number of rows, columns, and levels in the candy box. // // Output: // // int counts(c): the number of each type of candy in the box. // { int *counts; int *counts_2d; int i; int ic; int ic2; int k; int lf; int lr; counts = new int[n]; for ( i = 0; i < c; i++ ) { counts[i] = 0; } // // Do the computation for the first level: // counts_2d = candy_count_matrix ( c, m, n ); // // L = LF * C + LR // Note that C will automatically return a rounded down int // result for (l/c). // lf = ( l / c ); lr = l - lf * c; // // Part of the box can be regarded as LF repetitions // of a stack of sheets for which the item in the (K,0,0) position is // successively 0, 1, 2, ..., C-1. // // Warning: C (a % b) is perfectly capable of returning a NEGATIVE value. // Hence, we replace "mod(ic-k,c)" by "mod(c+ic-k,c)". // for ( k = 0; k < c; k++ ) { for ( ic = 0; ic < c; ic++ ) { ic2 = ( c + ic - k ) % c; counts[ic] = counts[ic] + lf * counts_2d[ic2]; } } // // Now there are 0 <= LR < C more sheets, for which the item in the (K,0,0) // position successively is 0, 1, 2, ..., LR-1. // for ( k = 0; k < lr; k++ ) { for ( ic = 0; ic < c; ic++ ) { ic2 = ( c + ic - k ) % c; counts[ic] = counts[ic] + counts_2d[ic2]; } } delete [] counts_2d; return counts; } //****************************************************************************80 int *candy_count_box_sum ( int c, int l, int m, int n ) //****************************************************************************80 // // Purpose: // // candy_count_box_sum() counts candy types in an LxMxN box. // // Discussion: // // This function is a "stupid" version of candy_count_box(). Instead of // using a formula, it sets up the candy box, and counts items one by one. // It is useful as a check of the intelligent version. // // We are given a box of candy containing C distinct types, and // asked to report how many of each type there are. // // In this case, the box is an L by M by N matrix represented as A(I,J,K). // // The box entry in row I, column J, level K will store candy type C, where // A(i,j,k) = mod ( I + J + K, C ). // // The effect of this numbering scheme is that the candy type is // constant along diagonal lines and sheets. // // The task is to determine, for a given set of C, L, M and N, // the number of candies of each type. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 24 June 2024 // // Author: // // John Burkardt // // Input: // // int c: the number of types of candy. // // int l, m, n: the number of rows, columns, and levels in the candy box. // // Output: // // int counts(c): the number of each type of candy in the box. // { int cijk; int *counts; int i; int j; int k; counts = new int[n]; for ( i = 0; i < c; i++ ) { counts[i] = 0; } for ( i = 0; i < l; i++ ) { for ( j = 0; j < m; j++ ) { for ( k = 0; k < n; k++ ) { cijk = ( i + j + k ) % c; counts[cijk] = counts[cijk] + 1; } } } return counts; } //****************************************************************************80 int *candy_count_matrix ( int c, int m, int n ) //****************************************************************************80 // // Purpose: // // candy_count_matrix() counts candy types in a matrix. // // Discussion: // // We are given a box of candy containing C distinct types, and // asked to report how many of each type there are. // // In this case, the box is an M by N matrix represented as A(I,J). // We will assume that rows and columns are indexed by I and J. // // The box entry in row I, column J will store candy type C, where // A(i,j) = mod ( I + J , C ). // // The effect of this numbering scheme is that the candy type is // constant along diagonal lines. // // The task is to determine, for a given set of C, M and N, // the number of candies of each type. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 24 June 2024 // // Author: // // John Burkardt // // Input: // // int c: the number of types of candy. // // int m, n: the number of rows and columns in the candy box. // // Output: // // int counts(c): the number of each type of candy in the box. // { int a; int b; int *counts; int i; int nmin; counts = new int[n]; a = ( m % c ); b = ( n % c ); nmin = ( ( m * n - a * b ) / c ); for ( i = 0; i < c; i++ ) { if ( ( i + 1 ) <= a + b - 1 - c ) { counts[i] = nmin + a + b - c; } else if ( ( i + 1 ) < min ( a, b ) ) { counts[i] = nmin + ( i + 1 ); } else if ( ( i + 1 ) <= max ( a, b ) ) { counts[i] = nmin + min ( a, b ); } else if ( ( i + 1 ) < a + b - 1 ) { counts[i] = nmin + a + b - ( i + 1 ); } else { counts[i] = nmin; } } return counts; } //****************************************************************************80 int *candy_count_matrix_sum ( int c, int m, int n ) //****************************************************************************80 // // Purpose: // // candy_count_matrix_sum() counts candy types in a matrix. // // Discussion: // // This function is a "stupid" version of candy_count_matrix(). Instead of // using a formula, it sets up the candy box, and counts items one by one. // It is useful as a check of the intelligent version. // // We are given a box of candy containing C distinct types, and // asked to report how many of each type there are. // // In this case, the box is an M by N matrix represented as A(I,J). // We will assume that rows and columns are indexed by I and J. // // The box entry in row I, column J will store candy type C, where // A(i,j) = mod ( I + J, C ). // // The effect of this numbering scheme is that the candy type is // constant along diagonal lines. // // The task is to determine, for a given set of C, M and N, // the number of candies of each type. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 24 June 2024 // // Author: // // John Burkardt // // Input: // // int c: the number of types of candy. // // int m, n: the number of rows and columns in the candy box. // // Output: // // int counts(c): the number of each type of candy in the box. // { int cij; int *counts; int i; int j; counts = new int[n]; for ( i = 0; i < c; i++ ) { counts[i] = 0; } for ( i = 0; i < m; i++ ) { for ( j = 0; j < n; j++ ) { cij = ( i + j ) % c; counts[cij] = counts[cij] + 1; } } return counts; } //****************************************************************************80 int *candy_count_vector ( int c, int n ) //****************************************************************************80 // // Purpose: // // candy_count_vector() counts candy types in a vector. // // Discussion: // // We are given a box of candy containing C distinct types, and // asked to report how many of each type there are. // // In this case, the box is a vector, which can hold N items, // indexed 1 through N. // // The candy types occur in sequence, that is, the first item is // candy type 0, item 1 is type 1, item C-1 is type C-1. Then // the types repeat, so item C is type 0, and so on. // // This version of the problem is simple to understand and solve. // The problem is more interesting if the candy is stored in a // rectangular array, or a 3-dimensional box. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 24 June 2024 // // Author: // // John Burkardt // // Input: // // int c: the number of types of candy. // // int n: the number of columns in the candy box. // // Output: // // int counts(c): the number of each type of candy in the box. // { int *counts; int i; int n_min; int n_rem; counts = new int[n]; // // N = N_MIN * C + N_REM // n_min = ( n / c ); // // Everybody gets at least N_MIN. // for ( i = 0; i < c; i++ ) { counts[i] = n_min; } // // There are N_REM candies remaining. // Give 1 each to types 1 through N_REM. // n_rem = n - n_min * c; for ( i = 0; i < n_rem; i++ ) { counts[i] = counts[i] + 1; } return counts; } //****************************************************************************80 int *candy_count_vector_sum ( int c, int n ) //****************************************************************************80 // // Purpose: // // candy_count_vector_sum() counts candy types in a vector. // // Discussion: // // This function is a "stupid" version of candy_count_vector(). Instead of // using a formula, it sets up the candy box, and counts items one by one. // It is useful as a check of the intelligent version. // // We are given a box of candy containing C distinct types, and // asked to report how many of each type there are. // // In this case, the box is a vector, which can hold N items, // indexed 1 through N. // // This version of the problem is simple to understand and solve. // The problem is more interesting if the candy is stored in a // rectangular array, or a 3-dimensional box. // // Licensing: // // This code is distributed under the MIT license. // // Modified: // // 24 June 2024 // // Author: // // John Burkardt // // Input: // // int c: the number of types of candy. // // int n: the number of columns in the candy box. // // Output: // // int counts(c): the number of each type of candy in the box. // { int ci; int *counts; int i; counts = new int[n]; for ( i = 0; i < c; i++ ) { counts[i] = 0; } for ( i = 0; i < n; i++ ) { ci = ( i % c ); counts[ci] = counts[ci] + 1; } return counts; }