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