Last letter-first letter: Difference between revisions

Content added Content deleted
m (→‎{{header|Perl 6}}: fix file open error handling)
m (→‎{{header|REXX}}: added/changed whitespace and comments, changing wording in the REXX header section.)
Line 3,564: Line 3,564:
<br><br>This REXX version allows a limit on the word scan (very useful for debugging), and
<br><br>This REXX version allows a limit on the word scan (very useful for debugging), and
<br>also has various speed optimizations.
<br>also has various speed optimizations.
<lang rexx>/*REXX program finds the longest path of word's last─letter ───► first-letter. */
<lang rexx>/*REXX program finds the longest path of word's last─letter ───► first─letter. */
@='audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon cresselia croagunk darmanitan',
@='audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon cresselia croagunk darmanitan',
'deino emboar emolga exeggcute gabite girafarig gulpin haxorus heatmor heatran ivysaur jellicent',
'deino emboar emolga exeggcute gabite girafarig gulpin haxorus heatmor heatran ivysaur jellicent',
Line 3,571: Line 3,571:
'remoraid rufflet sableye scolipede scrafty seaking sealeo silcoon simisear snivy snorlax spoink',
'remoraid rufflet sableye scolipede scrafty seaking sealeo silcoon simisear snivy snorlax spoink',
'starly tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask'
'starly tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask'
#= words(@) @.=; ig= 0; !.= 0 /*nullify array and the longest path. */
#=words(@)
parse arg limit .; if limit\=='' then #=limit /*allow user to specify a scan limit. */
parse arg limit .; if limit\=='' then #=limit /*allow user to specify a scan limit. */
@.=; $$$= /*nullify array; and also longest path.*/
call build@ /*build a stemmed array from the @ list*/
do i=1 for # /*build a stemmed array from the list. */
do v=# by -1 for # /*scrub the @ list for unusable words. */
@.i=word(@, i)
parse var @.v F 2 '' -1 L /*obtain first and last letter of word.*/
end /*i*/
if !.1.F>1 | !.9.L>1 then iterate /*is this a dead word?*/
MP=0; MPL=0 /*the initial Maximum Path Length. */
say 'ignoring dead word:' @.v; ig= ig+1; @= delword(@, v, 1)
do j=1 for # /* ─ ─ ─ */
end /*v*/ /*delete dead word from @ ──┘ */
parse value @.1 @.j with @.j @.1; call scan $$$, 2
$$$= /*nullify the possible longest path. */
parse value @.1 @.j with @.j @.1
if ig\==0 then do; call build@; say; say 'ignoring' ig "dead word"s(ig).; say
end /*j*/
end
MP= 0; MPL= 0 /*the initial Maximum Path Length. */
g=words($$$)
do j=1 for # /* ─ ─ ─ */
parse value @.1 @.j with @.j @.1; call scan $$$, 2
parse value @.1 @.j with @.j @.1
end /*j*/
g= words($$$)
say 'Of' # "words," MP 'path's(MP) "have the maximum path length of" g'.'
say 'Of' # "words," MP 'path's(MP) "have the maximum path length of" g'.'
say; say 'One example path of that length is: ' word($$$, 1)
say; say 'One example path of that length is: ' word($$$, 1)
Line 3,590: Line 3,595:
s: if arg(1)==1 then return arg(3); return word( arg(2) 's', 1) /*a pluralizer.*/
s: if arg(1)==1 then return arg(3); return word( arg(2) 's', 1) /*a pluralizer.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
scan: procedure expose @. MP # MPL $$$; parse arg $$$,!; p=! - 1
build@: do i=1 for #; @.i=word(@, i) /*build a stemmed array from the list. */
F= left(@.i, 1); !.1.F= !.1.F + 1 /*F: 1st char; !.1.F=count of 1st char*/
L=right(@.i, 1); !.9.L= !.9.L + 1 /*L: last " !.9.L= " " last " */
end /*i*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
scan: procedure expose @. # !. $$$ MP MPL; parse arg $$$,!; p=! - 1
parse var @.p '' -1 LC /*obtain last character of previous @. */
parse var @.p '' -1 LC /*obtain last character of previous @. */
if !.1.LC==0 then return /*is this a dead─end word? */
/* [↓] PARSE obtains first char of @.i*/
/* [↓] PARSE obtains first char of @.i*/
do i=! to #; parse var @.i p 2 /* [↓] scan for the longest word path.*/
do i=! to #; parse var @.i p 2 /*scan for the longest word path. */
if p==LC then do /*is the first─char last─char ? */
if p==LC then do /*is the first─character ≡ last─char? */
if !==MPL then MP=MP+1 /*bump the Maximum Paths counter. */
if !==MPL then MP= MP+1 /*bump the Maximum Paths Counter. */
else if !>MPL then do; $$$=@.1 /*rebuild. */
else if !>MPL then do; $$$=@.1 /*rebuild. */
do n=2 to !-1; $$$=$$$ @.n
do n=2 for !-2; $$$=$$$ @.n
end /*n*/
end /*n*/
$$$=$$$ @.i /*add last.*/
$$$=$$$ @.i /*add last.*/
MP=1; MPL=! /*new path.*/
MP=1; MPL=! /*new path.*/
end
end
parse value @.! @.i with @.i @.!; call scan $$$, !+1
parse value @.! @.i with @.i @.!; call scan $$$, !+1
parse value @.! @.i with @.i @.!
parse value @.! @.i with @.i @.!
end
end
end /*i*/
end /*i*/; return /*exhausted this particular scan. */</lang>
return /*exhausted this particular word scan. */</lang>
{{out|output|text=&nbsp; when using the default input:}}
{{out|output|text=&nbsp; when using the default input:}}
<pre>
<pre>
Line 3,638: Line 3,648:
===optimized version===
===optimized version===
This optimized version has two major improvements:
This optimized version has two major improvements:
::* removes dead words (words that cannot be used in a path)
::* &nbsp; removes dead words (words that cannot be used in a path)
::* stops scanning when a dead-end word is encountered.
::* &nbsp; stops scanning when a dead-end word is encountered.
With the full list of words being used, there are no dead words &nbsp; (but there are when a limit is used to shorten the list).
With the full list of words being used, there are no dead words &nbsp; (but there are when a limit is used to shorten the list).
<br>In the &nbsp; '''scan''' &nbsp; subroutine, a check is made to see if the word being used is a dead-end word, and if so, the rest of
<br>In the &nbsp; '''scan''' &nbsp; subroutine, a check is made to see if the word being used is a dead-end word, and if so, the rest of
Line 3,651: Line 3,661:
'remoraid rufflet sableye scolipede scrafty seaking sealeo silcoon simisear snivy snorlax spoink',
'remoraid rufflet sableye scolipede scrafty seaking sealeo silcoon simisear snivy snorlax spoink',
'starly tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask'
'starly tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask'
#= words(@); @.=; @s=; ig=0; og=0; !.=0 /*nullify array and the longest path. */
#=words(@)
parse arg limit .; if limit\=='' then #=limit /*allow user to specify a scan limit. */
parse arg limit .; if limit\=='' then #=limit /*allow user to specify a scan limit. */
@.=; ig=0; !.=0 /*nullify array and the longest path. */
call build@ /*build a stemmed array from the @ list*/
call build@ /*build a stemmed array from the @ list*/
do v=# by -1 for # /*scrub the @ list for unusable words. */
do v=# by -1 for # /*scrub the @ list for unusable words. */
parse var @.v F 2 '' -1 L /*obtain first and last letter of word.*/
parse var @.v F 2 '' -1 L /*obtain first and last letter of word.*/
if !.1.F>1 | !.9.L>1 then iterate /*is this a dead word?*/
if !.1.F>1 | !.9.L>1 then iterate /*is this a dead word?*/
say 'ignoring dead word:' @.v; ig=ig+1; @=delword(@, v, 1)
say 'ignoring dead word:' @.v; ig=ig+1; @=delword(@, v, 1)
end /*v*/ /*delete dead word from @ ──┘ */
end /*v*/ /*delete dead word from @ ──┘ */
$$$= /*nullify the possible longest path. */
#= words(@) /*recalculate the number of words in @.*/
do v=# by -1 for # /*scrub the @ list for stoppable words.*/
if ig\==0 then do; call build@; say; say 'ignoring' ig "dead word"s(ig).; say
parse var @.v F 2 '' -1 L /*obtain first and last letter of word.*/
if !.1.L>0 then iterate /*is this a stop word? */
say 'removing stop word:' @.v; og=og+1; @=delword(@, v, 1); @s=@s @.v
end /*v*/ /*delete dead word from @ ──┘ */

