Largest int from concatenated ints: Difference between revisions

Content added Content deleted
(→‎{{header|Fortran}}: Ah yes, arrays...)
Line 414: Line 414:


So, the plan is to regard the numbers as being text sequences aligned to the left, containing only digit characters of course - except for the fact that CHARACTER variables often end up having trailing spaces. F2003 formalised a scheme whereby such variables can be "cut-to-fit" as execution proceeds but with earlier Fortrans the standard method is to pay attention to the number of characters in use. F90 introduced a function LEN_TRIM(text) to return the index of the last non-blank character in a text so the only problem now is to decide on how long might the largest number be (and by representing numbers as text strings, there is no difficulty with the limits of INTEGER*2 or INTEGER*4 ''etc.''), and what will be the maximum number of numbers. By devising a subroutine to do the work, these issues can be handled by the caller that is providing the data. The subroutine however intends to sort the collection of texts. This could be done by damaging its parameter which might be regarded as impolite or even unwanted so instead the sort is effected via an array XLAT and juggling its values. This has the advantage that the possibly large elements of the text array are not being moved about, but means that the subroutine must be able to have an XLAT array that is "large enough". F90 standardised the ability for a routine to declare such an array at run-time; previously, arrays within a subroutine (or indeed anywhere) had to have a size fixed at compilation time. In the past this might have been handled by the caller supplying such an array as an additional parameter.
So, the plan is to regard the numbers as being text sequences aligned to the left, containing only digit characters of course - except for the fact that CHARACTER variables often end up having trailing spaces. F2003 formalised a scheme whereby such variables can be "cut-to-fit" as execution proceeds but with earlier Fortrans the standard method is to pay attention to the number of characters in use. F90 introduced a function LEN_TRIM(text) to return the index of the last non-blank character in a text so the only problem now is to decide on how long might the largest number be (and by representing numbers as text strings, there is no difficulty with the limits of INTEGER*2 or INTEGER*4 ''etc.''), and what will be the maximum number of numbers. By devising a subroutine to do the work, these issues can be handled by the caller that is providing the data. The subroutine however intends to sort the collection of texts. This could be done by damaging its parameter which might be regarded as impolite or even unwanted so instead the sort is effected via an array XLAT and juggling its values. This has the advantage that the possibly large elements of the text array are not being moved about, but means that the subroutine must be able to have an XLAT array that is "large enough". F90 standardised the ability for a routine to declare such an array at run-time; previously, arrays within a subroutine (or indeed anywhere) had to have a size fixed at compilation time. In the past this might have been handled by the caller supplying such an array as an additional parameter.

Passing arrays as parameters can be tricky, especially for multi-dimensional arrays. This uses the old style whereby the size is left unstated via the * in <code>TEXT(*)</code>, though one could use <code>TEXT(N)</code> instead - but at the risk that the actual value of N is wrong and array index checking might be confused thereby. Still earlier one would simply place some integer value there, any valid integer, as in <code>TEXT(666)</code>, and not worry about bound checking at all because old-style compilers did not produce checking code even if it was wanted. F90 standardised the MODULE protocol, within which the size is specified as <code>TEXT(:)</code> whereby secret additional parameters are supplied that contain the actual bound information and bound checking will be correct, possibly not so if the <code>TEXT(N)</code> form is used instead and N is wrong. This extra overhead in every use is possibly better than undetected errors in some uses...


