Jump to content

Largest int from concatenated ints: Difference between revisions

→‎{{header|Fortran}}: After a cup of tea...
(→‎{{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. withinWithin the spreadsheet, they are parts of some text, and the notion that takes over is one of a "blunt, heavy object", not alas close to hand.
 
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 longestlargest number be (and by representing numbers as text strings, there is no difficulty with the limits of INTEGER*2 or INTEGER*4 ''etc.'' limits), 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.
 
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 sort 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.
 
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}}==
1,220

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.