Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
115
Task/Magic-constant/Fortran/magic-constant.f
Normal file
115
Task/Magic-constant/Fortran/magic-constant.f
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
! Magic constant
|
||||
! tested with Intel ifx (IFX) 2025.2.1 20250806 on Kubuntu 25.10
|
||||
! GNU gfortran (Ubuntu 15.2.0-4ubuntu4) 15.2.0 on Kubuntu 25.10
|
||||
! VSI Fortran x86-64 V8.7-001 on OpenVMS V9.2-3
|
||||
! U.B., March 2026
|
||||
!
|
||||
program magicConstant
|
||||
implicit none
|
||||
integer,parameter :: DP=8, k_int=4
|
||||
|
||||
real(kind=DP), parameter :: realten=10._DP
|
||||
|
||||
integer(kind=k_int) :: order, ii
|
||||
! Starting at order 3, show the first 20 magic constants.
|
||||
|
||||
write (*, '("Count Order Magic")')
|
||||
order = 3
|
||||
do ii=1,20
|
||||
write (*,'(i5, 2x, i5,2x,i0)') ii, order, magicNumber (order)
|
||||
order = order + 1
|
||||
end do
|
||||
|
||||
! Show the 1000th magic constant. (Order 1003)
|
||||
! 1st magic constant is for order 3, i.e. order = count+2
|
||||
write (*,*)
|
||||
order = 1002
|
||||
ii = 1000
|
||||
write (*,'(i5, 2x, i5,2x,i0,/)') ii, order, magicNumber (order)
|
||||
!
|
||||
! Find and show the order of the smallest N x N magic square whose constant is greater than 10^1 through 10^10.
|
||||
! Stretch
|
||||
! Find and show the order of the smallest N x N magic square whose constant is greater than 10^11 through 10^20.
|
||||
!
|
||||
write (*, '(" Limit Order")')
|
||||
do i=1,20
|
||||
order = unmagic (realten**i) ! Using REAL for all 10^i to avoid 132 bit integers
|
||||
write (*,'("10**", i2, 2x, i0)') i, order
|
||||
end do
|
||||
|
||||
contains
|
||||
|
||||
! =============================================
|
||||
! Return the magic number of a sqare of order n
|
||||
! =============================================
|
||||
pure function magicNumber (n) result (retval)
|
||||
implicit none
|
||||
integer(kind=k_int), intent(in) :: n
|
||||
integer(kind=k_int) :: retval
|
||||
integer (kind=k_int) :: nn
|
||||
nn = n
|
||||
retval = (nn**3+nn) / 2
|
||||
|
||||
end function magicNumber
|
||||
|
||||
! =====================================================================================
|
||||
! return the order of the smallest magic square with a magic number >= a given "magic"
|
||||
! =====================================================================================
|
||||
function unMagic (magic) result (order)
|
||||
implicit none
|
||||
real (kind=DP), intent(in) :: magic
|
||||
|
||||
real (kind=DP) :: guess
|
||||
integer(kind=k_int) :: order
|
||||
|
||||
integer(kind=k_int) :: lo,hi,mid, mnc, mnf
|
||||
|
||||
! Following formula calculates an approximate value of the order we're looking for.
|
||||
! This is because the term n^3 in the formula for the Magic Number is dominant,
|
||||
! so the correct (real) value of the magic square's order is most likely between
|
||||
! Floor and Ceiling of this first guess, so the integer result is CEILING (guess)
|
||||
!
|
||||
! It turned out this approximation and using ceiling(this guess) as function
|
||||
! value is correct for all test values up to 10^20.
|
||||
|
||||
guess = (2._DP*magic)**(1._8/3._8)
|
||||
|
||||
! This check is only here because above reasoning is (maybe) plausible, but it is
|
||||
! not a conclusive proof. This function allows us to check whether any results are incorrect.
|
||||
if (checkGuess (magic, guess)) then
|
||||
order = ceiling (guess, k_int)
|
||||
else
|
||||
order=-1 ! signal fault
|
||||
print *, 'Problem: Guess for inverse magic fails for ', magic
|
||||
endif
|
||||
|
||||
end function unMagic
|
||||
|
||||
! ========================================================================================================
|
||||
! Check if the value of "guess" fulfills the condition
|
||||
! magicNumber (floor(guess) <= magic < magicNumber(ceiling(guess)
|
||||
! Special care has be taken to avoid integer overflows. Note that argument 'magic' can be as large as 10^20,
|
||||
! and 'guess' is (2*guess)^(1/3)), which is .lt. 10^7. So guess , floor(guess) and ceiling(guess)
|
||||
! can be represented by a 32-bin integer word, but 'magic' would cause an integer overflow.
|
||||
! So we replicate the calculation of the integer function magicNumber(n) here, but we
|
||||
! use double precision results instead of integers.
|
||||
! ========================================================================================================
|
||||
!
|
||||
function checkGuess (magic, guess) result (guessIsOK)
|
||||
real (kind=DP), intent(in) :: magic, guess
|
||||
logical :: guessIsOK
|
||||
|
||||
real (kind=DP) :: FloorGuess, CeilingGuess
|
||||
real (kind=dp) :: CeilingMagic,FloorMagic
|
||||
|
||||
FloorGuess = real (floor (guess, k_int) , DP)
|
||||
FloorMagic = (Floorguess**3 + Floorguess) /2.0_DP
|
||||
|
||||
CeilingGuess = real (ceiling (guess, k_int) , DP)
|
||||
CeilingMagic = (CeilingGuess**3 + Ceilingguess) /2.0_DP
|
||||
|
||||
guessIsOK = FloorMagic .le. magic .and. magic .lt. CeilingMagic
|
||||
|
||||
end function checkGuess
|
||||
|
||||
end program magicConstant
|
||||
Loading…
Add table
Add a link
Reference in a new issue