if og\==0 then do; call build@; say; say 'ignoring' og "stop word"s(og).
say 'stop words: ' @s; say
end
end
MP=0; MPL=0 /*the initial Maximum Path Length. */
$$$= /*nullify the possible longest path. */
MP= 0; MPL= 0 /*the initial Maximum Path Length. */
do j=1 for # /* ─ ─ ─ */
do j=1 for # /* ─ ─ ─ */
parse value @.1 @.j with @.j @.1; call scan $$$, 2
parse value @.1 @.j with @.j @.1; call scan $$$, 2
parse value @.1 @.j with @.j @.1
parse value @.1 @.j with @.j @.1
end /*j*/
end /*j*/
g=words($$$)
g= words($$$)
say 'Of' # "words," MP 'path's(MP) "have the maximum path length of" g'.'
say 'Of' # "words," MP 'path's(MP) "have the maximum path length of" g'.'
say; say 'One example path of that length is: ' word($$$, 1)
say; say 'One example path of that length is: ' word($$$, 1)
do m=2 to g; say left('', 36) word($$$, m); end /*m*/
do m=2 to g; say left('', 36) word($$$, m); end /*m*/
exit /*stick a fork in it, we're all done. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
build@: do i=1 for #; @.i=word(@, i) /*build a stemmed array from the list. */
F= left(@.i, 1); !.1.F=!.1.F + 1 /*F: 1st char; !.1.F=count of 1st char*/
L=right(@.i, 1); !.9.L=!.9.L + 1 /*L: last " !.9.L= " " last " */
end /*i*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
s: if arg(1)==1 then return arg(3); return word( arg(2) 's', 1) /*a pluralizer.*/
s: if arg(1)==1 then return arg(3); return word( arg(2) 's', 1) /*a pluralizer.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
scan: procedure expose @. # !. $$$ MP MPL; parse arg $$$,!; p=! - 1
build@: do i=1 for #; @.i= word(@, i) /*build a stemmed array from the list. */
F= left(@.i, 1); !.1.F= !.1.F + 1 /*F: 1st char; !.1.F=count of 1st char*/
L=right(@.i, 1); !.9.L= !.9.L + 1 /*L: last " !.9.L= " " last " */
end /*i*/; return
/*──────────────────────────────────────────────────────────────────────────────────────*/
scan: procedure expose @. # !. $$$ MP MPL; parse arg $$$,!; p= ! - 1
parse var @.p '' -1 LC /*obtain last character of previous @. */
parse var @.p '' -1 LC /*obtain last character of previous @. */
if !.1.LC==0 then return /*is this a dead─end word? */
if !.1.LC==0 then return /*is this a dead─end word? */
Line 3,687: Line 3,704:
do i=! to #; parse var @.i p 2 /*scan for the longest word path. */
do i=! to #; parse var @.i p 2 /*scan for the longest word path. */
if p==LC then do /*is the first─character ≡ last─char? */
if p==LC then do /*is the first─character ≡ last─char? */
if !==MPL then MP=MP+1 /*bump the Maximum Paths Counter. */
if !==MPL then MP= MP+1 /*bump the Maximum Paths Counter. */
else if !>MPL then do; $$$=@.1 /*rebuild. */
else if !>MPL then do; $$$= @.1 /*rebuild. */
do n=2 for !-2; $$$=$$$ @.n
do n=2 for !-2; $$$=$$$ @.n
end /*n*/
end /*n*/
$$$=$$$ @.i /*add last.*/
$$$= $$$ @.i /*add last.*/
MP=1; MPL=! /*new path.*/
MP=1; MPL=! /*new path.*/
end
end
Line 3,697: Line 3,714:
parse value @.! @.i with @.i @.!
parse value @.! @.i with @.i @.!
end
end
end /*i*/
end /*i*/; return /*exhausted this particular scan. */</lang>
return /*exhausted this particular scan. */</lang>
{{out|output|text=&nbsp; is the same as the brute force version.}}
{{out|output|text=&nbsp; is the same as the brute force version.}}
<br><br>
<br><br>