# include # include # include "candy_count.h" /******************************************************************************/ int *candy_count_box ( int c, int l, int m, int n ) /******************************************************************************/ /* 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 = ( int * ) malloc ( c * sizeof ( int ) ); 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]; } } free ( counts_2d ); return counts; } /******************************************************************************/ int *candy_count_box_sum ( int c, int l, int m, int n ) /******************************************************************************/ /* 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 = ( int * ) malloc ( c * sizeof ( int ) ); 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; } /******************************************************************************/ int *candy_count_matrix ( int c, int m, int n ) /******************************************************************************/ /* 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 = ( int * ) malloc ( c * sizeof ( int ) ); 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 ) < i4_min ( a, b ) ) { counts[i] = nmin + ( i + 1 ); } else if ( ( i + 1 ) <= i4_max ( a, b ) ) { counts[i] = nmin + i4_min ( a, b ); } else if ( ( i + 1 ) < a + b - 1 ) { counts[i] = nmin + a + b - ( i + 1 ); } else { counts[i] = nmin; } } return counts; } /******************************************************************************/ int *candy_count_matrix_sum ( int c, int m, int n ) /******************************************************************************/ /* 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 = ( int * ) malloc ( c * sizeof ( int ) ); 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; } /******************************************************************************/ int *candy_count_vector ( int c, int n ) /******************************************************************************/ /* 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 = ( int * ) malloc ( c * sizeof ( int ) ); /* 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; } /******************************************************************************/ int *candy_count_vector_sum ( int c, int n ) /******************************************************************************/ /* 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 = ( int * ) malloc ( c * sizeof ( int ) ); 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; } /******************************************************************************/ int i4_max ( int i1, int i2 ) /******************************************************************************/ /* Purpose: i4_max() returns the maximum of two I4's. Licensing: This code is distributed under the MIT license. Modified: 29 August 2006 Author: John Burkardt Input: int I1, I2, two integers to be compared. Output: int I4_MAX, the larger of I1 and I2. */ { int value; if ( i2 < i1 ) { value = i1; } else { value = i2; } return value; } /******************************************************************************/ int i4_min ( int i1, int i2 ) /******************************************************************************/ /* Purpose: i4_min() returns the smaller of two I4's. Licensing: This code is distributed under the MIT license. Modified: 29 August 2006 Author: John Burkardt Input: int I1, I2, two integers to be compared. Output: int I4_MIN, the smaller of I1 and I2. */ { int value; if ( i1 < i2 ) { value = i1; } else { value = i2; } return value; }