program main
!*****************************************************************************80
!
!! MAIN is the main program for LOCK_SOLVE.
!
! Discussion:
!
! A random 4 digit TARGET is given.
!
! The user starts at another random 4 digit starting point.
!
! The user can indicate which digit to be advanced, and by how much.
! That digit is advanced, modulo 10.
!
! When the target is achieved, the user has won.
!
! The problem is that the digits are "sticky". So advancing digit 1
! will cause digit 2 to move the same amount. If digit 2 is advanced,
! it will cause digits 1 and 3 to move the same. Similarly, digit 4
! will cause digit 3 to move as well.
!
! Although the problem is still solvable, and solvable in at most 4 steps,
! the complications of stickiness make it harder to see what to do.
!
! This program applies a formula to determine, given the starting and
! desired combinations, the amount that each digit must be advanced.
!
! Licensing:
!
! This code is distributed under the MIT license.
!
! Modified:
!
! 08 May 2011
!
! Author:
!
! John Burkardt
!
integer digit(4)
integer i4_modp
integer solve(4)
integer target(4)
integer x(4)
write ( *, '(a)' ) ' '
write ( *, '(a)' ) 'LOCK_SOLVE'
write ( *, '(a)' ) ' FORTRAN90 version'
write ( *, '(a)' ) ' Solve the lock combination problem.'
write ( *, '(a)') ' '
write ( *, * ) 'Enter the target combination'
read ( *, * ) target(1:4)
write ( *, * ) 'Enter the current combination:'
read ( *, * ) digit(1:4)
x(1:4) = target(1:4) - digit(1:4)
solve(1) = i4_modp ( x(1) - x(3) + x(4), 10 )
solve(2) = i4_modp ( x(3) - x(4), 10 )
solve(3) = i4_modp ( - x(1) + x(2), 10 )
solve(4) = i4_modp ( x(1) - x(2) + x(4), 10 )
write ( *, * ) solve(1:4)
write ( *, '(a)' ) ' '
write ( *, '(a)' ) 'LOCK_SOLVE:'
write ( *, '(a)' ) ' Normal end of execution.'
stop
end
function i4_modp ( i, j )
!*****************************************************************************80
!
!! I4_MODP returns the nonnegative remainder of I4 division.
!
! Discussion:
!
! If
! NREM = I4_MODP ( I, J )
! NMULT = ( I - NREM ) / J
! then
! I = J * NMULT + NREM
! where NREM is always nonnegative.
!
! The MOD function computes a result with the same sign as the
! quantity being divided. Thus, suppose you had an angle A,
! and you wanted to ensure that it was between 0 and 360.
! Then mod(A,360) would do, if A was positive, but if A
! was negative, your result would be between -360 and 0.
!
! On the other hand, I4_MODP(A,360) is between 0 and 360, always.
!
! An I4 is an integer value.
!
! Example:
!
! I J MOD I4_MODP Factorization
!
! 107 50 7 7 107 = 2 * 50 + 7
! 107 -50 7 7 107 = -2 * -50 + 7
! -107 50 -7 43 -107 = -3 * 50 + 43
! -107 -50 -7 43 -107 = 3 * -50 + 43
!
! Licensing:
!
! This code is distributed under the MIT license.
!
! Modified:
!
! 02 March 1999
!
! Author:
!
! John Burkardt
!
! Parameters:
!
! Input, integer I, the number to be divided.
!
! Input, integer J, the number that divides I.
!
! Output, integer I4_MODP, the nonnegative remainder when I is
! divided by J.
!
implicit none
integer i
integer i4_modp
integer j
integer value
if ( j == 0 ) then
write ( *, '(a)' ) ' '
write ( *, '(a)' ) 'I4_MODP - Fatal error!'
write ( *, '(a,i8)' ) ' Illegal divisor J = ', j
stop
end if
value = mod ( i, j )
if ( value < 0 ) then
value = value + abs ( j )
end if
i4_modp = value
return
end