2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,64 +1,71 @@
|
|||
'''Background'''
|
||||
;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.
|
||||
|
||||
: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.
|
||||
The original programming challenge and some solutions can be found at [https://tapestry.tucson.az.us/twiki/bin/view/Main/LongestStringsPuzzle Unicon Programming TWiki / Longest Strings Puzzle]. (See notes on the talk page if you have trouble with the site).
|
||||
|
||||
:The original programming challenge and some solutions can be found at [https://tapestry.tucson.az.us/twiki/bin/view/Main/LongestStringsPuzzle Unicon Programming TWiki / Longest Strings Puzzle]. (See notes on the talk page if you have trouble with the site).
|
||||
|
||||
'''Basic problem statement:'''
|
||||
;Basic problem statement
|
||||
Write a program that reads lines from standard input and, upon end of file, writes the longest line to standard output.
|
||||
If there are ties for the longest line, the program writes out all the lines that tie.
|
||||
If there is no input, the program should produce no output.
|
||||
|
||||
:Write a program that reads lines from standard input and, upon end of file, writes the longest line to standard output.
|
||||
:If there are ties for the longest line, the program writes out all the lines that tie.
|
||||
:If there is no input, the program should produce no output.
|
||||
|
||||
'''Task'''
|
||||
;Task
|
||||
Implement a solution to the basic problem that adheres to the spirit of the restrictions (see below).
|
||||
|
||||
:Implement a solution to the basic problem that adheres to the spirit of the restrictions (see below).
|
||||
Describe how you circumvented or got around these 'restrictions' and met the 'spirit' of the challenge. Your supporting description may need to describe any challenges to interpreting the restrictions and how you made this interpretation. You should state any assumptions, warnings, or other relevant points. The central idea here is to make the task a bit more interesting by thinking outside of the box and perhaps by showing off the capabilities of your language in a creative way. Because there is potential for considerable variation between solutions, the description is key to helping others see what you've done.
|
||||
|
||||
:Describe how you circumvented or got around these 'restrictions' and met the 'spirit' of the challenge. Your supporting description may need to describe any challenges to interpreting the restrictions and how you made this interpretation. You should state any assumptions, warnings, or other relevant points. The central idea here is to make the task a bit more interesting by thinking outside of the box and perhaps by showing off the capabilities of your language in a creative way. Because there is potential for considerable variation between solutions, the description is key to helping others see what you've done.
|
||||
|
||||
:This task is likely to encourage a variety of different types of solutions. They should be substantially different approaches.
|
||||
This task is likely to encourage a variety of different types of solutions. They should be substantially different approaches.
|
||||
|
||||
Given the input:
|
||||
<pre>a
|
||||
<pre>
|
||||
a
|
||||
bb
|
||||
ccc
|
||||
ddd
|
||||
ee
|
||||
f
|
||||
ggg</pre>
|
||||
ggg
|
||||
</pre>
|
||||
|
||||
the output should be (possibly rearranged):
|
||||
<pre>ccc
|
||||
<pre>
|
||||
ccc
|
||||
ddd
|
||||
ggg</pre>
|
||||
ggg
|
||||
</pre>
|
||||
|
||||
'''Original list of restrictions:'''
|
||||
|
||||
:1. No comparison operators may be used.
|
||||
:2. No arithmetic operations, such as addition and subtraction, may be used.
|
||||
:3. The only datatypes you may use are integer and string. In particular, you may not use lists.
|
||||
;Original list of restrictions
|
||||
|
||||
An additional restriction became apparent in the discussion.
|
||||
:4. Do not re-read the input file. Avoid using files as a replacement for lists.
|
||||
# No comparison operators may be used.
|
||||
# No arithmetic operations, such as addition and subtraction, may be used.
|
||||
# The only datatypes you may use are integer and string. In particular, you may not use lists.
|
||||
# Do not re-read the input file. Avoid using files as a replacement for lists (this restriction became apparent in the discussion).
|
||||
|
||||
'''Intent of Restrictions'''
|
||||
|
||||
:Because of the variety of languages on Rosetta Code and the wide variety of concepts used in them, there needs to be a bit of clarification and guidance here to get to the spirit of the challenge and the intent of the restrictions.
|
||||
;Intent of restrictions:
|
||||
Because of the variety of languages on Rosetta Code and the wide variety of concepts used in them, there needs to be a bit of clarification and guidance here to get to the spirit of the challenge and the intent of the restrictions.
|
||||
|
||||
::The basic problem can be solved very conventionally, but that's boring and pedestrian. The original intent here wasn't to unduly frustrate people with interpreting the restrictions, it was to get people to think outside of their particular box and have a bit of fun doing it.
|
||||
The basic problem can be solved very conventionally, but that's boring and pedestrian. The original intent here wasn't to unduly frustrate people with interpreting the restrictions, it was to get people to think outside of their particular box and have a bit of fun doing it.
|
||||
|
||||
::The guiding principle here should be to be creative in demonstrating some of the capabilities of the programming language being used. If you need to bend the restrictions a bit, explain why and try to follow the intent. If you think you've implemented a 'cheat', call out the fragment yourself and ask readers if they can spot why. If you absolutely can't get around one of the restrictions, explain why in your description.
|
||||
The guiding principle here should be to be creative in demonstrating some of the capabilities of the programming language being used. If you need to bend the restrictions a bit, explain why and try to follow the intent. If you think you've implemented a 'cheat', call out the fragment yourself and ask readers if they can spot why. If you absolutely can't get around one of the restrictions, explain why in your description.
|
||||
|
||||
::Now having said that, the restrictions require some elaboration.
|
||||
Now having said that, the restrictions require some elaboration.
|
||||
|
||||
:::* 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. Representing the length of any string as a number should also be avoided. 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.
|
||||
:::: To make this a bit more concrete, here are a couple of specific examples:
|
||||
::::: In C, a string is an array of chars, so using a couple of arrays as strings is in the spirit while using a second array in a non-string like fashion would violate the intent.
|
||||
::::: In APL or J, arrays are the core of the language so ruling them out is unfair. Meeting the spirit will come down to how they are used.
|
||||
:::: Please keep in mind these are just examples and you may hit new territory finding a solution. There will be other cases like these. Explain your reasoning. You may want to open a discussion on the talk page as well.
|
||||
:::* The added "No rereading" restriction is for practical reasons, re-reading stdin should be broken. I haven't outright banned the use of other files but I've discouraged them as it is basically another form of a list. Somewhere there may be a language that just sings when doing file manipulation and where that makes sense; however, for most there should be a way to accomplish without resorting to an externality.
|
||||
* 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. Representing the length of any string as a number should also be avoided. 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.
|
||||
|
||||
: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.
|
||||
|
||||
To make this a bit more concrete, here are a couple of specific examples:
|
||||
In C, a string is an array of chars, so using a couple of arrays as strings is in the spirit while using a second array in a non-string like fashion would violate the intent.
|
||||
In APL or J, arrays are the core of the language so ruling them out is unfair. Meeting the spirit will come down to how they are used.
|
||||
|
||||
Please keep in mind these are just examples and you may hit new territory finding a solution. There will be other cases like these. Explain your reasoning. You may want to open a discussion on the talk page as well.
|
||||
* The added "No rereading" restriction is for practical reasons, re-reading stdin should be broken. I haven't outright banned the use of other files but I've discouraged them as it is basically another form of a list. Somewhere there may be a language that just sings when doing file manipulation and where that makes sense; however, for most there should be a way to accomplish without resorting to an externality.
|
||||
|
||||
|
||||
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>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
# The standard SIGN operator returns -1 if its operand is < 0 #
|
||||
# , 0 if its operand is 0 #
|
||||
# , 1 if its operand is > 0 #
|
||||
# This array maps he results of SIGN to FALSE or TRUE for the #
|
||||
# ATLEASTASLONGAS operator defined below #
|
||||
[ -1 : 1 ]BOOL not shorter;
|
||||
not shorter[ -1 ] := FALSE;
|
||||
not shorter[ 0 ] := FALSE;
|
||||
not shorter[ 1 ] := TRUE;
|
||||
|
||||
# Set the priorities for the dyadic operators defined below #
|
||||
# 9 is the highest priority, so a LOMGERTHAN b AND ... #
|
||||
# is parsed correctly #
|
||||
PRIO ATLEASTASLONGAS = 9
|
||||
, LONGERTHAN = 9
|
||||
;
|
||||
|
||||
|
||||
OP NONEMPTYSTRING = ( STRING a )STRING: " " + a[ AT 1 ];
|
||||
|
||||
# STRING x is at least as long as STRING y if the substring #
|
||||
# of x from the upper bound of y to the end of x is at least #
|
||||
# one character long #
|
||||
# Note that Algol 68 doesn't raise an error if the substring #
|
||||
# start position is after the upper bound of the string, but #
|
||||
# does object if the start position is before the lower bound #
|
||||
# - hence the need for the NONEMPTYSTRING operator to ensure #
|
||||
# we don't try executing a[ 0 : ] when b is "" #
|
||||
OP ATLEASTASLONGAS = ( STRING x, STRING y )BOOL:
|
||||
BEGIN
|
||||
STRING a = NONEMPTYSTRING x;
|
||||
STRING b = NONEMPTYSTRING y;
|
||||
not shorter[ SIGN UPB a[ UPB b : ] ]
|
||||
END # ATLEASTASLONGAS # ;
|
||||
|
||||
# x is longer than y if x is at least as long as y and #
|
||||
# y is not at least as long as x #
|
||||
OP LONGERTHAN = ( STRING x, STRING y )BOOL: x ATLEASTASLONGAS y AND NOT ( y ATLEASTASLONGAS x );
|
||||
# additional LONGERTHAN operators to handle single chatracter #
|
||||
# STRINGs which are actually CHAR values in Algol 68 #
|
||||
# Not needed for the task, but useful for testing LONGERTHAN #
|
||||
OP LONGERTHAN = ( CHAR x, CHAR y )BOOL: FALSE;
|
||||
OP LONGERTHAN = ( CHAR x, STRING y )BOOL: STRING( x ) LONGERTHAN y;
|
||||
OP LONGERTHAN = ( STRING x, CHAR y )BOOL: x LONGERTHAN STRING( y );
|
||||
|
||||
COMMENT # basic test of LONGERTHAN: # C-MMENT
|
||||
print( ( "abc" LONGERTHAN "bbcd", "ABC" LONGERTHAN "", "" LONGERTHAN "abc", "DEF" LONGERTHAN "DEF", "abcd" LONGERTHAN "a", newline ) );
|
||||
C-MMENT COMMENT
|
||||
|
||||
PROC read line = ( REF FILE f )STRING:
|
||||
BEGIN
|
||||
STRING line;
|
||||
get( f, ( line, newline ) );
|
||||
IF at eof THEN "" ELSE line FI
|
||||
END # read line # ;
|
||||
|
||||
# EOF handler for standard input #
|
||||
BOOL at eof := FALSE;
|
||||
on logical file end( stand in, ( REF FILE f )BOOL:
|
||||
BEGIN
|
||||
at eof := TRUE;
|
||||
TRUE
|
||||
END
|
||||
);
|
||||
|
||||
|
||||
# recursively find the longest line(s) in the specified file #
|
||||
# and print them #
|
||||
PROC print longest lines = ( REF FILE f, STRING longest so far )STRING:
|
||||
BEGIN
|
||||
IF at eof THEN
|
||||
longest so far
|
||||
ELSE
|
||||
STRING s = read line( f );
|
||||
STRING t = IF s LONGERTHAN longest so far
|
||||
THEN
|
||||
print longest lines( f, s )
|
||||
ELSE
|
||||
print longest lines( f, longest so far )
|
||||
FI;
|
||||
IF s ATLEASTASLONGAS t AND t ATLEASTASLONGAS s
|
||||
THEN
|
||||
# this line is as long as the longest #
|
||||
print( ( s, newline ) );
|
||||
s
|
||||
ELSE
|
||||
# shorter line - return the longest #
|
||||
t
|
||||
FI
|
||||
FI
|
||||
END # print longest lines # ;
|
||||
|
||||
# find the logest lines from standard inoout #
|
||||
VOID( print longest lines( stand in, read line( stand in ) ) )
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
ns longest-string
|
||||
(:gen-class))
|
||||
|
||||
(defn longer [a b]
|
||||
" if a is longer, it returns the characters in a after length b characters have been removed
|
||||
otherwise it returns nil "
|
||||
(if (or (empty? a) (empty? b))
|
||||
(not-empty a)
|
||||
(recur (rest a) (rest b))))
|
||||
|
||||
(defn get-input []
|
||||
" Gets the data from standard input as a lazy-sequence of lines (i.e. reads lines as needed by caller
|
||||
Input is terminated by a zero length line (i.e. line with just <CR> "
|
||||
(let [line (read-line)]
|
||||
(if (> (count line) 0)
|
||||
(lazy-seq (cons line (get-input)))
|
||||
nil)))
|
||||
|
||||
(defn process []
|
||||
" Returns list of longest lines "
|
||||
(first ; takes lines from [lines longest]
|
||||
(reduce (fn [[lines longest] x]
|
||||
(cond
|
||||
(longer x longest) [x x] ; new longer line
|
||||
(not (longer longest x)) [(str lines "\n" x) longest] ; append x to previous longest
|
||||
:else [lines longest])) ; keep previous lines & longest
|
||||
["" ""] (get-input))))
|
||||
|
||||
(println "Input text:")
|
||||
(println "Output:\n" (process))
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# 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
|
||||
$File = ( Get-Content C:\Test\File.txt ) -join "`n"
|
||||
|
||||
$LongestString = $LongestStrings = ''
|
||||
|
||||
# While the file string still still exists
|
||||
While ( $File )
|
||||
{
|
||||
# Set the String to the first string and File to any remaining strings
|
||||
$String, $File = $File.Split( "`n", 2 )
|
||||
|
||||
# Strip off characters until one or both strings are zero length
|
||||
$A = $LongestString
|
||||
$B = $String
|
||||
While ( $A -and $B )
|
||||
{
|
||||
$A = $A.Substring( 1 )
|
||||
$B = $B.Substring( 1 )
|
||||
}
|
||||
|
||||
# If A is zero length...
|
||||
If ( -not $A )
|
||||
{
|
||||
# If $B is not zero length (and therefore String is longer than LongestString)...
|
||||
If ( $B )
|
||||
{
|
||||
$LongestString = $String
|
||||
$LongestStrings = $String
|
||||
}
|
||||
# Else ($B is also zero length, and therefore String is the same length as LongestString)...
|
||||
Else
|
||||
{
|
||||
$LongestStrings = $LongestStrings, $String -join "`n"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Output longest strings
|
||||
$LongestStrings.Split( "`n" )
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
@'
|
||||
a
|
||||
bb
|
||||
ccc
|
||||
ddd
|
||||
ee
|
||||
f
|
||||
ggg
|
||||
'@ -split "`r`n" |
|
||||
Group-Object -Property Length |
|
||||
Sort-Object -Property Name -Descending |
|
||||
Select-Object -Property Count, @{Name="Length"; Expression={[int]$_.Name}}, Group -First 1
|
||||
Loading…
Add table
Add a link
Reference in a new issue