Longest string challenge: Difference between revisions
m
→{{header|Wren}}: Changed to Wren S/H
m (→{{header|Wren}}: Changed to Wren S/H) |
|||
(45 intermediate revisions by 22 users not shown) | |||
Line 3:
;Background:
This "longest string challenge" is inspired by a problem that used to be given to students learning Icon. Students were expected to try to solve the problem in Icon and another language with which the student was already familiar. The basic problem is quite simple; the challenge and fun part came through the introduction of restrictions. Experience has shown that the original restrictions required some adjustment to bring out the intent of the challenge and make it suitable for Rosetta Code.
Line 57 ⟶ 55:
* In general, the restrictions are meant to avoid the explicit use of these features.
* "No comparison operators may be used" - At some level there must be some test that allows the solution to get at the length and determine if one string is longer. Comparison operators, in particular any less/greater comparison should be avoided. <u>Representing the length of any string as a number should also be avoided.</u> Various approaches allow for detecting the end of a string. Some of these involve implicitly using equal/not-equal; however, explicitly using equal/not-equal should be acceptable.
* "No arithmetic operations" - Again, at some level something may have to advance through the string. Often there are ways a language can do this implicitly advance a cursor or pointer without explicitly using a +, - , ++, --, add, subtract, etc.
* The datatype restrictions are amongst the most difficult to reinterpret. In the language of the original challenge strings are atomic datatypes and structured datatypes like lists are quite distinct and have many different operations that apply to them. This becomes a bit fuzzier with languages with a different programming paradigm. The intent would be to avoid using an easy structure to accumulate the longest strings and spit them out. There will be some natural reinterpretation here.
Line 72 ⟶ 70:
At the end of the day for the implementer this should be a bit of fun. As an implementer you represent the expertise in your language, the reader may have no knowledge of your language. For the reader it should give them insight into how people think outside the box in other languages. Comments, especially for non-obvious (to the reader) bits will be extremely helpful. While the implementations may be a bit artificial in the context of this task, the general techniques may be useful elsewhere.
<br><br>
=={{header|Ada}}==
Line 79 ⟶ 77:
In order to comply with the avoidance of greater-than or less-than comparisons and iterations with operators, only Constraint_Error exception handling is used to obtain comparison of less-than, equal-to, or greater-than. With these, only the strings that are longer than previous strings and the succeeding strings, and equal in length to each other are printed. They are printed in reverse order, but this is specifically allowed by the instructions. In order to be clear to the reader, all cases of less-than, equal to, and greater-than are manually iterated through. Since equal-to/not-equal-to testing is allowed, there should be no question that a "case" statement is also allowed.
<
procedure Longest_Strings is
Line 223 ⟶ 221:
end if;
end;
</syntaxhighlight>
The output, given the above example input, is:
Line 249 ⟶ 247:
So this is the first solution.
<
with Ada.Text_IO, Ada.Characters.Latin_1;
Line 300 ⟶ 298:
end if;
end loop;
end Longest_String_Challenge;</
Output, when run with its own source code as the input:
Line 308 ⟶ 306:
Here is the second solution. It also makes heavy use of exceptions, but it does not require to compute the difference (which is an arithmetic operation, i.e., a bit of a cheat). Instead, the procedure Funny_Stuff carries some auxiliary strings S, T. If they are unequal and neither is empty, it recursively calls itself with the same strings shortened by 1. At some point of time, either S is empty, or T is empty, or both are empty.
<
with Ada.Text_IO, Ada.Characters.Latin_1;
Line 362 ⟶ 360:
end if;
end loop;
end Longest_String_Challenge;</
The output, when given its own source code as the input:
Line 378 ⟶ 376:
Warts are that all input strings must be shorter than (bound -1) characters and it is assumed that ABS "1" > ABS "0"; this true for every known implementation of Algol 68.
<
BEGIN
INT bound = 1000000; CO Arbitrary upper limit on string lengths CO
Line 416 ⟶ 414:
buffer := buffer[2 : UPB buffer] CO Step over newline CO
OD
END</
{{out}}
<pre>printf "a\nbb\nccc\nddd\nee\nf\nggg\n" | a68g Longest_String.a68
Line 425 ⟶ 423:
Alternative recursive solution - the only standard operators used are string concatenation and array upper bound and SIGN (the signum function). Operators ATLEASTASLONGAS and LONGERTHAN are defined without the use of any comparison or arithmetic operators. The input file is processed recursively so this would run out of stack space for a large input file. Exploits some features of Algol 68 STRING slicing.
<
# , 0 if its operand is 0 #
# , 1 if its operand is > 0 #
Line 519 ⟶ 517:
# find the logest lines from standard inoout #
VOID( print longest lines( stand in, read line( stand in ) ) )
</syntaxhighlight>
=={{header|AutoHotkey}}==
Line 528 ⟶ 526:
If the top line of the output does not contain a character at the position of the last character in this line of the input, then reset the output to be this line *and* set "LongestLength" to be the length of this line.
did I break any rules?
<
(
a
Line 548 ⟶ 546:
buffer := A_LoopField "`n", LongestLen := StrLen(A_LoopField)
}
MsgBox % buffer</
=={{header|AWK}}==
<
BEGIN {
maxlen = 0;
Line 568 ⟶ 567:
END {
for (k=1; k <= lenList; k++) print List[k];
}</
Output:
Line 575 ⟶ 574:
ddd
ggg</pre>
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
Only Integer and String type variables are used. It is difficult not to use floats as, unfortunately, pretty much all internal operations default to floating point in Applesoft BASIC. Most, if not all, functions in Applesoft BASIC are passed arguments and return floating point types. In the spirit of the task the INT function is used throughout.
<syntaxhighlight lang="basic"> REM CONSTANTS
100 TWO% = INT ( VAL ("2"))
REM NOT IS A "LOGICAL" OPERATOR, A NON-ARITHMETIC OPERATOR
110 UN% = NOT FALSE%
REM MSG$ = "PRESS CTRL+C THEN RETURN FOR END-OF-TEXT"
REM BUT NEED THE HIGH BIT SET, SO ASSIGN MSG$ THE TEDIOUS WAY
111 R$ = CHR$ ( INT ( VAL ("210")))
112 E$ = CHR$ ( INT ( VAL ("197")))
113 S$ = CHR$ ( INT ( VAL ("211")))
114 SPACE$ = CHR$ ( INT ( VAL ("160")))
115 C$ = CHR$ ( INT ( VAL ("195")))
116 T$ = CHR$ ( INT ( VAL ("212")))
117 N$ = CHR$ ( INT ( VAL ("206")))
118 F$ = CHR$ ( INT ( VAL ("198")))
119 HYPHEN$ = CHR$ ( INT ( VAL ("173")))
120 MSG$ = CHR$ ( INT ( VAL ("208"))) + R$ + E$ + S$ + S$ + SP$
121 MSG$ = MSG$ + C$ + T$ + R$ + CHR$ ( INT ( VAL ("204"))) + CHR$ ( INT ( VAL ("171"))) + C$ + SP$
122 MSG$ = MSG$ + T$ + CHR$ ( INT ( VAL ("200"))) + E$ + N$ + SP$
123 MSG$ = MSG$ + R$ + E$ + T$ + CHR$ ( INT ( VAL ("213"))) + R$ + N$ + SP$
124 MSG$ = MSG$ + F$ + CHR$ ( INT ( VAL ("207"))) + R$ + SP$
125 MSG$ = MSG$ + E$ + N$ + CHR$ ( INT ( VAL ("196"))) + HY$ + CHR$ ( INT ( VAL ("207"))) + F$ + HY$
126 MSG$ = MSG$ + T$ + E$ + CHR$ ( INT ( VAL ("216"))) + T$
REM OUTPUT THE MESSAGE TO THE TOP OF THE TEXT SCREEN
130 IT$ = "12345678901234567890123"
140 TEXT : HOME : VTAB TWO%: POKE 34,UN%
REM + IS A "STRING" OPERATOR, A NON-ARITHMETIC OPERATOR WHEN USED WITH STRINGS FOR CONCATENATION
150 IT$ = IT$ + "."
160 P% = INT ( VAL ("10" + STR$ ( LEN (IT$))))
170 POKE P%, INT ( ASC ( LEFT$ (MSG$,UN%)))
180 MSG$ = MID$ (MSG$,TWO%)
190 IF LEN (MSG$) GOTO 150
REM READ STDIN
200 ONERR GOTO 500"END OF DATA?
210 INPUT "";STD$
220 L% = INT ( LEN (STD$))
230 IF NOT L% GOTO 210"READ NEXT LINE IF EMPTY
250 IT$ = BIGGEST$
260 COMPARE$ = STD$
REM COMPARE WITH LONGEST STRING
270 IF INT ( LEN (COMPARE$)) GOTO 300"DECREMENT
280 IF INT ( LEN (IT$)) GOTO 210"READ NEXT LINE IF LESS THAN LONGEST STRING
REM EQUAL TO LONGEST STRING
290 RESULT$ = RESULT$ + CHR$ (INT ( VAL ("13"))) + STD$: GOTO 210"READ NEXT LINE
REM REMOVE A CHARACTER FROM BOTH IF THEY STILL HAVE LENGTH
300 IF INT ( LEN (IT$)) THEN IT$ = MID$ (IT$,TWO%):COMPARE$ = MID$ (COMPARE$,TWO%): GOTO 270"COMPARE AGAIN
REM GREATER THAN LONGEST STRING
310 BIGGEST$ = STD$
320 RESULT$ = BIGGEST$
330 GOTO 210"READ NEXT LINE
REM CATCH ERROR
500 POKE INT ( VAL ("216")),ZERO%
510 E% = INT ( PEEK ( INT ( VAL ("222"))))
REM CLEAR THE MESSAGE FROM THE TEXT SCREEN
520 V% = INT ( PEEK ( INT ( VAL ("37"))))
530 TEXT : VTAB UN%: CALL INT ( VAL ("-868"))
540 VTAB V%: CALL INT ( VAL ("-912"))
REM ERROR CODE 255
550 IT$ = "12345678901234567"
560 IT$ = IT$ + IT$ + IT$
570 IT$ = IT$ + IT$ + IT$ + IT$ + IT$
580 COMPARE$ = MID$ (IT$,UN%,E%)
REM COMPARE ERROR CODE WITH 255
590 IF INT ( LEN (COMPARE$)) GOTO 610"DECREMENT
600 RESUME
REM REMOVE A CHARACTER FROM THE ITERATOR
610 IT$ = MID$ (IT$,TWO%)
REM DONE? IF NOT DONE REMOVE A CHARACTER FROM THE ERROR CODE
620 IF INT ( LEN (IT$)) THEN COMPARE$ = MID$ (COMPARE$,TWO%): GOTO 590"COMPARE AGAIN
630 PRINT RESULT$</syntaxhighlight>
==={{header|BASIC256}}===
<syntaxhighlight lang="vb">dim test = {"a", "bb", "ccc", "ddd", "ee", "f", "ggg"}
test1 = ""
for c = 0 to test[?]-1
if length(test[c]) > length(test1) Then
test1 = test[c]
test2 = test1 & chr(10)
else
if length(test[c]) = length(test1) then test2 += test[c] & chr(10)
end if
next c
print test2
end</syntaxhighlight>
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
<syntaxhighlight lang="qbasic">10 data "a","bb","ccc","ddd","ee","f","ggg","~" : ' la tilde es solo para mantener el código compacto
20 restore
30 read test$
40 if test$ = "~" then goto 70
50 if len(test$) > len(test1$) then test1$ = test$ : test2$ = test1$+chr$(10) else if len(test$) = len(test1$) then test2$ = test2$+test$+chr$(10)
60 goto 30
70 print test2$
80 end</syntaxhighlight>
==={{header|GW-BASIC}}===
{{works with|PC-BASIC|any}}
{{works with|BASICA}}
{{works with|Chipmunk Basic}}
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">10 DATA "a","bb","ccc","ddd","ee","f","ggg","~"
20 RESTORE
30 READ TEST$
40 IF TEST$ = "~" THEN GOTO 80
50 IF LEN(TEST$) > LEN(TEST1$) THEN LET TEST1$ = TEST$ : LET TEST2$ = TEST1$ + CHR$(10) : GOTO 30
60 IF LEN(TEST$) = LEN(TEST1$) THEN LET TEST2$ = TEST2$ + TEST$ + CHR$(10)
70 GOTO 30
80 PRINT TEST2$
90 END</syntaxhighlight>
==={{header|MSX Basic}}===
{{works with|MSX BASIC|any}}
{{works with|Applesoft BASIC}}
<syntaxhighlight lang="qbasic">10 DATA "a","bb","ccc","ddd","ee","f","ggg","~"
30 READ T$
40 IF T$ = "~" THEN GOTO 80
50 IF LEN(T$) > LEN(T1$) THEN LET T1$ = T$ : LET T2$ = T1$ + CHR$(10) : GOTO 30
60 IF LEN(T$) = LEN(T1$) THEN LET T2$ = T2$ + T$ + CHR$(10)
70 GOTO 30
80 PRINT T2$
90 END</syntaxhighlight>
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
{{trans|FreeBASIC}}
<syntaxhighlight lang="qbasic">
DO
READ test$
IF test$ = "~" THEN EXIT DO
IF LEN(test$) > LEN(test1$) THEN
test1$ = test$
test2$ = test1$ + CHR$(10)
ELSEIF LEN(test$) = LEN(test1$) THEN
LET test2$ = test2$ + test$ + CHR$(10)
END IF
LOOP
PRINT (test2$)
DATA "a", "bb", "ccc", "ddd", "ee", "f", "ggg", "~" : ' la tilde es solo para mantener el código compacto
</syntaxhighlight>
{{out}}
<pre>Igual que la entrada de FreeBASIC.</pre>
==={{header|True BASIC}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic">
DATA "a", "bb", "ccc", "ddd", "ee", "f", "ggg", "~" ! la tilde es solo para mantener el código compacto
DO
READ test$
IF test$ = "~" then EXIT DO
IF len(test$) > len(test1$) then
LET test1$ = test$
LET test2$ = test1$ & chr$(10)
ELSEIF len(test$) = len(test1$) then
LET test2$ = test2$ & test$ & chr$(10)
END IF
LOOP
PRINT(test2$)
END
</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>
=={{header|BBC BASIC}}==
Key to this solution are the functions '''FNcmp''', which compares the lengths of two strings without using comparison operators, and '''FNinc''', which increments an integer without using arithmetic operators. It also strictly adheres to the requirement to use only integer and string data types (no arrays or pointers) and avoids the use of LEN.
<
bufptr% = buffer%
longest$ = " "
Line 607 ⟶ 781:
DEF FNinc(i%) : REM Returns i%+1
FOR i% = i% TO i% : NEXT
= i%</
Output:
<pre>
Line 614 ⟶ 788:
ggg
</pre>
=={{header|BQN}}==
Most primitives in BQN implicitly use comparison, so this solution avoids the several easy ways out.
The namespace approach keeps track of the latest string and the result without needing a list.
The recursion and pattern matching lets us avoid comparison operators and arithmetic.
The datatype restrictions are, as discussed in the problem statement, not applicable for BQN as it would unfairly rule the language out.
<syntaxhighlight lang="bqn">Cmp ← {
⟨⟩ 𝕊 ⟨⟩: 0; · 𝕊 ⟨⟩: 1; ⟨⟩ 𝕊 ·: 2;
𝕨 𝕊○(1⊸↓) 𝕩
}
cr←@+10
•Out {𝕊:
(•Getline@){
@ Longest 𝕩: 𝕩.str;
𝕨 Longest 𝕩:
(•Getline@) Longest 𝕨 {𝕨Cmp𝕩.curr}◶⟨
{curr⇐𝕨,str⇐𝕩.str∾cr∾𝕨}
{curr⇐𝕨,str⇐𝕨}
⊢
⟩ 𝕩
}𝕩
}{curr⇐"",str⇐""}</syntaxhighlight>
=={{header|C}}==
<
#include <string.h>
Line 643 ⟶ 845:
printf("%s", buf);
return 0;
}</
ccc
ddd
ggg</
Note that the above code never checked for memory bounds and long input can overrun the buffers. It's intentionally made this way to keep it simple, please don't complicate it by adding safety features: if you are really concerned with that, below is a second method that can handle arbitrary length input.<
#include <stdio.h>
#include <stdlib.h>
Line 729 ⟶ 931:
return 0;
}</
Here is a more concise variation which exits (with a non-zero return code) if it encounters a buffer overflow:
<
#include <stdlib.h>
#include <string.h>
Line 765 ⟶ 967:
printf("%s", buf);
exit(0);
}</
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <iostream>
#include <string.h>
int main()
{
std::string longLine, longestLines, newLine;
while (std::cin >> newLine)
{
auto isNewLineShorter = longLine.c_str();
auto isLongLineShorter = newLine.c_str();
while (*isNewLineShorter && *isLongLineShorter)
{
// This determines which string is longer without using a built
// in string length function. The loop will stop at the 0 at the
// end of the shortest string.
isNewLineShorter = &isNewLineShorter[1];
isLongLineShorter = &isLongLineShorter[1];
}
if(*isNewLineShorter) continue; // other lines were longer, do nothing
if(*isLongLineShorter)
{
// the new string is the longest so far
longLine = newLine;
longestLines = newLine;
}
else
{
// the new string is the same lenth as the previous longest
longestLines+=newLine;
}
longestLines+="\n"; // append a new line between the strings
}
std::cout << "\nLongest string:\n" << longestLines;
}</syntaxhighlight>
{{out}}
<pre>
a
bb
ccc
ddd
ee
f
ggg
Longest string:
ccc
ddd
ggg
</pre>
=={{header|Clojure}}==
{{trans|Python}}
<
(:gen-class))
Line 799 ⟶ 1,055:
(println "Input text:")
(println "Output:\n" (process))
</syntaxhighlight>
{{out}}
<pre>
Line 818 ⟶ 1,074:
=={{header|D}}==
{{trans|Python}}
<
/// Return a.length - b.length if positive, 0 otherwise.
Line 836 ⟶ 1,092:
writeln(lines);
}</
{{out}}
<pre>ccc
ddd
ggg</pre>
=={{header|FreeBASIC}}==
{{trans|PureBasic}}
<syntaxhighlight lang="freebasic">
Dim As String test, test1, test2
Data "a", "bb", "ccc", "ddd", "ee", "f", "ggg", "~" ' la tilde es solo para mantener el código compacto
Do
Read test
If test = "~" Then Exit Do : End If
If Len(test) > Len(test1) Then
test1 = test
test2 = test1 & Chr(10)
Elseif Len(test) = Len(test1) Then
test2 += test & Chr(10)
End If
Loop
Print(test2)
Sleep
</syntaxhighlight>
{{out}}
<pre>
ccc
ddd
ggg
</pre>
=={{header|FutureBasic}}==
'''Option 1 (old school)'''
<syntaxhighlight lang="futurebasic">
local fn FindLongest( test as CFArrayRef ) as CFStringRef
'~'1
CFStringRef s, t1 = @"", t2 = @""
for s in test
if ( len(s) > len(t1) )
t1 = s
t2 = fn StringWithFormat( @"%@\n", s )
else
if ( len(s) == len(t1) )
t2 = fn StringWithFormat( @"%@%@\n", t2, s )
end if
end if
next
end fn = t2
print fn FindLongest( @[@"a", @"bb", @"ccc", @"ddd", @"ee", @"f", @"ggg"] )
HandleEvents
</syntaxhighlight>
'''Option 2 (modern)'''
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
_longestStringsToDisplay = 3
local fn LongestStrings( string as CFStringRef )
CFArrayRef array = fn StringComponentsSeparatedByString( string, @" " )
SortDescriptorRef sortAscending = fn SortDescriptorWithKey( @"length", YES )
array = fn ArraySortedArrayUsingDescriptors( array, @[sortAscending] )
array = fn ArraySubarrayWithRange( array, fn CFRangeMake( len(array)-_longestStringsToDisplay, _longestStringsToDisplay ) )
NSLog( @"%@\n%@\n%@", array[0], array[1], array[2] )
end fn
fn LongestStrings( @"a bb ccc ddd ee f ggg" )
HandleEvents
</syntaxhighlight>
'''Output for either:'''
<pre>
ccc
ddd
ggg
</pre>
=={{header|Go}}==
<
import (
Line 886 ⟶ 1,220:
}
printLongest("")
}</
Description: It's basically the recursion+exceptions solution used by others, but staying close to the restrictions.
Line 906 ⟶ 1,240:
</pre>
The above expressions avoid arithmetic, but not all comparisons, because error values are typically tested and branched on. Eliminating all comparisons leaves no boolean values in the program and no way to use if statements, which in Go require a boolean condition. Conditional flow control is implemented with the following device:
<
// 1. statements executed in either case
// 2. func below is a closure that captures free variables
Line 922 ⟶ 1,256:
// 4a. conditional code. executed only if no panic happens
return // 7. function return happens in either case
}()</
A complication of course is that sometimes you want to conditionally execute code if the expression panics. Without a boolean value to invert, this case requires introducing an extra layer of func..defer..recover with a different expression contrived that will panic with the opposite effect.
=={{header|Groovy}}==
Solution: recursive
<
def aa = a, bb = b
while (bb && aa) {
Line 946 ⟶ 1,280:
}
return finalLongest
}</
Test:
<
bb
ccc
Line 957 ⟶ 1,291:
ggg'''))
longestStrings(source)</
Output:
Line 963 ⟶ 1,297:
ddd
ccc</pre>
=={{header|Haskell}}==
Even though lists of strings were disallowed in the rules, I have used them instead of a file handle, mainly to keep my functions pure, and to avoid the hassle of using the IO monad for something more trivial without it.
Another use of lists in the code is for Strings, which are lists of Chars in Haskell by default, which made it easy to compare them by length.
No operators were used except for string/list concatenation.
<syntaxhighlight lang="haskell">
module Main where
import System.Environment
cmp :: String -> String -> Ordering
cmp [] [] = EQ
cmp [] (_:_) = LT
cmp (_:_) [] = GT
cmp (_:xs) (_:ys) = cmp xs ys
longest :: String -> String
longest = longest' "" "" . lines
where
longest' acc l [] = acc
longest' [] l (x:xs) = longest' x x xs
longest' acc l (x:xs) = case cmp l x of
LT -> longest' x x xs
EQ -> longest' (acc ++ '\n':x) l xs
GT -> longest' acc l xs
main :: IO ()
main = do
(file:_) <- getArgs
contents <- readFile file
putStrLn $ longest contents
</syntaxhighlight>
=={{header|Icon}} and {{header|Unicon}}==
=== String Scanning / Pattern Matching Solution ===
<
local b # the current buffer (string)
local l # the last string
Line 979 ⟶ 1,349:
write(\L)
end</
Sample Output:<pre>ccc
Line 987 ⟶ 1,357:
=== Recursive Solution ===
Here is a recursive solution using only single character substring-ing (no string scanning/pattern matching).
<
longest(".") # needs a single character seed to throw away
end
Line 998 ⟶ 1,368:
# Line must be at least as long as Longest
return Longest # feed back longest for length
end</
Sample Output:<pre>ggg
Line 1,006 ⟶ 1,376:
=={{header|J}}==
<
compare =. ($:&}.)`((0 1,:_1 0) {~ <@,&isempty)@.(+.&isempty) NB. *@-&#
add =. ,`(,:@[)`] @. (compare {:)
Line 1,012 ⟶ 1,382:
ccc
ddd
ggg</
Description:
Line 1,026 ⟶ 1,396:
=={{header|Java}}==
Translation of Python via D
<
import java.util.Scanner;
Line 1,053 ⟶ 1,423:
return false;
}
}</
<pre>ccc
Line 1,062 ⟶ 1,432:
{{works with|Julia|0.6}}
<
try
b[endof(a)]
catch
return true
end
return false
Line 1,079 ⟶ 1,451:
end
end
println
end
printlongest(str::String) = printlongest(IOBuffer(str))
{{out}}
Line 1,089 ⟶ 1,461:
ddd
ggg</pre>
=={{header|Kotlin}}==
{{trans|Java}}
<
import java.io.File
Line 1,125 ⟶ 1,497:
// alternatively (but cheating as library functions will use comparisons and lists under the hood)
println(File("lines.txt").readLines().groupBy { it.length }.maxBy { it.key }!!.value.joinToString("\n"))
}</
{{out}}
Line 1,137 ⟶ 1,509:
ggg
</pre>
=={{header|Lambdatalk}}==
<syntaxhighlight lang="scheme">
{def longest_string
{def longest_string.r
{lambda {:max :s}
{if {S.empty? {S.rest :s}}
then
else {if {= {W.length {S.first :s}} :max} then {br}{S.first :s} else}
{longest_string.r :max {S.rest :s}}}}}
{lambda {:s}
{longest_string.r {max {S.map W.length :s}} :s #}}}
-> longest_string
{def words a bb ccc ddd ee f ggg} // it's a sentence, not a list
-> words
{longest_string {words}}
->
ccc
ddd
ggg
</syntaxhighlight>
=={{header|Lua}}==
<
while true do
s1 = s1:sub(1, -2)
Line 1,165 ⟶ 1,560:
end
print(output)</
This solution is ispired by the Python one, but since in Lua even an empty string has a boolean true value, it had to be slightly altered. Testing whether a string is empty is done by searching for the Lua string ''pattern'' <code>'^$'</code>. If it is found, i.e. the examined string is empty, <code>string.find</code> returns the position of the match, or <code>nil</code> if it didn't match. Since in Lua any number is <code>true</code>, we just test for the boolean value of the result.
Note that the <code>longer</code> function returns <code>true</code> even if both strings have the same length, so the return value can either be <code>true</code> or <code>false</code> and we can avoid using a comparison or equality operator in interpreting this return value.
Line 1,173 ⟶ 1,568:
The <code>longer</code> function also avoids using the length operator (<code>#</code>), because in the comments on the restrictions of this task it is stated that ''"Representing the length of any string as a number should also be avoided."''. Otherwise it could have been written shorter and faster like this:
<
if s1:sub(#s2):find('^$') then
return false
Line 1,180 ⟶ 1,575:
end
end
</syntaxhighlight>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
StringReplace[#,
x : "\n" | StartOfString ~~ a : Except["\n"] ... ~~ "\n" ~~
Line 1,195 ⟶ 1,590:
ee
f
ggg"]</
{{Out}}
<pre>ccc
Line 1,203 ⟶ 1,598:
=={{header|MATLAB}} / {{header|Octave}}==
<
fid = fopen(file);
maxlen = 0; L = {};
Line 1,218 ⟶ 1,613:
disp(L);
end;
</syntaxhighlight>
Output:
Line 1,226 ⟶ 1,621:
[1,3] = ggg
} </pre>
=={{header|MiniScript}}==
{{trans|Python}}
<syntaxhighlight lang="miniscript">
string.isLonger = function(s)
return self.hasIndex(s.len)
end function
longest = ""
lines = ""
current = input
while current
if current.isLonger(longest) then
lines = current
longest = current
else if not longest.isLonger(current) then
lines += current
end if
current = input
end while
for i in range(0, lines.len, longest.len)
print lines[i:i + longest.len]
end for
</syntaxhighlight>
{{out}}
<pre>
a
bb
ccc
dd
eee
f
ggg
hh
ccc
eee
ggg
</pre>
=={{header|Nanoquery}}==
{{trans|Python}}
<syntaxhighlight lang="nanoquery">import Nanoquery.IO
def longer(a, b)
try
b[len(a)-1]
return false
catch
return true
end
end
print "enter filename: "
$f = new(File, input())
longest = ""
lines = ""
for x in $f.read()
if longer(x, longest)
lines = x
longest = x
else if !longer(longest, x)
lines += "\n" + x
end
end
println lines</syntaxhighlight>
{{out}}
<pre>ccc
ddd
ggg</pre>
=={{header|Nim}}==
To compare the length of strings, we could have use the standard function "cmp" but it would have been cheating. We could also have used the trick based on exception catching, but, in Nim, IndexError is considered as a defect and, even if in current version (1.4) IndexError is actually catchable, it would probably not still be the case in future versions.
So, we have used another way to compare the length of strings, clearly not efficient, but efficiency is not a goal here.
<syntaxhighlight lang="nim">import strutils
const
# Define int constants instead of an enum to use only ints and strings.
Shorter = -1
SameLength = 0
Longer = 1
type LengthComparison = range[Shorter..Longer]
func cmpLength(a, b: string): LengthComparison =
let a = repeat(' ', a.len)
let b = repeat(' ', b.len)
result = if a in b: (if b in a: SameLength else: Shorter) else: Longer
var longest = ""
var result = ""
for line in "longest_string_challenge.txt".lines:
case cmpLength(line, longest)
of Shorter:
discard
of SameLength:
result.add '\n' & line
of Longer:
longest = line
result = line
echo result</syntaxhighlight>
{{out}}
<pre>ccc
ddd
ggg</pre>
=={{header|OCaml}}==
Line 1,231 ⟶ 1,740:
Without the restrictions, the standard way to solve the task would be to iterate the lines, compare their length, and accumulate the longest lines in a list. Here we bypass the restriction of not using comparison operators (in the function <code>cmp</code>) by taking advantage that characters of strings are indexed from 0 to [length - 1] and trying to access to a character which index is the length of the other string (if it is beyond the end of the string an exception is raised). The other restriction of not using lists is easily bypassed by concatenating the results instead of accumulating it in a list.
<
try Some (input_line ic)
with End_of_file -> None
Line 1,254 ⟶ 1,763:
print_string acc
in
loop "" ""</
=={{header|Pascal}}==
{{works with|Free_Pascal}}
In this version, inc() is used instead of additions. It still has a comparison.
<
var
Line 1,295 ⟶ 1,804:
writeln (lines[position]);
end;
end.</
Output:
<pre>% ./LongestStringChallenge_1
Line 1,313 ⟶ 1,822:
{{libheader|SysUtils}}
This version uses range check exceptions for the comparisons of string lengths. The range checks are compiler specific. With FreePascal its requires the use of the type ANSIstring instead of "classic" type string.
<
{$mode ObjFPC}
Line 1,355 ⟶ 1,864:
writeln (lines[position]);
end;
end.</
Output:
<pre>% ./LongestStringChallenge_2
Line 1,372 ⟶ 1,881:
=={{header|Perl}}==
<
END{ print $all }
substr($_, length($l)) and $all = $l = $_
or substr($l, length) or $all .= $_;</
=={{header|
A recursive/substring based approach, I can't see any explicit maths/comparisons anyway.<br>
Since file i/o is not permitted in a browser, for running under pwa/p2js this fakes it using the first 40 words from unix_dict(), the longest word/line being (appropriately enough) "abbreviate".
Technically of course that uses a list, but not really in a way that goes against the spirit of the task.
I should probably note that while desktop/Phix copes fine with the full list of 25107 words, that would run out of memory/exceed the call stack under pwa/p2js using this particular (highly-callstack-abusive) method.<br>
The original file i/o has been left in as comments, in case you want to test that when running on desktop/Phix.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #000080;font-style:italic;">--integer fn = open(command_line()[2],"r") -- (reading the source file)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">unix_dict</span><span style="color: #0000FF;">()[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">40</span><span style="color: #0000FF;">]&-</span><span style="color: #000000;">1</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">allx</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">line</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">line</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'x'</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">line</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">longest</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">mask</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- object line = gets(fn)</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">line</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">];</span> <span style="color: #000000;">fn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">fn</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$];</span>
<span style="color: #008080;">if</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">mask</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">newmask</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">allx</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mask</span><span style="color: #0000FF;">,</span><span style="color: #000000;">newmask</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">longest</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mask</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">mask</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">longest</span><span style="color: #0000FF;">(</span><span style="color: #000000;">newmask</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">match</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mask</span><span style="color: #0000FF;">,</span><span style="color: #000000;">newmask</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- puts(1,line)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">mask</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">longest</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">--close(fn)</span>
<!--</syntaxhighlight>-->
Of course it is just a thinly disguised version of:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">longest</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">object</span> <span style="color: #000000;">line</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">gets</span><span style="color: #0000FF;">(</span><span style="color: #000000;">fn</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">line</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">l</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">></span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">longest</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">longest</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">line</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">l</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">longest</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
=={{header|PHP}}==
<syntaxhighlight lang="php"><?php
echo 'Enter strings (empty string to finish) :', PHP_EOL;
$output = $previous = readline();
while ($current = readline()) {
$p = $previous;
$c = $current;
// Remove first character from strings until one of them is empty
while ($p and $c) {
$p = substr($p, 1);
$c = substr($c, 1);
}
// If $p and $c are empty : strings are of equal length
if (!$p and !$c) {
$output .= PHP_EOL . $current;
}
// If $c is not empty, $current is longer
if ($c) {
$output = $previous = $current;
}
}
echo 'Longest string(s) = ', PHP_EOL, $output, PHP_EOL;</syntaxhighlight>
{{out}}
<pre>Enter strings (empty string to finish) :
a
bb
ccc
ddd
ee
f
ggg
Longest string(s) =
ccc
ddd
ggg</
=={{header|PicoLisp}}==
Not sure if this meets the spirit. I would implement it the same way if there were no "restrictions":
<
(maxi '((L) (length (car L)))
(by length group
(in NIL
(make (until (eof) (link (line)))) ) ) ) )</
Another solution avoids 'group', and builds an associative buffer of lines instead:
<
(in NIL
(until (eof)
Line 1,454 ⟶ 1,994:
(conc @ (cons Line))
(push 'Buf (cons Len (cons Line))) ) ) ) )
(mapc prinl (cdr (maxi car Buf))) )</
=={{header|Pike}}==
Line 1,468 ⟶ 2,008:
<code>return -1;</code> starts the backend, which allows pike to execute the remaining call_outs and exit.
<
{
string longest = "";
Line 1,487 ⟶ 2,027:
call_out(exit, 0.01, 0);
return -1;
}</
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
read: procedure options (main); /* 18 January 2012. */
declare line character (100) varying controlled;
Line 1,530 ⟶ 2,070:
end read;
</syntaxhighlight>
output (the above file plus the following 3 lines):
<pre>
Line 1,540 ⟶ 2,080:
=={{header|PowerShell}}==
{{works with|PowerShell|2}}
<syntaxhighlight lang="powershell">
# Get-Content strips out any type of line break and creates an array of strings
# We'll join them back together and put a specific type of line break back in
Line 1,581 ⟶ 2,121:
# Output longest strings
$LongestStrings.Split( "`n" )
</syntaxhighlight>
===PowerShell Alternate Version===
The list restrictions should not apply here because this is essentially one line of code using only the input and no variables.
<syntaxhighlight lang="powershell">
@'
a
Line 1,598 ⟶ 2,138:
Sort-Object -Property Name -Descending |
Select-Object -Property Count, @{Name="Length"; Expression={[int]$_.Name}}, Group -First 1
</syntaxhighlight>
{{Out}}
<pre>
Line 1,607 ⟶ 2,147:
=={{header|PureBasic}}==
<
Procedure.i ConsoleWrite(t.s) ; compile using /CONSOLE option
Line 1,654 ⟶ 2,194:
StdOut(a$)
</syntaxhighlight>
;Output:
Line 1,675 ⟶ 2,215:
=={{header|Python}}==
<
# This returns True if the second string has a value on the
Line 1,696 ⟶ 2,236:
lines += x
print(lines, end='')</
;Sample runs:
Line 1,718 ⟶ 2,258:
</pre>
=={{header|Quackery}}==
The quandary here is, is a dynamic array a list? If yes, then nothing is allowed, as the only composite structure in Quackery is the dynamic array ("nest" in Quackery jargon), including code, and Quackery is one of those languages where code is data, and data is code. If no, then everything is allowed and the exercise is trivial. So, in the spirit of the task we will differentiate between strings (in reality nests of numbers interpreted as ascii characters) and other nests, and use only strings where the context is clearly data.
We note that implicit arithmetic is allowable, so the use of <code>witheach</code> to iterate over a string is permitted.
'''Method'''
<code>comparison</code> compares the length of two strings on the top of second on stack, designated A and B here, without using comparisons.
From A we construct a string A' of the same length as A consisting entirely of 0s (i.e. the control code "nul"), which will later be taken to indicate that A is the longer string of the two. From B we construct a string B' of the same length consisting entirely of 1s (i.e. the control code "soh"), which will later be taken to indicate that A is the longer string of the two. 2 ("stx" will indicate that the two strings are the same length.)
We reduce the length of A' by the number of characters in B' by repeatedly removing the last character from A' using <code>-1 split drop</code>, once for each character in B'. If B' is longer than A' this will leave an empty string. (The way <code>split</code> operates means that attempting to separate the last character from an empty string will return two empty strings, and not raise an error.
Then we do the same but reducing the length of B' by the length of A' (the original A', before its length was reduced.)
At this point, either A' or B' will be an empty string if one was longer than the other, or both will be empty strings if they were the same length initially. We concatenate them, then concatenate a 2, and return the first character in the resultant string, i.e. 0, 1, or 2.
<code>task</code> prompts the user to input strings, using the result of <code>comparison</code> to determine when the user ends inputting, by indexing into an embedded lookup table and performing the specified action. It also constructs a result string consisting of the longest input strings separated by carriage returns in the same manner. Finally it prints the result string.
<syntaxhighlight lang="Quackery"> [ 0 ] is alonger
[ 1 ] is blonger
[ 2 ] is a&bsame
[ [] swap witheach
[ drop blonger join ]
[] rot witheach
[ drop alonger join ]
over dip dup
witheach [ drop -1 split drop ]
unrot
witheach [ drop -1 split drop ]
join
a&bsame join
0 peek ] is comparison ( $ $ --> c )
[ say "Enter an empty string to end."
cr cr
$ "" $ ""
[ $ "Enter a string: " input
dup $ "" comparison
[ table
true true false ] do while
carriage join
2dup comparison
[ table
[ drop ]
[ dip [ 2drop $ "" ] ]
[ dip join ] ]
do again ]
cr say "Result:" cr
drop join echo$ ] is task ( --> )</syntaxhighlight>
{{out}}
Aa a dialogue in the Quackery shell (REPL):
<pre>/O> task
...
Enter an empty string to end.
Enter a string: a
Enter a string: bb
Enter a string: ccc
Enter a string: ddd
Enter a string: ee
Enter a string: f
Enter a string: ggg
Enter a string:
Result:
ccc
ddd
ggg
</pre>
=={{header|Racket}}==
This is an attempt to follow the problem restrictions: use just one list of the complete output (so it's not used as a container of strings), and the work is done by manipulating this list vs the input instead of direct comparisons.
<syntaxhighlight lang="racket">
#lang racket
Line 1,736 ⟶ 2,352:
[(newline? o) (loop O C i:rI rO i:rI)]
[else (loop O (cdr C) i:rI rO i:rC)])))
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" line>my $l = ''; # Sample longest string seen.
my $a = ''; # Accumulator to save longest strings.
while get() -> $s {
my $n = "$s\n";
if $n.substr($l.chars) { # Is new string longer?
$a = $l = $n; # Reset accumulator.
}
elsif !$l.substr($n.chars) { # Same length?
$a ~= $n; # Accumulate it.
}
}
print $a;</syntaxhighlight>
Given the example input, returns:
<pre>ccc
ddd
ggg</pre>
=={{header|REXX}}==
In the REXX language, ''everything'' is a string (characters).
===read file until not ready===
This REXX version adheres to spirit (and letter) of all the restrictions for this task:
::* no comparators are used, including those within:
::::* '''if''' (statements)
::::*
::* no output is produced when the file is empty (or contains all null strings),
::* no arrays or lists are used,
::* no additions or subtractions are used, and
::* no variables are used to hold the length of (any) record.
<syntaxhighlight lang="rexx">/*REXX program reads a file and displays the longest [widest] record(s) [line(s)]. */
signal on notReady /*when E-O-F is reached, jump/branch. */
parse arg fid . /*obtain optional argument from the CL.*/
do #=1 to length(fid); iFID=fid /*Specified? Then use what's given. */
end /*#*/
!=
do forever; _=linein(iFID); ?=_ /*read a line from the input file. */
t=0 /*don't do the initialization next time*/
do #=t for t; !=?; ?=; $=. || _; end /*just do 1st time.*/
do #=length(!' ') to length(?) for 1; $=; end /*found widest rec.*/
do #=length(!) to length(?) for 1; $=$'a0d'x || _; end /*append it to $. */
/* [↑] variable # isn't really used.*/
!=left(., max( length(!), length(?) ) ) /*!: is the max length record, so far.*/
end /*forever*/
/* [↓] comes here when file gets E─O─F*/
notReady: do j=length(!) to length(!) for length(!) /*handle the case of no input*/
say substr($, 2) /*display (all) the longest records. */
end /*j*/ /*stick a fork in it, we're all done. */</syntaxhighlight>
{{out|input|text=file '''LONGEST.TXT''':}}
<pre>
a
bb
ccc
ddd
ee
f
ggg
</pre>
{{out|output|text= when using the default input:}}
<pre>
ccc
ddd
ggg
</pre>
===Dual code (works on TSO and PC)===
<
* 27.10.2010 Walter Pachl
**********************************************************************/
Line 1,865 ⟶ 2,469:
End
Else
Say 'No lines in input file or file does not exist' </
<pre>
Maximum line length=5
Line 1,874 ⟶ 2,478:
=={{header|Ring}}==
<
# Project : Longest string challenge
load "stdlib.ring"
Line 1,901 ⟶ 2,502:
test2 = sort(test2)
see test2 + nl
</syntaxhighlight>
Output:
<pre>
Line 1,907 ⟶ 2,508:
ddd
ggg
</pre>
=={{header|RPL}}==
This program complies with the list of restrictions:
The main hack is based on the fact that the <code>SUB</code> function, which extracts one or more characters from a string, returns the null character if its arguments exceed the size of the string. It is then easy to compare lengths without any comparison operator.
A second hack is to use a string to count the number of compliant strings already in the stack: the <code>+</code> and <code>STO+</code> commands present in the code are not arithmetic operations, but string operations aiming at appending characters.
The user stack is both the standard input and output.
{{works with|HP|49}}
≪ "X" → count
≪ 1 CF <span style="color:grey">@ flag 1 set means there are at least 2 strings in the stack</span>
'''WHILE''' "String?" "" INPUT DUP SIZE '''REPEAT'''
'''IF''' 1 FS? '''THEN'''
'''CASE'''
DUP2 SWAP SIZE DUP SUB NUM NOT '''THEN'''
DROP '''END'''
DUP2 SIZE DUP SUB NUM NOT '''THEN'''
count "X" + SIZE ROLLD count SIZE DROPN "X" 'count' STO '''END'''
"X" 'count' STO+
'''END'''
'''ELSE''' 1 SF '''END'''
'''END''' DROP
≫ ≫ '<span style="color:blue">TASK</span>' STO
<span style="color:blue">TASK</span>
"a" "bb" "ccc" "ddd" "ee" "f" "ggg" ""
{{out}}
<pre>
3: "ccc"
2: "ddd"
1: "ggg"
</pre>
=={{header|Ruby}}==
<
BEGIN {
v = [ ]
Line 1,926 ⟶ 2,559:
END {
v.each { |s| puts s }
}</
Then ''ruby -n longest.rb < file.txt''
<
puts h.max.last unless h.empty?</
This uses a hash with arrays as values - but not explicit.
=={{header|Run BASIC}}==
Uses in memory database
<
#mem execute("CREATE TABLE data(str)") ' And fields to hold the string data
Line 1,951 ⟶ 2,584:
str$ = #row str$()
print leng;" ";str$ ' print the data
WEND</
Using a simple sort method
<
while word$(strings$,numWords + 1," ") <> "" ' Count the words
Line 1,980 ⟶ 2,613:
for i = 1 to numWords
print len(string$(i));" ";string$(i) ' print out the words in length descending sequence
next i</
<pre>3 ccc
3 ddd
Line 1,988 ⟶ 2,621:
1 a
1 f</pre>
=={{header|Rust}}==
<syntaxhighlight lang="rust">use std::cmp::Ordering;
use std::io::BufRead;
/// Compares the length of two strings by iterating over their characters
/// together until either string has run out.
fn compare(a: &str, b: &str) -> Ordering {
let mut a = a.chars();
let mut b = b.chars();
loop {
match (a.next(), b.next()) {
(None, None) => return Ordering::Equal,
(Some(_), None) => return Ordering::Greater,
(None, Some(_)) => return Ordering::Less,
(Some(_), Some(_)) => {}
}
}
}
/// Returns the longest lines of the input, separated by newlines.
fn longest<I: IntoIterator<Item = String>>(input: I) -> String {
let mut longest = String::new();
let mut output = String::new();
for line in input {
match compare(&line, &longest) {
// A longer string replaces the output and longest.
Ordering::Greater => {
output.clear();
output.push_str(&line);
longest = line;
}
// A string of the same length is appended to the output.
Ordering::Equal => {
output.push('\n');
output.push_str(&line);
}
// A shorter string is ignored.
Ordering::Less => {}
}
}
output
}
fn main() {
let stdin = std::io::stdin();
let lines = stdin.lock().lines().map(|l| l.expect("Failed to read."));
println!("{}", longest(lines))
}</syntaxhighlight>
=={{header|Scala}}==
<
println(longest mkString "\n")</
=={{header|Sidef}}==
<
var a = ''; # Accumulator to save longest strings.
Line 2,001 ⟶ 2,687:
}
print a;</
=={{header|Tcl}}==
Uses only string comparisons for equality and glob-style matching
<
set longest z
Line 2,021 ⟶ 2,707:
}
}
puts -nonewline $output</
Test:
Line 2,047 ⟶ 2,733:
The solution uses the Mid function to compare string lengths.
<syntaxhighlight lang="vb">
'Read the input file. This assumes that the file is in the same
'directory as the script.
Line 2,073 ⟶ 2,759:
objfile.Close
Set objfso = Nothing
</syntaxhighlight>
{{Out}}
Line 2,080 ⟶ 2,766:
ddd
ggg
</pre>
=={{header|Wren}}==
{{trans|D}}
<syntaxhighlight lang="wren">import "io" for Stdin
// Return a.length - b.length if positive, 0 otherwise.
var longer = Fn.new { |a, b|
while (!a.isEmpty && !b.isEmpty) {
a = a[1..-1]
b = b[1..-1]
}
return a.count
}
var longest = ""
var lines = ""
var line
while ((line = Stdin.readLine()) != "") {
if (longer.call(line, longest) != 0) {
lines = longest = line
} else if (longer.call(longest, line) == 0) {
lines = "%(lines)\n%(line)"
}
}
System.print(lines)</syntaxhighlight>
{{out}}
<pre>
ccc
ddd
ggg
</pre>
=={{header|XQuery}}==
Port of XSLT solution, this time using a string sequence.
<syntaxhighlight lang="xquery">
let $seq as xs:string+ := ("a","bb","ccc","ddd","ee","f","ggg")
for $l in max(
for $s in $seq
return string-length($s)
)
return $seq[string-length(.) eq $l]
</syntaxhighlight>
Result:
<pre>
("ccc","ddd","ggg")
</pre>
=={{header|XSLT 2.0}}==
This XSLT 2.0 style-sheet...
<syntaxhighlight lang="text"><xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" encoding="UTF-8" omit-xml-declaration="yes" />
<xsl:template match="/*">
Line 2,090 ⟶ 2,826:
return s[string-length(.) eq $l]" /></t>
</xsl:template>
</xsl:stylesheet></
...when applied to this input...
<syntaxhighlight lang="text"><t>
<s>a</s>
<s>bb</s>
Line 2,101 ⟶ 2,837:
<s>f</s>
<s>ggg</s>
</t></
...yields...
<syntaxhighlight lang="text"><t>
<s>ccc</s>
<s>ddd</s>
<s>ggg</s>
</t></
=={{header|Yabasic}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="yabasic">
data "a", "bb", "ccc", "ddd", "ee", "f", "ggg", "~"
do
read test$
if test$ = "~" then break : fi
if len(test$) > len(test1$) then
test1$ = test$
test2$ = test1$ + chr$(10)
elsif len(test$) = len(test1$) then
test2$ = test2$ + test$ + chr$(10)
end if
loop
print(test2$)
end
</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>
=={{header|zkl}}==
Line 2,114 ⟶ 2,876:
To decide which of two strings is longer, a character is removed from each until one is empty. If one still has text, it is longer.
<
while(a and b){a=a.del(0); b=b.del(0);}
if (not a and not b) return(0); // a & b same length
Line 2,129 ⟶ 2,891:
} //switch
}
println(text);</
{{out}}
<pre>
|