Longest string challenge: Difference between revisions
m
syntax highlighting fixup automation
(C++ entry) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 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 221:
end if;
end;
</syntaxhighlight>
The output, given the above example input, is:
Line 247:
So this is the first solution.
<
with Ada.Text_IO, Ada.Characters.Latin_1;
Line 298:
end if;
end loop;
end Longest_String_Challenge;</
Output, when run with its own source code as the input:
Line 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 360:
end if;
end loop;
end Longest_String_Challenge;</
The output, when given its own source code as the input:
Line 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 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 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 517:
# find the logest lines from standard inoout #
VOID( print longest lines( stand in, read line( stand in ) ) )
</syntaxhighlight>
=={{header|AutoHotkey}}==
Line 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 546:
buffer := A_LoopField "`n", LongestLen := StrLen(A_LoopField)
}
MsgBox % buffer</
=={{header|AWK}}==
<
BEGIN {
maxlen = 0;
Line 567:
END {
for (k=1; k <= lenList; k++) print List[k];
}</
Output:
Line 579:
{{trans|FreeBASIC}}
{{works with|QBasic}}
<syntaxhighlight lang="qbasic">
DO
READ test$
Line 594:
DATA "a", "bb", "ccc", "ddd", "ee", "f", "ggg", "~" : ' la tilde es solo para mantener el código compacto
</syntaxhighlight>
{{out}}
<pre>
Line 603:
==={{header|True BASIC}}===
{{trans|FreeBASIC}}
<
DATA "a", "bb", "ccc", "ddd", "ee", "f", "ggg", "~" ! la tilde es solo para mantener el código compacto
Line 619:
PRINT(test2$)
END
</syntaxhighlight>
{{out}}
<pre>
Line 628:
=={{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 657:
DEF FNinc(i%) : REM Returns i%+1
FOR i% = i% TO i% : NEXT
= i%</
Output:
<pre>
Line 666:
=={{header|C}}==
<
#include <string.h>
Line 693:
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 779:
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 815:
printf("%s", buf);
exit(0);
}</
=={{header|C++}}==
<
#include <string.h>
Line 854:
std::cout << "\nLongest string:\n" << longestLines;
}</
{{out}}
<pre>
Line 873:
=={{header|Clojure}}==
{{trans|Python}}
<
(:gen-class))
Line 903:
(println "Input text:")
(println "Output:\n" (process))
</syntaxhighlight>
{{out}}
<pre>
Line 922:
=={{header|D}}==
{{trans|Python}}
<
/// Return a.length - b.length if positive, 0 otherwise.
Line 940:
writeln(lines);
}</
{{out}}
<pre>ccc
Line 949:
=={{header|FreeBASIC}}==
{{trans|PureBasic}}
<
Dim As String test, test1, test2
Data "a", "bb", "ccc", "ddd", "ee", "f", "ggg", "~" ' la tilde es solo para mantener el código compacto
Line 966:
Print(test2)
Sleep
</syntaxhighlight>
{{out}}
<pre>
Line 976:
=={{header|Go}}==
<
import (
Line 1,019:
}
printLongest("")
}</
Description: It's basically the recursion+exceptions solution used by others, but staying close to the restrictions.
Line 1,039:
</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 1,055:
// 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 1,079:
}
return finalLongest
}</
Test:
<
bb
ccc
Line 1,090:
ggg'''))
longestStrings(source)</
Output:
Line 1,105:
No operators were used except for string/list concatenation.
<syntaxhighlight lang="haskell">
module Main where
Line 1,131:
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 1,148:
write(\L)
end</
Sample Output:<pre>ccc
Line 1,156:
=== 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 1,167:
# Line must be at least as long as Longest
return Longest # feed back longest for length
end</
Sample Output:<pre>ggg
Line 1,175:
=={{header|J}}==
<
compare =. ($:&}.)`((0 1,:_1 0) {~ <@,&isempty)@.(+.&isempty) NB. *@-&#
add =. ,`(,:@[)`] @. (compare {:)
Line 1,181:
ccc
ddd
ggg</
Description:
Line 1,195:
=={{header|Java}}==
Translation of Python via D
<
import java.util.Scanner;
Line 1,222:
return false;
}
}</
<pre>ccc
Line 1,231:
{{works with|Julia|0.6}}
<
try
b[endof(a)]
Line 1,254:
printlongest(str::String) = printlongest(IOBuffer(str))
printlongest("a\nbb\nccc\nddd\nee\nf\nggg")</
{{out}}
Line 1,263:
=={{header|Kotlin}}==
{{trans|Java}}
<
import java.io.File
Line 1,296:
// 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,310:
=={{header|Lambdatalk}}==
<
{def longest_string
{def longest_string.r
Line 1,330:
ddd
ggg
</syntaxhighlight>
=={{header|Lua}}==
<
while true do
s1 = s1:sub(1, -2)
Line 1,359:
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> if it didn't match. Since in Lua any number is <code>true</code>, we just test for the boolean value of the result.
Line 1,367:
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,374:
end
end
</syntaxhighlight>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
StringReplace[#,
x : "\n" | StartOfString ~~ a : Except["\n"] ... ~~ "\n" ~~
Line 1,389:
ee
f
ggg"]</
{{Out}}
<pre>ccc
Line 1,397:
=={{header|MATLAB}} / {{header|Octave}}==
<
fid = fopen(file);
maxlen = 0; L = {};
Line 1,412:
disp(L);
end;
</syntaxhighlight>
Output:
Line 1,423:
=={{header|Nanoquery}}==
{{trans|Python}}
<
def longer(a, b)
Line 1,448:
end
println lines</
{{out}}
<pre>ccc
Line 1,459:
So, we have used another way to compare the length of strings, clearly not efficient, but efficiency is not a goal here.
<
const
Line 1,487:
result = line
echo result</
{{out}}
Line 1,498:
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,521:
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,562:
writeln (lines[position]);
end;
end.</
Output:
<pre>% ./LongestStringChallenge_1
Line 1,580:
{{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,622:
writeln (lines[position]);
end;
end.</
Output:
<pre>% ./LongestStringChallenge_2
Line 1,639:
=={{header|Perl}}==
<
END{ print $all }
substr($_, length($l)) and $all = $l = $_
or substr($l, length) or $all .= $_;</
=={{header|Phix}}==
Line 1,651:
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.
<!--<
<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>
Line 1,678:
<span style="color: #000080;font-style:italic;">--close(fn)</span>
<!--</
Of course it is just a thinly disguised version of:
<!--<
<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>
Line 1,693:
<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>
<!--</
=={{header|PHP}}==
<
echo 'Enter strings (empty string to finish) :', PHP_EOL;
Line 1,720:
}
echo 'Longest string(s) = ', PHP_EOL, $output, PHP_EOL;</
{{out}}
Line 1,739:
=={{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,752:
(conc @ (cons Line))
(push 'Buf (cons Len (cons Line))) ) ) ) )
(mapc prinl (cdr (maxi car Buf))) )</
=={{header|Pike}}==
Line 1,766:
<code>return -1;</code> starts the backend, which allows pike to execute the remaining call_outs and exit.
<
{
string longest = "";
Line 1,785:
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,828:
end read;
</syntaxhighlight>
output (the above file plus the following 3 lines):
<pre>
Line 1,838:
=={{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,879:
# 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,896:
Sort-Object -Property Name -Descending |
Select-Object -Property Count, @{Name="Length"; Expression={[int]$_.Name}}, Group -First 1
</syntaxhighlight>
{{Out}}
<pre>
Line 1,905:
=={{header|PureBasic}}==
<
Procedure.i ConsoleWrite(t.s) ; compile using /CONSOLE option
Line 1,952:
StdOut(a$)
</syntaxhighlight>
;Output:
Line 1,973:
=={{header|Python}}==
<
# This returns True if the second string has a value on the
Line 1,994:
lines += x
print(lines, end='')</
;Sample runs:
Line 2,020:
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 2,034:
[(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"
my $a = ''; # Accumulator to save longest strings.
Line 2,051:
}
}
print $a;</
Given the example input, returns:
Line 2,071:
::* no additions or subtractions are used, and
::* no variables are used to hold the length of (any) record.
<
signal on notReady /*when E-O-F is reached, jump/branch. */
iFID= 'LONGEST.TXT' /*the default file identifier for input*/
Line 2,089:
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. */</
{{out|input|text=file '''LONGEST.TXT''':}}
<pre>
Line 2,108:
===Dual code (works on TSO and PC)===
<
* 27.10.2010 Walter Pachl
**********************************************************************/
Line 2,151:
End
Else
Say 'No lines in input file or file does not exist' </
<pre>
Maximum line length=5
Line 2,160:
=={{header|Ring}}==
<
# Project : Longest string challenge
Line 2,184:
test2 = sort(test2)
see test2 + nl
</syntaxhighlight>
Output:
<pre>
Line 2,193:
=={{header|Ruby}}==
<
BEGIN {
v = [ ]
Line 2,209:
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 2,234:
str$ = #row str$()
print leng;" ";str$ ' print the data
WEND</
Using a simple sort method
<
while word$(strings$,numWords + 1," ") <> "" ' Count the words
Line 2,263:
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 2,273:
=={{header|Rust}}==
<
use std::io::BufRead;
Line 2,322:
println!("{}", longest(lines))
}</
=={{header|Scala}}==
<
println(longest mkString "\n")</
=={{header|Sidef}}==
<
var a = ''; # Accumulator to save longest strings.
Line 2,337:
}
print a;</
=={{header|Tcl}}==
Uses only string comparisons for equality and glob-style matching
<
set longest z
Line 2,357:
}
}
puts -nonewline $output</
Test:
Line 2,383:
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,409:
objfile.Close
Set objfso = Nothing
</syntaxhighlight>
{{Out}}
Line 2,420:
=={{header|Wren}}==
{{trans|D}}
<
// Return a.length - b.length if positive, 0 otherwise.
Line 2,441:
}
}
System.print(lines)</
{{out}}
Line 2,454:
Port of XSLT solution, this time using a string sequence.
<
let $seq as xs:string+ := ("a","bb","ccc","ddd","ee","f","ggg")
for $l in max(
Line 2,461:
)
return $seq[string-length(.) eq $l]
</syntaxhighlight>
Result:
Line 2,470:
=={{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,476:
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,487:
<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}}
<
data "a", "bb", "ccc", "ddd", "ee", "f", "ggg", "~"
Line 2,515:
print(test2$)
end
</syntaxhighlight>
{{out}}
<pre>
Line 2,526:
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,541:
} //switch
}
println(text);</
{{out}}
<pre>
|