Last letter-first letter: Difference between revisions
Content added Content deleted
SqrtNegInf (talk | contribs) 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 ───► |
<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' |
||
⚫ | |||
⚫ | |||
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. */ |
||
@ |
call build@ /*build a stemmed array from the @ list*/ |
||
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.*/ |
||
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) |
|||
end /*v*/ /*delete dead word from @ ──┘ */ |
|||
$$$= /*nullify the possible longest path. */ |
|||
if ig\==0 then do; call build@; say; say 'ignoring' ig "dead word"s(ig).; say |
|||
end |
|||
⚫ | |||
g=words($$$) |
|||
⚫ | |||
parse value @.1 @.j with @.j @.1; call scan $$$, 2 |
|||
parse value @.1 @.j with @.j @.1 |
|||
⚫ | |||
⚫ | |||
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.*/ |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
build@: do i=1 for #; @.i=word(@, i) /*build a stemmed array from the list. */ |
|||
⚫ | |||
⚫ | |||
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 |
do i=! to #; parse var @.i p 2 /*scan for the longest word path. */ |
||
if p==LC then do |
if p==LC then do /*is the first─character ≡ last─char? */ |
||
if !==MPL then MP=MP+1 |
if !==MPL then MP= MP+1 /*bump the Maximum Paths Counter. */ |
||
else if !>MPL then do; |
else if !>MPL then do; $$$=@.1 /*rebuild. */ |
||
do n=2 for !-2; $$$=$$$ @.n |
|||
end /*n*/ |
|||
$$$=$$$ @.i /*add last.*/ |
$$$=$$$ @.i /*add last.*/ |
||
MP=1; |
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> |
||
⚫ | |||
{{out|output|text= when using the default input:}} |
{{out|output|text= 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) |
::* removes dead words (words that cannot be used in a path) |
||
::* stops scanning when a dead-end word is encountered. |
::* stops scanning when a dead-end word is encountered. |
||
With the full list of words being used, there are no dead words (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 (but there are when a limit is used to shorten the list). |
||
<br>In the '''scan''' 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 '''scan''' 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. */ |
||
⚫ | |||
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:' |
say 'ignoring dead word:' @.v; ig=ig+1; @=delword(@, v, 1) |
||
end /*v*/ /*delete dead word from @ ──┘ */ |
end /*v*/ /*delete dead word from @ ──┘ */ |
||
#= words(@) /*recalculate the number of words in @.*/ |
|||
do v=# by -1 for # /*scrub the @ list for stoppable words.*/ |
|||
⚫ | |||
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 @ ──┘ */ |
|||
⚫ | |||
say 'stop words: ' @s; say |
|||
end |
end |
||
$$$= /*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. */ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
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.*/ |
||
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
/*──────────────────────────────────────────────────────────────────────────────────────*/ |
||
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 |
if !==MPL then MP= MP+1 /*bump the Maximum Paths Counter. */ |
||
else if !>MPL then do; $$$=@.1 |
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.*/ |
||
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> |
||
⚫ | |||
{{out|output|text= is the same as the brute force version.}} |
{{out|output|text= is the same as the brute force version.}} |
||
<br><br> |
<br><br> |