Largest int from concatenated ints: Difference between revisions
Content deleted Content added
→{{header|Go}}: Add Fortran. |
→{{header|Fortran}}: After a cup of tea... |
||
Line 411:
=={{header|Fortran}}==
There is often a potential ambiguity when reading numbers. While three definitely names the Platonic number notion, 3 might instead be regarded as being a text that happens to have the glyph of a number but is not a number. This sort of discussion arises when a spreadsheet has read in a text file and behold! numbers are on the display and they look just like what is displayed when numbers are being shown, but, they are ''not'' numbers, they are only drawn that way.
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
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 text pairs.
The source is F77 style, except for the declaration of XLAT(N), the use of <N> in the FORMAT statements instead of some large constant or similar, and the ability to declare an array via constants as in <code>(/"5","54"/)</code> rather than mess about declaring arrays and initialising them separately. The <code>I0</code> format to convert a number (an actual number) into a digit string aligned leftwards in a CHARACTER variable of sufficient size is also a F90 introduction, though the B6700 compiler allowed a code <code>J</code> instead. This last is to demonstrate usage of actual numbers for those unpersuaded by the argument for ambiguity that allows for texts. If the <code>I0</code> format code is unavailable then <code>I9</code> (or some suitable size) could be used, followed by <code>text = ADJUSTL(text)</code>, except that this became an intrinsic function only in F90, so perhaps you will have to write a simple alignment routine. <lang Fortran> SUBROUTINE SWAP(A,B) !Why can't the compiler supply these!
INTEGER A,B,T
T = B
B = A
A = T
END
SUBROUTINE BIGUP(TEXT,N) !Outputs the numbers in TEXT to give the biggest number.
CHARACTER*(*) TEXT(*) !The numbers as text, aligned left.
INTEGER N !The number of them.
INTEGER XLAT(N),L(N) !An index and a set of lengths.
INTEGER I,J,M !Assorted steppers.
INTEGER TI,TJ !Fingers to a text.
INTEGER LI,LJ !Lengths of the fingered texts.
INTEGER MSG !I/O unit number.
COMMON /IODEV/ MSG !Old style.
DO I = 1,N !Step through my supply of texts.
XLAT(I) = I !Preparing a finger to them.
L(I) = LEN_TRIM(TEXT(I)) !And noting their last non-blank.
END DO !On to the next.
WRITE (MSG,1) "Supplied",(TEXT(I)(1:L(I)), I = 1,N) !Show the grist.
1 FORMAT (A12,":",<N>(A,",")) !Instead of <N>, 666 might suffice.
Crude bubblesort. No attempt at noting the bounds of swaps made.
DO M = N,1,-1 !Just for fun, go backwards.
DO I = 2,M !Start a scan.
J = I - 1 !Comparing element I to element I - 1.
TI = XLAT(I) !Thus finger the I'th text in XLAT order.
TJ = XLAT(J) !And its supposed predecessor.
LI = L(TI) !The length of the fingered text.
LJ = L(TJ) !All this to save on typing below.
IF (LI .EQ. LJ) THEN !If the texts are equal lengths,
IF (TEXT(TI).LT.TEXT(TJ)) CALL SWAP(XLAT(I),XLAT(J)) !A simple 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.
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.
END IF !So much for that comparison.
END DO !On to the next.
END DO !The original plan was to reveal element XLAT(M) as found.
WRITE (MSG,2) "Biggest",(TEXT(XLAT(I))(1:L(XLAT(I))),I = N,1,-1) !But, all at once is good too.
2 FORMAT (A12,":",<N>(A," ")) !The space maintains identity.
END !That was fun.
PROGRAM POKE
CHARACTER*4 T1(10)
CHARACTER*4 T2(4)
INTEGER MSG
COMMON /IODEV/ MSG
DATA T1(1:8)/"1","34","3","98","9","76","45","4"/
DATA T2/"54","546","548","60"/
MSG = 6
WRITE (MSG,1)
1 FORMAT ("Takes a list of integers and concatenates them so as ",
1 "to produce the biggest possible number.",/,
2 "The result is shown with spaces between the parts ",
3 "to show provenance. Ignore them otherwise."/)
CALL BIGUP(T1,8)
WRITE (MSG,*)
CALL BIGUP(T2,4)
WRITE (MSG,*) "These are supplied in lexicographical order..."
CALL BIGUP((/"5","54"/),2)
WRITE (MSG,*) "But this is not necessarily the biggest order."
CALL BIGUP((/"5","56"/),2)
WRITE (MSG,*) "And for those who count..."
DO I = 1,10
WRITE (T1(I),"(I0)") I !This format code produces only the necessary text.
END DO !Thus, the numbers are aligned left in the text field.
CALL BIGUP(T1,10)
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...
<pre>
Takes a list of integers and concatenates them so as to produce the biggest possible number.
The result is shown with spaces between the parts to show provenance. Ignore them otherwise.
Supplied:1,34,3,98,9,76,45,4,
Biggest:9 98 76 45 4 34 3 1
Supplied:54,546,548,60,
Biggest:60 548 546 54
These are supplied in lexicographical order...
Supplied:5,54,
Biggest:5 54
But this is not necessarily the biggest order.
Supplied:5,56,
Biggest:56 5
And for those who count...
Supplied:1,2,3,4,5,6,7,8,9,10,
Biggest:9 8 7 6 5 4 3 2 1 10
</pre>
=={{header|Go}}==
|