The sorting of the text array was to be by the notorious BubbleSort, taking advantage of the fact that each pass delivers the maximum value of the unsorted portion to its final position: the output could thereby be produced as the sort worked. Rather than mess about with early termination (no element being swapped) or attention to the bounds within which swapping took place, attention concentrated upon the comparison. Because of the left-alignment of the texts, a simple comparison seemed sufficient until I thought of unequal text lengths and then the following example. Suppose there are two numbers, 5, and one of 54, 55, or 56 as the other. Via normal comparisons, the 5 would always be first (because short texts are considered expanded with trailing spaces when compared against longer texts, and a space precedes every digit) however the biggest ordering is 5 54 for the first case but 56 5 for the last. This possibility is not exemplified in the specified examples. So, a more complex comparison is required. One could of course write a suitable function and consider the issue there but instead the comparison forms the compound text in the same manner as the result will be, in the two ways AB and BA, and looks to see which yields the bigger sequence. This need only be done for unequal length text pairs.
The sorting of the text array was to be by the notorious BubbleSort, taking advantage of the fact that each pass delivers the maximum value of the unsorted portion to its final position: the output could thereby be produced as the sort worked. Rather than mess about with early termination (no element being swapped) or attention to the bounds within which swapping took place, attention concentrated upon the comparison. Because of the left-alignment of the texts, a simple comparison seemed sufficient until I thought of unequal text lengths and then the following example. Suppose there are two numbers, 5, and one of 54, 55, or 56 as the other. Via normal comparisons, the 5 would always be first (because short texts are considered expanded with trailing spaces when compared against longer texts, and a space precedes every digit) however the biggest ordering is 5 54 for the first case but 56 5 for the last. This possibility is not exemplified in the specified examples. So, a more complex comparison is required. One could of course write a suitable function and consider the issue there but instead the comparison forms the compound text in the same manner as the result will be, in the two ways AB and BA, and looks to see which yields the bigger sequence. This need only be done for unequal length text pairs.
Line 451: Line 453:
ELSE !But if not, construct the actual candidate texts for comparison.
ELSE !But if not, construct the actual candidate texts for comparison.
IF (TEXT(TI)(1:LI)//TEXT(TJ)(1:LJ) !These two will be the same length.
IF (TEXT(TI)(1:LI)//TEXT(TJ)(1:LJ) !These two will be the same length.
1 .LT.TEXT(TJ)(1:LJ)//TEXT(TI)(1:LI)) !Just as above.
1 .LT.TEXT(TJ)(1:LJ)//TEXT(TI)(1:LI)) !Just as above.
2 CALL SWAP(XLAT(I),XLAT(J)) !J shall now follow I.
2 CALL SWAP(XLAT(I),XLAT(J)) !J shall now follow I.
END IF !So much for that comparison.
END IF !So much for that comparison.
Line 461: Line 463:


PROGRAM POKE
PROGRAM POKE
CHARACTER*4 T1(10)
CHARACTER*4 T1(10) !Prepare some example arrays.
CHARACTER*4 T2(4)
CHARACTER*4 T2(4) !To hold the specified examples.
INTEGER MSG
INTEGER MSG
COMMON /IODEV/ MSG
COMMON /IODEV/ MSG
DATA T1(1:8)/"1","34","3","98","9","76","45","4"/
DATA T1(1:8)/"1","34","3","98","9","76","45","4"/
DATA T2/"54","546","548","60"/
DATA T2/"54","546","548","60"/
MSG = 6
MSG = 6 !Standard output.
WRITE (MSG,1)
WRITE (MSG,1)
1 FORMAT ("Takes a list of integers and concatenates them so as ",
1 FORMAT ("Takes a list of integers and concatenates them so as ",
Line 489: Line 491:
END DO !Thus, the numbers are aligned left in the text field.
END DO !Thus, the numbers are aligned left in the text field.
CALL BIGUP(T1,10)
CALL BIGUP(T1,10)
END</lang>
END </lang>
Output: the Fortran compiler ignores spaces when reading fortran source, so hard-core fortranners should have no difficulty doing so for the output...
Output: the Fortran compiler ignores spaces when reading fortran source, so, hard-core fortranners should have no difficulty doing likewise for the output...
<pre>
<pre>
Takes a list of integers and concatenates them so as to produce the biggest possible number.
Takes a list of integers and concatenates them so as to produce the biggest possible number.