Last letter-first letter: Difference between revisions

Content deleted Content added
Chkas (talk | contribs)
Added Easylang
 
(131 intermediate revisions by 57 users not shown)
Line 1:
{{task}}
A certain childrens game involves starting with a word in a particular category. Each participant in turn says a word, but that word must begin with the final letter of the previous word. Once a word has been given, it cannot be repeated. If an opponent cannot give a word in the category, they fall out of the game. For example, with "animals" as the category,
 
A certain children's game involves starting with a word in a particular category.   Each participant in turn says a word, but that word must begin with the final letter of the previous word.   Once a word has been given, it cannot be repeated.   If an opponent cannot give a word in the category, they fall out of the game.
<pre>Child 1: dog
 
 
For example, with &nbsp; "animals" &nbsp; as the category,
<pre>
Child 1: dog
Child 2: goldfish
Child 1: hippopotamus
Line 9 ⟶ 13:
</pre>
 
;Task Description
Take the following selection of 70 English Pokemon names (extracted from [[wp:List of Pokémon|Wikipedia's list of Pokemon]]) and generate the/a sequence with the highest possible number of Pokemon names where the subsequent name starts with the final letter of the preceding name. No Pokemon name is to be repeated.
 
;Task:
<pre>audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
Take the following selection of 70 English Pokemon names &nbsp; (extracted from &nbsp; [[wp:List of Pokémon|Wikipedia's list of Pokemon]]) &nbsp; and generate the/a sequence with the highest possible number of Pokemon names where the subsequent name starts with the final letter of the preceding name.
 
No Pokemon name is to be repeated.
 
<pre>
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
Line 19 ⟶ 27:
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask</pre>
</pre>
 
 
Extra brownie points for dealing with the full list of &nbsp; 646 &nbsp; names.
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F order_words(words)
DefaultDict[Char, Set[String]] byfirst
L(word) words
byfirst[word[0]].add(word)
R byfirst
 
F linkfirst(&byfirst; sofar)
assert(!sofar.empty)
V chmatch = sofar.last.last
V options = byfirst[chmatch] - Set(sofar)
 
I options.empty
R sofar
E
V alternatives = options.map(word -> linkfirst(&@byfirst, @sofar [+] [word]))
R max(alternatives, key' s -> s.len)
 
F llfl(words)
V byfirst = order_words(words)
R max((words.map(word -> linkfirst(&@byfirst, [word]))), key' s -> s.len)
 
V pokemon_str = ‘audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask’
V pokemon = pokemon_str.split((‘ ’, "\n"))
V l = llfl(pokemon)
L(i) (0 .< l.len).step(8)
print(l[i .< i + 8].join(‘ ’))
print(l.len)</syntaxhighlight>
 
{{out}}
<pre>
machamp petilil landorus scrafty yamask kricketune emboar registeel
loudred darmanitan nosepass simisear relicanth heatmor rufflet trapinch
haxorus seaking girafarig gabite exeggcute emolga audino
23
</pre>
 
=={{header|Ada}}==
 
<syntaxhighlight lang="ada">with Ada.Containers.Indefinite_Vectors, Ada.Text_IO;
 
procedure Lalefile is
 
package Word_Vec is new Ada.Containers.Indefinite_Vectors
(Index_Type => Positive,
Element_Type => String);
 
use type Word_Vec.Vector, Ada.Containers.Count_Type;
 
type Words_Type is array (Character) of Word_Vec.Vector;
 
procedure Read(Words: out Words_Type) is
F: Ada.Text_IO.File_Type;
begin
Ada.Text_IO.Open(File => F,
Name => "pokemon70.txt",
Mode => Ada.Text_IO.In_File);
loop
declare
Word: String := Ada.Text_IO.Get_Line(F);
begin
exit when Word = "";
Words(Word(Word'First)).Append(Word);
end;
end loop;
exception
when Ada.Text_IO.End_Error => null;
end Read;
 
procedure Write (List: Word_Vec.Vector; Prefix: String := " ") is
Copy: Word_Vec.Vector := List;
begin
loop
exit when Copy.Is_Empty;
Ada.Text_IO.Put_Line(Prefix & Copy.First_Element);
Copy.Delete_First;
end loop;
end Write;
 
function Run(Start: Character; Words: Words_Type) return Word_Vec.Vector is
Result: Word_Vec.Vector := Word_Vec.Empty_Vector;
begin
for I in Words(Start).First_Index .. Words(Start).Last_Index loop
declare
Word: String := Words(Start).Element(I);
Dupl: Words_Type := Words;
Alternative : Word_Vec.Vector;
begin
Dupl(Start).Delete(I);
Alternative := Word & Run(Word(Word'Last), Dupl);
if Alternative.Length > Result.Length then
Result := Alternative;
end if;
end;
end loop;
return Result;
end Run;
 
W: Words_Type;
A_Vector: Word_Vec.Vector;
Best: Word_Vec.Vector := Word_Vec.Empty_Vector;
 
begin
Read(W);
Ada.Text_IO.Put("Processing ");
for Ch in Character range 'a' .. 'z' loop
Ada.Text_IO.Put(Ch & ", ");
A_Vector := Run(Ch, W);
if A_Vector.Length > Best.Length then
Best := A_Vector;
end if;
end loop;
Ada.Text_IO.New_Line;
Ada.Text_IO.Put_Line("Length of longest Path:" &
Integer'Image(Integer(Best.Length)));
Ada.Text_IO.Put_Line("One such path:");
Write(Best);
end Lalefile;</syntaxhighlight>
 
Output:<pre>Processing a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,
Length of longest Path: 23
One such path:
machamp
petilil
landorus
scrafty
yamask
kricketune
emboar
registeel
loudred
darmanitan
nosepass
simisear
relicanth
heatmor
rufflet
trapinch
haxorus
seaking
girafarig
gabite
exeggcute
emolga
audino</pre>
 
=={{header|BaCon}}==
Naive implementation showing the algorithm.
<syntaxhighlight lang="freebasic">all$ = "audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon " \
"cresselia croagunk darmanitan deino emboar emolga exeggcute gabite " \
"girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan " \
"kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine " \
"nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2 " \
"porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking " \
"sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko " \
"tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask"
 
SUB check(list$, rest$)
 
LOCAL x
 
FOR x = 1 TO AMOUNT(rest$)
IF RIGHT$(list$, 1) = LEFT$(TOKEN$(rest$, x), 1) THEN check(APPEND$(list$, 0, TOKEN$(rest$, x)), DEL$(rest$, x))
NEXT
 
IF AMOUNT(list$) > total THEN
total = AMOUNT(list$)
result$ = list$
END IF
 
END SUB
 
FOR z = 1 TO AMOUNT(all$)
CALL check(TOKEN$(all$, z), DEL$(all$,z))
NEXT
 
PRINT total, ": ", result$
 
PRINT NL$, "Speed: ", TIMER, " msecs."</syntaxhighlight>
{{out}}
<pre>
23: machamp petilil landorus scrafty yamask kricketune emboar registeel loudred darmanitan nosepass simisear relicanth heatmor rufflet trapinch haxorus seaking girafarig gabite exeggcute emolga audino
 
Speed: 662734 msecs.
</pre>
Optimized implementation. The idea is to quantify the equations.
<syntaxhighlight lang="freebasic">all$ = "audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon " \
"cresselia croagunk darmanitan deino emboar emolga exeggcute gabite " \
"girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan " \
"kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine " \
"nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2 " \
"porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking " \
"sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko " \
"tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask"
 
SPLIT all$ TO name$ SIZE MaxSize
 
DECLARE start, end, used, result ARRAY MaxSize
 
FOR y = 0 TO MaxSize-1
start[y] = ASC(LEFT$(name$[y], 1))
end[y] = ASC(RIGHT$(name$[y], 1))
used[y] = -1
NEXT
 
FOR i = 0 TO MaxSize-1
used[i] = 0
CALL check(used, i, 1)
used[i] = -1
NEXT
 
PRINT maxtotal, ": ";
FOR a = 0 TO maxtotal-1
FOR y = 0 TO MaxSize-1
IF result[y] = a THEN PRINT name$[y]," ";
NEXT
NEXT
 
PRINT NL$, "Speed: ", TIMER, " msecs."
 
SUB check(ya[], ultim, nr)
 
LOCAL x
 
FOR x = 0 TO MaxSize-1
IF end[ultim] = start[x] AND ya[x] = -1 THEN
ya[x] = nr
CALL check(ya, x, nr+1)
ya[x] = -1
END IF
 
IF nr > maxtotal THEN
maxtotal = nr
OPTION MEMTYPE long
COPY ya TO result SIZE MaxSize
END IF
NEXT
 
END SUB
</syntaxhighlight>
{{out}}
<pre>
23: machamp petilil landorus scrafty yamask kricketune emboar registeel loudred darmanitan nosepass simisear relicanth heatmor rufflet trapinch haxorus seaking girafarig gabite exeggcute emolga audino
 
Speed: 818 msecs.
</pre>
 
=={{header|BASIC256}}==
<syntaxhighlight lang="basic256">dim names$(1)
names$ = { "audino", "bagon", "baltoy", "banette", "bidoof", "braviary", "bronzor", "carracosta", "charmeleon", "cresselia", "croagunk", "darmanitan", "deino", "emboar", "emolga", "exeggcute", "gabite", "girafarig", "gulpin", "haxorus", "heatmor", "heatran", "ivysaur", "jellicent", "jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba", "loudred", "lumineon", "lunatone", "machamp", "magnezone", "mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu", "pinsir", "poliwrath", "poochyena", "porygon2", "porygonz", "registeel", "relicanth", "remoraid", "rufflet", "sableye", "scolipede", "scrafty", "seaking", "sealeo", "silcoon", "simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga", "trapinch", "treecko", "tyrogue", "vigoroth", "vulpix", "wailord", "wartortle", "whismur", "wingull", "yamask" }
 
global names$, lnames, index, maxlen, first, last
maxlen = 0
 
lnames = names$[?]-1
dim index(names$[?])
dim first(names$[?])
dim last(names$[?])
for t = 0 to lnames
index[t] = t
last[t] = asc(right(names$[t],1))
first[t] = asc(left(names$[t],1))
next t
 
 
# try each name as the first name on the list
for t = 0 to lnames
call swapindex(0,t)
call downlevel(1)
call swapindex(0,t)
next t
 
end
 
subroutine downlevel(lev)
#print n$[?] + " " + lev
if lev <= lnames then
for t = lev to lnames
if last[index[lev-1]] = first[index[t]] then
call swapindex(lev,t)
if lev >= maxlen then
maxlen = lev
call showsolution(lev)
end if
call downlevel(lev+1)
call swapindex(lev,t)
end if
next t
end if
end subroutine
 
subroutine showsolution(l)
print l+1;
for t = 0 to l
print " " + names$[index[t]];
next t
print
end subroutine
 
subroutine swapindex(a, b)
# swap element a and bin in the array index (used to swap names$)
t = index[a]
index[a] = index[b]
index[b] = t
end subroutine
</syntaxhighlight>
 
Output:
<pre>2 bagon nosepass
3 bagon nosepass sableye
4 bagon nosepass sableye emboar
5 bagon nosepass sableye emboar registeel
...
23 machamp pinsir rufflet trapinch heatmor remoraid darmanitan nosepass starly yamask kricketune emboar relicanth haxorus simisear registeel landorus seaking girafarig gabite exeggcute emolga audino
23 machamp pinsir rufflet trapinch heatmor remoraid darmanitan nosepass starly yamask kricketune exeggcute emboar registeel landorus simisear relicanth haxorus seaking girafarig gabite emolga audino
23 machamp pinsir rufflet trapinch heatmor remoraid darmanitan nosepass starly yamask kricketune exeggcute emboar relicanth haxorus simisear registeel landorus seaking girafarig gabite emolga audino</pre>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<syntaxhighlight lang="bbcbasic"> DIM names$(69)
names$() = "audino", "bagon", "baltoy", "banette", \
\ "bidoof", "braviary", "bronzor", "carracosta", "charmeleon", \
\ "cresselia", "croagunk", "darmanitan", "deino", "emboar", \
\ "emolga", "exeggcute", "gabite", "girafarig", "gulpin", \
\ "haxorus", "heatmor", "heatran", "ivysaur", "jellicent", \
\ "jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba", \
\ "loudred", "lumineon", "lunatone", "machamp", "magnezone", \
\ "mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu", \
\ "pinsir", "poliwrath", "poochyena", "porygon2", "porygonz", \
\ "registeel", "relicanth", "remoraid", "rufflet", "sableye", \
\ "scolipede", "scrafty", "seaking", "sealeo", "silcoon", \
\ "simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga", \
\ "trapinch", "treecko", "tyrogue", "vigoroth", "vulpix", \
\ "wailord", "wartortle", "whismur", "wingull", "yamask"
maxPathLength% = 0
maxPathLengthCount% = 0
maxPathExample$ = ""
FOR i% = 0 TO DIM(names$(),1)
SWAP names$(0), names$(i%)
PROClastfirst(names$(), 1)
SWAP names$(0), names$(i%)
NEXT
PRINT "Maximum length = " ; maxPathLength%
PRINT "Number of solutions with that length = " ; maxPathLengthCount%
PRINT "One such solution: " ' maxPathExample$
END
DEF PROClastfirst(names$(), offset%)
LOCAL i%, l%
IF offset% > maxPathLength% THEN
maxPathLength% = offset%
maxPathLengthCount% = 1
ELSE IF offset% = maxPathLength% THEN;
maxPathLengthCount% += 1
maxPathExample$ = ""
FOR i% = 0 TO offset%-1
maxPathExample$ += names$(i%) + CHR$13 + CHR$10
NEXT
ENDIF
l% = ASCRIGHT$(names$(offset% - 1))
FOR i% = offset% TO DIM(names$(),1)
IF ASCnames$(i%) = l% THEN
SWAP names$(i%), names$(offset%)
PROClastfirst(names$(), offset%+1)
SWAP names$(i%), names$(offset%)
ENDIF
NEXT
ENDPROC</syntaxhighlight>
'''Output:'''
<pre>
Maximum length = 23
Number of solutions with that length = 1248
One such solution:
machamp
pinsir
rufflet
trapinch
heatmor
remoraid
darmanitan
nosepass
starly
yamask
kricketune
exeggcute
emboar
relicanth
haxorus
simisear
registeel
landorus
seaking
girafarig
gabite
emolga
audino
</pre>
 
=={{header|Bracmat}}==
===Naive===
<syntaxhighlight lang="bracmat">( audino bagon baltoy banette bidoof braviary bronzor
carracosta charmeleon cresselia croagunk darmanitan deino
emboar emolga exeggcute gabite girafarig gulpin haxorus
heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp
magnezone mamoswine nosepass petilil pidgeotto pikachu
pinsir poliwrath poochyena porygon2 porygonz registeel
relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly
tirtouga trapinch treecko tyrogue vigoroth vulpix wailord
wartortle whismur wingull yamask
: ?names
& 0:?max
& :?sequence
& ( lalefile
= done todo A M Z Length first
. !arg:(!done.)&!done:?sequence
| !arg:(.?todo)
& ( !todo
: ?A
%@?M
(?Z&lalefile$(!M.!A !Z)&~)
|
)
| !arg:(@(%:? @?first) ?:?done.?todo)
& :?M
& ( !todo
: ?A
@(%:!first ?:?M)
( ?Z
& lalefile$(!M !done.!A !Z)
& ~
)
| !M:
& !done:? [?Length
& !Length:>!max:?max
& !done:?sequence
|
)
)
& lalefile$(.!names)
& out$("Length:" !max "Sequence:" !sequence)
);</syntaxhighlight>
Output (read from bottom to top):
<pre> Length:
23
Sequence:
audino
emolga
exeggcute
gabite
girafarig
seaking
haxorus
trapinch
rufflet
heatmor
relicanth
simisear
nosepass
darmanitan
loudred
registeel
emboar
kricketune
yamask
scrafty
landorus
petilil
machamp</pre>
===Optimized===
Optimizations:
 
The <code>whl</code> loop transforms the flat list of names to, conceptually, a search tree with nodes at three levels. The lowest level contains the names. The top level contains the word's first letter and the second level contains its last letter. Words starting with a specific letter are all children of one single top node, speeding up search for candidates. Under a second level node all words have the same letter at the start and the same letter at the end. When looking for candidates it always suffices to take the first word and ignore the rest. This optimization eliminates all solutions that merely are the result of swapping pairs of words with the same begin and end. Notice that the tree is built using the 'smart' binary operators <code>*</code>, <code>^</code>, <code>+</code> and <code>\L</code> (logarithm). Bracmat uses the commutative, distributive and associative laws to transform expressions containing these operators to canonical forms that fit the requiremens of the search tree. For example, the words in the list <code>sableye scolipede scrafty seaking sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko tyrogue</code> end up in this tree:
<pre> s
^ ( (.e)\L(sableye*scolipede)
+ (.g)\Lseaking
+ (.k)\Lspoink
+ (.n)\Lsilcoon
+ (.o)\Lsealeo
+ (.r)\Lsimisear
+ (.x)\Lsnorlax
+ (.y)\L(scrafty*snivy*starly)
)
* t
^ ( (.a)\Ltirtouga
+ (.e)\Ltyrogue
+ (.h)\Ltrapinch
+ (.o)\Ltreecko
)</pre>
 
Another, less important, optimization is the way in which the last letter of a name is found, using the position pattern <code>[</code> rather than the pattern that matches at most one letter, <code>@</code>.
 
The optimized version is about 4.5 times faster than the naive version.
 
<syntaxhighlight lang="bracmat">( audino bagon baltoy banette bidoof braviary bronzor
Extra brownie points for dealing with the full list of 646 names.
carracosta charmeleon cresselia croagunk darmanitan deino
emboar emolga exeggcute gabite girafarig gulpin haxorus
heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp
magnezone mamoswine nosepass petilil pidgeotto pikachu
pinsir poliwrath poochyena porygon2 porygonz registeel
relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly
tirtouga trapinch treecko tyrogue vigoroth vulpix wailord
wartortle whismur wingull yamask
: ?names
& 1:?newnames
& whl
' ( !names:@(%?name:%@?first ? @?last) ?names
& !first^(.!last)\L!name*!newnames:?newnames
)
& !newnames:?names
& 0:?max
& :?sequence
& ( lalefile
= done todo A M Z Length first
, Ms a z last candidates
. !arg:(!done.)&!done:?sequence
| !arg:(.?todo)
& ( !todo
: ?A
* %?first^?candidates
* ( ?Z
& !candidates
: ?a
+ ?last\L(%?M*?Ms)
+ ( ?z
& lalefile$(!M.!A*!first^(!a+!last\L!Ms+!z)*!Z)
& ~
)
)
|
)
| !arg:(@(%:? [-2 ?first) ?:?done.?todo)
& :?M
& ( !todo:?A*!first^%?candidates*?Z
& !candidates
: ?a
+ ?last\L(%?M*?Ms)
+ ( ?z
& lalefile
$ (!M !done.!A*!first^(!a+!last\L!Ms+!z)*!Z)
& ~
)
| !M:
& !done:? [?Length
& !Length:>!max:?max
& !done:?sequence
|
)
)
& lalefile$(.!names)
& out$("Length:" !max "Sequence:" !sequence)
);</syntaxhighlight>
Output (read from bottom to top):
<pre> Length:
23
Sequence:
audino
emolga
kricketune
yamask
scrafty
haxorus
trapinch
rufflet
simisear
landorus
registeel
heatmor
relicanth
emboar
exeggcute
gabite
girafarig
seaking
nosepass
darmanitan
loudred
petilil
machamp</pre>
 
=={{header|C}}==
From the D version.
<langsyntaxhighlight lang="c">#include <stdlib.h>
#include <string.h>
#include <stdio.h>
Line 43 ⟶ 648:
size_t n_solutions;
 
const char** longest_path;
size_t longest_path_len;
 
 
/// tally statistics
void search(const size_t curr_len) {
if (curr_len == longest_path_refs_len) {
n_solutions++;
Line 58 ⟶ 663:
 
// recursive search
const intptr_t last_char = refs[curr_len - 1].last_char;
for (size_t i = curr_len; i < refs_len; i++)
if (refs[i].first_char == last_char) {
const Ref aux = refs[curr_len];
refs[curr_len] = refs[i];
refs[i] = aux;
Line 70 ⟶ 675:
}
 
void find_longest_chain(const char **const items[],
const size_t items_len) {
refs_len = items_len;
refs = calloc(refs_len, sizeof(Ref));
Line 80 ⟶ 685:
 
for (size_t i = 0; i < items_len; i++) {
const size_t itemsi_len = strlen(items[i]);
if (itemsi_len <= 1)
exit(1);
Line 90 ⟶ 695:
// try each item as possible start
for (size_t i = 0; i < items_len; i++) {
const Ref aux = refs[0];
refs[0] = refs[i];
refs[i] = aux;
Line 99 ⟶ 704:
 
longest_path_len = longest_path_refs_len;
longest_path = calloc(longest_path_len, sizeof(const char*));
for (size_t i = 0; i < longest_path_len; i++)
longest_path[i] = items[longest_path_refs[i].index];
Line 108 ⟶ 713:
 
int main() {
const char* pokemon[] = {"audino", "bagon", "baltoy", "banette",
"bidoof", "braviary", "bronzor", "carracosta", "charmeleon",
"cresselia", "croagunk", "darmanitan", "deino", "emboar",
Line 122 ⟶ 727:
"trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
"wailord", "wartortle", "whismur", "wingull", "yamask"};
const size_t pokemon_len = sizeof(pokemon) / sizeof(pokemon[0]);
 
find_longest_chain(pokemon, pokemon_len);
Line 138 ⟶ 743:
 
return 0;
}</langsyntaxhighlight>
Output:
<pre>Maximum path length: 23
Line 151 ⟶ 756:
===Approximate===
For dealing with full list (646 names), here's an approximate method. Names are restricted to begin and end with a lower case letter, so for example in my input file "porygon2" is written as "porygon-two". It finds some chains with 300-odd length for 646 names, and found a chain with 23 for the 70 names (by luck, that is), and since it's basically a one-pass method, running time is next to none. C99 code.
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 346 ⟶ 951:
printf("longest found: %d\n", best);
return 0;
}</langsyntaxhighlight>output<syntaxhighlight lang="text">read 646 names
307: voltorb breloom magikarp palpito...
308: voltorb bayleef forretress swinub b...
Line 354 ⟶ 959:
322: voltorb beldum mandibuzz zekrom murk...
323: voltorb breloom mandibuzz zekr...
longest found: 323</langsyntaxhighlight>
 
=={{header|DC sharp}}==
<syntaxhighlight lang="csharp">using System;
Improved from the Go version:
using System.Collections.Generic;
<lang d>import std.stdio,std.algorithm,std.string,std.range,std.typecons;
using System.Linq;
using System.Text;
 
namespace ConsoleApplication1
Tuple!(string[], int) findLongestChain(string[] items) {
{
string[] longestPath;
intclass nSolutions;Program
{
static void Main(string[] args)
{
string pokemon_names = @"audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask";
 
string[] pokemon = pokemon_names.Split(new char[]{' ','\n'});
void search(in int currLen) {
List<string> chain = new List<string>(pokemon.Length);
if (currLen == longestPath.length) {
 
nSolutions++;
} else if for (currLenint >i longestPath= 0; i < pokemon.length)Length; {i++)
nSolutions = 1;{
longestPath = items swap(ref pokemon[0], ..ref currLenpokemon[i].dup);
Search( pokemon, chain, 1 );
swap(ref pokemon[0], ref pokemon[i]);
}
 
foreach (string s in chain)
Console.WriteLine(s);
 
Console.ReadKey();
}
 
static void Search(string[] pokemon, List<string> longest_chain, int len )
// recursive search
{
const dchar lastChar = items[currLen - 1][$ - 1];
foreach (i; currLen .. itemsif (len > longest_chain.lengthCount)
if (items[i][0] == lastChar) {
swaplongest_chain.Clear(items[currLen], items[i]);
searchfor (currLenint +i 1)= 0; i < len; i++)
swap(items[currLen], items longest_chain.Add(pokemon[i]);
}
 
char lastchar = pokemon[len - 1][pokemon[len-1].Length - 1];
for (int i = len; i < pokemon.Length; i++)
{
if (pokemon[i][0] == lastchar)
{
swap(ref pokemon[i], ref pokemon[len]);
Search(pokemon, longest_chain, len + 1);
swap(ref pokemon[i], ref pokemon[len]);
}
}
}
 
static void swap(ref string s1, ref string s2)
{
string tmp = s1;
s1 = s2;
s2 = tmp;
}
}
}</syntaxhighlight><pre>machamp
petilil
landorus
sableye
emboar
registeel
loudred
darmanitan
nosepass
simisear
relicanth
heatmor
rufflet
trapinch
haxorus
scrafty
yamask
kricketune
exeggcute
emolga
audino</pre>
 
=={{header|C++}}==
// try each item as possible start
<syntaxhighlight lang="cpp">#include <iostream>
foreach (i; 0 .. items.length) {
#include <string>
swap(items[0], items[i]);
#include <vector>
search(1);
 
swap(items[0], items[i]);
struct last_letter_first_letter {
size_t max_path_length = 0;
size_t max_path_length_count = 0;
std::vector<std::string> max_path_example;
 
void search(std::vector<std::string>& names, size_t offset) {
if (offset > max_path_length) {
max_path_length = offset;
max_path_length_count = 1;
max_path_example.assign(names.begin(), names.begin() + offset);
} else if (offset == max_path_length) {
++max_path_length_count;
}
char last_letter = names[offset - 1].back();
for (size_t i = offset, n = names.size(); i < n; ++i) {
if (names[i][0] == last_letter) {
names[i].swap(names[offset]);
search(names, offset + 1);
names[i].swap(names[offset]);
}
}
}
 
void find_longest_chain(std::vector<std::string>& names) {
return tuple(longestPath, nSolutions);
max_path_length = 0;
max_path_length_count = 0;
max_path_example.clear();
for (size_t i = 0, n = names.size(); i < n; ++i) {
names[i].swap(names[0]);
search(names, 1);
names[i].swap(names[0]);
}
}
};
 
int main() {
std::vector<std::string> names{"audino", "bagon", "baltoy", "banette",
"bidoof", "braviary", "bronzor", "carracosta", "charmeleon",
"cresselia", "croagunk", "darmanitan", "deino", "emboar",
"emolga", "exeggcute", "gabite", "girafarig", "gulpin",
"haxorus", "heatmor", "heatran", "ivysaur", "jellicent",
"jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba",
"loudred", "lumineon", "lunatone", "machamp", "magnezone",
"mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu",
"pinsir", "poliwrath", "poochyena", "porygon2", "porygonz",
"registeel", "relicanth", "remoraid", "rufflet", "sableye",
"scolipede", "scrafty", "seaking", "sealeo", "silcoon",
"simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga",
"trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
"wailord", "wartortle", "whismur", "wingull", "yamask"};
last_letter_first_letter solver;
solver.find_longest_chain(names);
std::cout << "Maximum path length: " << solver.max_path_length << '\n';
std::cout << "Paths of that length: " << solver.max_path_length_count << '\n';
std::cout << "Example path of that length:\n ";
for (size_t i = 0, n = solver.max_path_example.size(); i < n; ++i) {
if (i > 0 && i % 7 == 0)
std::cout << "\n ";
else if (i > 0)
std::cout << ' ';
std::cout << solver.max_path_example[i];
}
std::cout << '\n';
}</syntaxhighlight>
 
{{out}}
<pre>
Maximum path length: 23
Paths of that length: 1248
Example path of that length:
machamp petilil landorus scrafty yamask kricketune emboar
registeel loudred darmanitan nosepass simisear relicanth heatmor
rufflet trapinch haxorus seaking girafarig gabite exeggcute
emolga audino
</pre>
 
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">(ns rosetta-code.last-letter-first-letter
(:require clojure.string))
 
(defn by-first-letter
"Returns a map from letters to a set of words that start with that letter"
[words]
(into {} (map (fn [[k v]]
[k (set v)]))
(group-by first words)))
 
(defn longest-path-from
"Find a longest path starting at word, using only words-by-first-letter for successive words.
Returns a pair of [length list-of-words] to describe the path."
[word words-by-first-letter]
(let [words-without-word (update words-by-first-letter (first word)
disj word)
next-words (words-without-word (last word))]
(if (empty? next-words)
[1 [word]]
(let [sub-paths (map #(longest-path-from % words-without-word) next-words)
[length words-of-path] (apply max-key first sub-paths)]
[(inc length) (cons word words-of-path)]))))
 
(defn longest-word-chain
"Find a longest path among the words in word-list, by performing a longest path search
starting at each word in the list."
[word-list]
(let [words-by-letter (by-first-letter word-list)]
(apply max-key first
(pmap #(longest-path-from % words-by-letter)
word-list))))
 
(defn word-list-from-file [file-name]
(let [contents (slurp file-name)
words (clojure.string/split contents #"[ \n]")]
(filter #(not (empty? %)) words)))
 
(time (longest-word-chain (word-list-from-file "pokemon.txt")))</syntaxhighlight>
Evaluating the last line:
<syntaxhighlight lang="clojure">"Elapsed time: 2867.337816 msecs"
[23
("machamp"
"pinsir"
"relicanth"
"heatmor"
"registeel"
"landorus"
"seaking"
"girafarig"
"gabite"
"exeggcute"
"emboar"
"rufflet"
"trapinch"
"haxorus"
"simisear"
"remoraid"
"darmanitan"
"nosepass"
"scrafty"
"yamask"
"kricketune"
"emolga"
"audino")]</syntaxhighlight>
It initially ran in about 5 seconds, then I changed <code>map</code> to <code>pmap</code> (parallel map) in <code>longest-word-chain</code>.
This gave a nice speedup for a dual core laptop; the speedup for parallel searches was over 3x on a server.
 
=={{header|Common Lisp}}==
Pretty brute force here. Takes a couple of seconds to run.
<syntaxhighlight lang="lisp">;;; return all the words that start with an initial letter
 
(defun filter-with-init (words init)
(remove-if-not (lambda (word) (eql init (aref word 0))) words))
 
;;; produce a hash table whose key is the initial letter of a word and whose value is
;;; a list of the words that start with that initial letter
 
(defun group-by-first-letter (words)
(let ((map_letters (make-hash-table))
(inits (remove-duplicates (mapcar (lambda (word) (aref word 0)) words))))
(dolist (init inits map_letters)
(setf (gethash init map_letters) (filter-with-init words init)))
))
 
;;; Get the last letter in a word or array
 
(defun last-element (array) (aref array (- (length array) 1)))
 
;;; Produce a hash table whose key is a word and whose value is a list of the
;;; words that can follow that word
 
(defun get-followers (words)
(let ((map-word-to-followers (make-hash-table :test 'equal))
(init_hash (group-by-first-letter words)))
(dolist (word words map-word-to-followers)
(setf
(gethash word map-word-to-followers)
(gethash (last-element word) init_hash)))))
 
;;; Retrieve all the keys from a hash table
 
(defun keys (hashtbl)
(let ((allkeys ()))
(maphash #'(lambda (key val) (setf allkeys (cons key allkeys))) hashtbl)
allkeys))
 
;;; Find the words which can follow a word and haven't been used yet. The parameters are:
;;; word - word being tested
;;; followers - the hash table returned from get-followers
;;; available - hash table with word as key and boolean indicating whether that word
;;; has been used previously as value
 
(defun get-available-followers (word followers available)
(if (null word)
(keys followers)
(remove-if-not #'(lambda (word) (gethash word available)) (gethash word followers))))
 
;;; Find the best in a list using an arbitrary test
 
(defun best (lst test)
(let ((top (car lst)))
(do
((rest (cdr lst) (cdr rest)))
((null rest) top)
(if (funcall test (car rest) top) (setf top (car rest))))))
 
;;; Find the best path in a list
 
(defun best-list-path (paths)
(best paths #'(lambda (path1 path2) (> (length path1) (length path2)))))
 
;;; Find the best path given all the supporting information we need
 
(defun best-path-from-available (word followers available depth path available-followers)
(let ((results
(mapcar #'(lambda (new-word)
(dfs-recurse new-word followers available (+ 1 depth) (cons word path)))
available-followers)))
(best-list-path results)))
 
;;; Recurse to find the best available path - the meat of the algorithm
 
(defun dfs-recurse (word followers available depth path)
(let ((ret))
; Mark the word as unavailable
(setf (gethash word available) nil)
; Find the longest path starting with word
(let ((available-followers (get-available-followers word followers available)))
(setf ret
(if (null available-followers)
(cons word path)
(best-path-from-available word followers available depth path available-followers))))
; Mark the word as available again
(setf (gethash word available) t)
; Return our longest path
ret))
 
;;; Create the availability table
 
(defun make-available-table (words)
(let
((available (make-hash-table)))
(dolist (word words available) (setf (gethash word available) t))))
 
;;; Find the best path for a set of words
 
(defun best-path (words)
(let
((followers (get-followers words))
(available (make-available-table words)))
(cdr (reverse (dfs-recurse nil followers available 0 nil)))))
 
;;; set up the words as a set of strings
(setf *words* (mapcar #'symbol-name
'(audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask)))
 
(setf *path* (best-path *words*))</syntaxhighlight>
Output:<syntaxhighlight lang="text">("MACHAMP" "PETILIL" "LANDORUS" "SCRAFTY" "YAMASK" "KRICKETUNE" "EMBOAR" "REGISTEEL"
"LOUDRED" "DARMANITAN" "NOSEPASS" "SIMISEAR" "RELICANTH" "HEATMOR" "RUFFLET"
"TRAPINCH" "HAXORUS" "SEAKING" "GIRAFARIG" "GABITE" "EXEGGCUTE" "EMOLGA" "AUDINO")</syntaxhighlight>
 
=={{header|D}}==
===Simple Version===
Modified from the Go version:
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.string;
 
void trySwap(string[] items, ref string item, in size_t len, ref string[] longest)
pure nothrow @safe {
swap(items[len], item);
search(items, len + 1, longest);
swap(items[len], item);
}
 
void search(string[] items, in size_t len, ref string[] longest)
pure nothrow @safe {
if (len > longest.length)
longest = items[0 .. len].dup;
immutable lastChar = items[len - 1][$ - 1];
foreach (ref item; items[len .. $])
if (item[0] == lastChar)
trySwap(items, item, len, longest);
}
 
void main() @safe {
auto pokemon = "audino bagon baltoy banette bidoof braviary
bronzor carracosta charmeleon cresselia croagunk darmanitan deino
Line 403 ⟶ 1,353:
scrafty seaking sealeo silcoon simisear snivy snorlax spoink starly
tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle
whismur wingull yamask".tolower().split();
 
string[] solution;
// remove duplicates
pokemon.lengthforeach -= copy(uniq(pokemon.sort()),ref name; pokemon).length;
trySwap(pokemon, name, 0, solution);
 
writefln("%-(%s\n%)", solution);
auto sol_nsol = findLongestChain(pokemon);
}</syntaxhighlight>
writeln("Maximum path length: ", sol_nsol[0].length);
writeln("Paths of that length: ", sol_nsol[1]);
writeln("Example path of that length:");
foreach (i; iota(0, cast(int)sol_nsol[0].length, 7))
writeln(" ", sol_nsol[0][i .. min(i+7, $)].join(" "));
}</lang>
Output:
<pre>machamp
<pre>Maximum path length: 23
petilil
Paths of that length: 1248
landorus
Example path of that length:
scrafty
machamp petilil landorus scrafty yamask kricketune emboar
yamask
registeel loudred darmanitan nosepass simisear relicanth heatmor
kricketune
rufflet trapinch haxorus seaking girafarig gabite exeggcute
emboar
emolga audino</pre>
registeel
Runtime: about 1.23 seconds, dmd compiler.
loudred
darmanitan
nosepass
simisear
relicanth
heatmor
rufflet
trapinch
haxorus
seaking
girafarig
gabite
exeggcute
emolga
audino</pre>
The run-time is about 0.9 seconds with the dmd compiler and about 0.55 seconds with the ldc2 compiler.
 
===Improved Version===
A more optimized solution (same output):
With two small changes the code gets faster. Here the names are represented as in C (so swapping them means just swapping a pointer, instead of swapping a pointer+length as before), and during the computation their last char is swapped with their second char (so there's no need to keep the string lengths around or use strlen).
<lang d>import std.stdio, std.algorithm, std.string,
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.string, std.array, std.conv;
std.range, std.typecons;
 
void search(immutable(char)*[] items, in int len,
ref immutable(char)*[] longest) pure {
if (len > longest.length)
longest = items[0 .. len].dup;
immutable lastChar = items[len - 1][1];
foreach (ref item; items[len .. $])
if (item[0] == lastChar) {
swap(items[len], item);
search(items, len + 1, longest);
swap(items[len], item);
}
}
 
void main() {
alias Tuple!(string, "word", bool, "unused") Pair;
static immutable(char)* prep(in string s) pure {
int nSolutions;
assert(s.length > 1);
auto sd = s.dup;
swap(sd[1], sd[$ - 1]);
return sd.toStringz;
}
 
static string unprep(immutable(char)* sd) pure {
auto ms = sd.to!(char[]);
swap(ms[1], ms[$ - 1]);
return ms;
}
 
auto pokemon = "audino bagon baltoy banette bidoof braviary
void search(Pair[][] sequences, size_t minHead, string currWord,
bronzor carracosta charmeleon cresselia croagunk darmanitan deino
string[] currentPath, size_t currentPathLen,
emboar emolga exeggcute gabite girafarig gulpin haxorus heatmor
ref string[] longestPath) {
heatran ivysaur jellicent jumpluff kangaskhan kricketune landorus
ledyba loudred lumineon lunatone machamp magnezone mamoswine nosepass
petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede
scrafty seaking sealeo silcoon simisear snivy snorlax spoink starly
tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle
whismur wingull yamask".split.map!prep.array;
 
immutable(char)*[] solution;
currentPath[currentPathLen] = currWord;
foreach (ref name; pokemon) {
currentPathLen++;
swap(pokemon[0], name);
 
search(pokemon, 1, solution);
if (currentPathLen == longestPath.length) {
nSolutions++swap(pokemon[0], name);
} else if (currentPathLen > longestPath.length) {
nSolutions = 1;
longestPath = currentPath[0 .. currentPathLen].dup;
}
 
writefln("%-(%s\n%)", solution.map!unprep);
// recursive search
}</syntaxhighlight>
size_t lastCharIndex = currWord[$ - 1] - minHead;
if (lastCharIndex < sequences.length)
foreach (ref pair; sequences[lastCharIndex])
if (pair.unused) {
pair.unused = false;
search(sequences, minHead, pair.word, currentPath,
currentPathLen, longestPath);
pair.unused = true;
}
}
 
This leads to tight enough code for the foreach loop in the search function:
 
<syntaxhighlight lang="asm">LBB0_4:
movl (%esi), %eax
movb 19(%esp), %cl
cmpb %cl, (%eax)
jne LBB0_6
movl (%edi,%ebx,4), %ecx
movl %eax, (%edi,%ebx,4)
movl %ecx, (%esi)
movl %edi, 8(%esp)
movl 48(%esp), %eax
movl %eax, 4(%esp)
movl 12(%esp), %eax
movl %eax, (%esp)
movl 20(%esp), %eax
calll __D25last_letter_first_letter26searchFNaAPyaxiKAPyaZv
subl $12, %esp
movl (%edi,%ebx,4), %eax
movl (%esi), %ecx
movl %ecx, (%edi,%ebx,4)
movl %eax, (%esi)
LBB0_6:
addl $4, %esi
decl %ebp
jne LBB0_4</syntaxhighlight>
 
The run-time is about 0.65 seconds with LDC2 compiler. The output is similar.
 
===Faster Version===
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.string, std.range, std.typecons;
 
Tuple!(uint, string[]) findLongestChain(in string[] words)
pure nothrow {
static struct Pair { string word; bool unused; }
uint nSolutions;
 
void search(Pair[][] sequences, in size_t minHead,
in string currWord, string[] currentPath,
size_t currentPathLen,
ref string[] longestPath) nothrow {
currentPath[currentPathLen] = currWord;
currentPathLen++;
 
if (currentPathLen == longestPath.length) {
nSolutions++;
} else if (currentPathLen > longestPath.length) {
nSolutions = 1;
longestPath = currentPath[0 .. currentPathLen].dup;
}
 
// Recursive search.
immutable size_t lastCharIndex = currWord[$ - 1] - minHead;
if (lastCharIndex < sequences.length)
foreach (ref pair; sequences[lastCharIndex])
if (pair.unused) {
pair.unused = false;
search(sequences, minHead, pair.word, currentPath,
currentPathLen, longestPath);
pair.unused = true;
}
}
 
if (words.empty)
typeof(return)(0, null);
immutable heads = words.map!q{ a[0] }.array;
immutable size_t minHead = reduce!min(heads[0],
heads[1.. $].representation);
immutable size_t maxHead = reduce!max(heads[0],
heads[1.. $].representation);
 
string[] findLongestChain(string[] words) {
auto heads = map!q{ a[0] }(words);
size_t minHead = reduce!min(heads);
size_t maxHead = reduce!max(heads);
auto sequences = new Pair[][](maxHead - minHead + 1, 0);
foreach (const word; words)
sequences[word[0] - minHead] ~= Pair(word, true);
 
Line 472 ⟶ 1,517:
string[] longestPath;
 
// tryTry each item as possible start.
foreach (seq; sequences)
foreach (ref pair; seq) {
Line 481 ⟶ 1,526:
}
 
return typeof(return)(nSolutions, longestPath);
}
 
Line 495 ⟶ 1,540:
scrafty seaking sealeo silcoon simisear snivy snorlax spoink starly
tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle
whismur wingull yamask".tolower()toLower.split();
 
// removeRemove duplicates.
pokemon.length -= copy(uniq(pokemon.sort()), .uniq.copy(pokemon).length;
 
autoconst sol = findLongestChain(pokemon).findLongestChain;
writeln("Maximum path length: ", sol[1].length);
writeln("Paths of that length: ", nSolutionssol[0]);
writeln("Example path of that length:");
foreach writefln(i; iota"%(0, cast %-(int%s %)sol.length\n%)", sol[1].chunks(7));
}</syntaxhighlight>
writeln(" ", sol[i .. min(i+7, $)].join(" "));
{{out}}
}</lang>
<pre>Maximum path length: 23
Runtime: about 0.20 seconds, dmd compiler.
Paths of that length: 1248
Example path of that length:
machamp petilil landorus scrafty yamask kricketune emboar
registeel loudred darmanitan nosepass simisear relicanth heatmor
rufflet trapinch haxorus seaking girafarig gabite exeggcute
emolga audino</pre>
Runtime: about 0.20 seconds with dmd compiler, about 0.15 seconds with ldc2 compiler.
 
===Alternative Version===
{{trans|PicoLisp}}
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.array, std.typecons,
std.container, std.range;
 
auto findChain(in string[] seq) pure nothrow /*@safe*/ {
const adj = seq
.map!(item => tuple(item, seq
.filter!(x => x[0] == item[$ - 1])
.array))
.assocArray;
SList!string res;
 
foreach (immutable item; adj.byKey) {
void inner(in string it, SList!string lst) nothrow {
lst.insertFront(it);
if (lst[].walkLength > res[].walkLength)
res = lst;
foreach (immutable x; adj[it])
if (!lst[].canFind(x))
inner(x, lst);
}
 
inner(item, SList!string());
}
 
return res.array.retro;
}
 
void main() /*@safe*/ {
"audino bagon baltoy banette bidoof braviary
bronzor carracosta charmeleon cresselia croagunk darmanitan deino
emboar emolga exeggcute gabite girafarig gulpin haxorus heatmor
heatran ivysaur jellicent jumpluff kangaskhan kricketune landorus
ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena
porygon2 porygonz registeel relicanth remoraid rufflet sableye
scolipede scrafty seaking sealeo silcoon simisear snivy snorlax
spoink starly tirtouga trapinch treecko tyrogue vigoroth vulpix
wailord wartortle whismur wingull yamask".split.findChain.writeln;
}</syntaxhighlight>
{{out}}
<pre>["machamp", "petilil", "landorus", "scrafty", "yamask", "kricketune", "emboar", "registeel", "loudred", "darmanitan", "nosepass", "simisear", "relicanth", "heatmor", "rufflet", "trapinch", "haxorus", "seaking", "girafarig", "gabite", "exeggcute", "emolga", "audino"]</pre>
Run-time is about 3.1 seconds with ldc2 compiler.
 
=={{header|Delphi}}==
Visual implementation, this unit is a VCL Form with a Memo, a Button, a Checkbox, a DataGrid, a DBMemo, a DataSource and a ClientDataSet with tree fields (length integer,count integer,list memo):
<langsyntaxhighlight lang="delphi">unit Unit1;
 
interface
Line 787 ⟶ 1,884:
end;
 
end.</langsyntaxhighlight>
Runtime varies depending if you run the "optimized" version or not. Ranges from 6 to 18 seconds.
 
NOTE: "optimized" version is actually a different algorithm, but in most cases returns the same results.
 
=={{header|EasyLang}}==
<syntaxhighlight>
repeat
s$ = input
until s$ = ""
for n$ in strsplit s$ " "
pok$[] &= n$
.
.
#
chain$[] = [ ]
proc search lng . .
if lng > len chain$[]
chain$[] = [ ]
for j to lng
chain$[] &= pok$[j]
.
.
lastc$ = substr pok$[lng] len pok$[lng] 1
for i = lng + 1 to len pok$[]
if substr pok$[i] 1 1 = lastc$
swap pok$[i] pok$[lng + 1]
search lng + 1
swap pok$[i] pok$[lng + 1]
.
.
.
for i to len pok$[]
swap pok$[i] pok$[1]
search 1
swap pok$[i] pok$[1]
.
for p$ in chain$[]
write p$ & " "
.
#
input_data
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask
</syntaxhighlight>
{{out}}
<pre>
machamp petilil landorus scrafty yamask kricketune emboar registeel loudred darmanitan nosepass simisear relicanth heatmor rufflet trapinch haxorus seaking girafarig gabite exeggcute emolga audino
</pre>
 
=={{header|Elixir}}==
{{trans|Ruby}}
<syntaxhighlight lang="elixir">defmodule LastLetter_FirstLetter do
def search(names) do
first = Enum.group_by(names, &String.first/1)
sequences = Enum.reduce(names, [], fn name,acc -> add_name(first, acc, [name]) end)
max = Enum.max_by(sequences, &length/1) |> length
max_seqs = Enum.filter(sequences, fn seq -> length(seq) == max end)
IO.puts "there are #{length(sequences)} possible sequences"
IO.puts "the longest is #{max} names long"
IO.puts "there are #{length(max_seqs)} such sequences. one is:"
hd(max_seqs) |> Enum.with_index |>
Enum.each(fn {name, idx} ->
:io.fwrite " ~2w ~s~n", [idx+1, name]
end)
end
defp add_name(first, sequences, seq) do
last_letter = String.last(hd(seq))
potentials = Map.get(first, last_letter, []) -- seq
if potentials == [] do
[Enum.reverse(seq) | sequences]
else
Enum.reduce(potentials, sequences, fn name, acc -> add_name(first, acc, [name | seq]) end)
end
end
end
 
names = ~w(
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask
)
 
LastLetter_FirstLetter.search(names)</syntaxhighlight>
 
{{out}}
<pre>
there are 2076396 possible sequences
the longest is 23 names long
there are 1248 such sequences. one is:
1 machamp
2 petilil
3 landorus
4 scrafty
5 yamask
6 kricketune
7 emboar
8 registeel
9 loudred
10 darmanitan
11 nosepass
12 simisear
13 relicanth
14 heatmor
15 rufflet
16 trapinch
17 haxorus
18 seaking
19 girafarig
20 gabite
21 exeggcute
22 emolga
23 audino
</pre>
 
=={{header|Erlang}}==
This is a parallel version. It takes 2.1 seconds. The (commented out) serial version takes 7.1 seconds. Both times measured on my (low end) Mac Mini. I thought parallel code would help in getting the brownie points. But even a small increase to 100 Pokemons makes the code run for more than the few spare hours I have in the evening.
<syntaxhighlight lang="erlang">
-module( last_letter_first_letter ).
 
-export( [solve/1, task/0] ).
 
solve( Names ) ->
Dict = lists:foldl( fun dict_append/2, dict:new(), Names ),
Chains = construct_chains_in_parallel( Dict ),
% Chains = [construct_chain_from_key(Dict, X) || X <- dict:fetch_keys(Dict)],
lists:foldl( fun construct_chain_longest/2, [], Chains ).
 
task() -> solve( binary:split(names(), <<" ">>, [global]) ).
 
 
 
construct_chains_in_parallel( Dict ) ->
My_pid = erlang:self(),
Pids = [erlang:spawn( fun() -> My_pid ! {erlang:self(), construct_chain_from_key(Dict, X)} end) || X <- dict:fetch_keys(Dict)],
[receive {X, Chain} -> Chain end || X <- Pids].
 
construct_chain_from_key( Dict, First_letter ) ->
Names = construct_chain_names( dict:find(First_letter, Dict) ),
construct_chain_from_names( Names, Dict, [] ).
 
construct_chain_from_names( [], _Dict, Best_chain ) -> Best_chain;
construct_chain_from_names( [{Name, Last_letter} | T], Dict, Best_chain ) ->
New_dict = dict_delete( Name, Dict ),
New_chain = [Name | construct_chain_from_key( New_dict, Last_letter )],
construct_chain_from_names( T, Dict, construct_chain_longest(Best_chain, New_chain) ).
 
construct_chain_longest( Chain1, Chain2 ) when length(Chain1) > length(Chain2) -> Chain1;
construct_chain_longest( _Chain1, Chain2 ) -> Chain2.
 
construct_chain_names( {ok, {Name, Last_letter}} ) -> [{Name, Last_letter}];
construct_chain_names( {ok, Values} ) -> Values;
construct_chain_names( error ) -> [].
 
dict_append( Name, Acc ) ->
{First_letter, {Name, Last_letter}} = dict_item( Name ),
dict:append( First_letter, {Name, Last_letter}, Acc ).
 
dict_item( <<First_letter, _T/binary>>=Name ) ->
Until_last_letter = erlang:byte_size( Name ) - 1,
<<_H:Until_last_letter/binary, Last_letter>> = Name,
{First_letter, {Name, Last_letter}}.
 
dict_delete( <<First_letter, _T/binary>>=Name, Dict ) ->
Name_last_letters = dict:fetch(First_letter, Dict),
dict:store( First_letter, lists:keydelete(Name, 1, Name_last_letters), Dict ).
 
names() -> <<"audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon cresselia croagunk darmanitan deino emboar emolga exeggcute gabite girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2 porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask">>.
</syntaxhighlight>
{{out}}
<pre>
11> last_letter_first_letter:task().
[<<"machamp">>,<<"pinsir">>,<<"rufflet">>,<<"trapinch">>,
<<"heatmor">>,<<"remoraid">>,<<"darmanitan">>,
<<"nosepass">>,<<"starly">>,<<"yamask">>,<<"kricketune">>,
<<"exeggcute">>,<<"emboar">>,<<"relicanth">>,<<"haxorus">>,
<<"simisear">>,<<"registeel">>,<<"landorus">>,<<"seaking">>,
<<"girafarig">>,<<"gabite">>,<<"emolga">>,<<"audino">>]
</pre>
 
=={{header|Go}}==
Depth first, starting with each possible name.
<langsyntaxhighlight lang="go">package main
 
import (
Line 849 ⟶ 2,133:
}
}
}</langsyntaxhighlight>
Output:
<pre>
Line 864 ⟶ 2,148:
=={{header|Haskell}}==
Note: This takes ~80 seconds to complete on my machine.
<langsyntaxhighlight Haskelllang="haskell">import Data.List
import qualified Data.ByteString.Char8 as B
 
Line 886 ⟶ 2,170:
isLink pl pr = B.last pl == B.head pr
 
main = mapM_ B.putStrLn $ growChains $ map (\x -> [x]) allPokemon</langsyntaxhighlight>
Output:
<pre>machamp
Line 911 ⟶ 2,195:
emolga
audino</pre>
A simpler version (no ByteString), about 2.4 times slower (GHC -O3), same output:
<syntaxhighlight lang="haskell">import Data.List
 
allPokemon = words
"audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon \
\cresselia croagunk darmanitan deino emboar emolga exeggcute gabite \
\girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan \
\kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine \
\nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2 \
\porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking \
\sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko \
\tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask"
 
growChains :: [[String]] -> [String]
growChains pcs
| nextChainSet == [] = head pcs
| otherwise = growChains nextChainSet
where nextChainSet = pcs >>= findLinks
findLinks pc = map (\x -> pc ++ [x]) $ filter (isLink $ last pc) (allPokemon \\ pc)
isLink pl pr = last pl == head pr
 
main = mapM_ putStrLn $ growChains $ map (\x -> [x]) allPokemon</syntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
 
Works in both languages (brute force):
 
<syntaxhighlight lang="unicon">global words
 
procedure main()
words := table()
every word := genwords(&input) do {
/words[word[1]] := []
put(words[word[1]], word)
}
bP := []
every p := getPath(!!words,[]) do if *\p > *bP then bP := copy(p)
write("Longest: ",*bP)
every writes((!bP||" ")|"\n")
end
 
procedure getPath(word, p)
if word == !p then return p
if /words[word[-1]] then suspend p <- p ||| [word]
else suspend getPath(!words[word[-1]], p <- p ||| [word])
end
 
procedure genwords(f)
while l := !f do
l ? while tab(upto(&letters)) do suspend tab(many(&letters))\1
end</syntaxhighlight>
 
Sample run on sample data:
<pre>
->llfl <llfl.in
Longest: 23
machamp petilil landorus scrafty yamask kricketune emboar registeel loudred darmanitan nosepass simisear relicanth heatmor rufflet trapinch haxorus seaking girafarig gabite exeggcute emolga audino
->
</pre>
 
=={{header|J}}==
Here, we use a brute force breadth-first search. Unless we know ahead of time how long "longest" is, we must try all possibilities to ensure that an unchecked possibility is not longer than a possibility which we have found.
 
<langsyntaxhighlight lang="j">pokenames=: ;:0 :0-.LF
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
Line 935 ⟶ 2,278:
end.
r
)</langsyntaxhighlight>
 
The line <code>assert. 1e9>*/8,$r</code> was added to avoid a very bad behavior from microsoft windows which appeared on different arguments, when intermediate results became too large (the machine would have to be rebooted when intermediate results became an order of magnitude larger than the available physical memory). By ensuring that the program would end before consuming that much virtual memory, this behavior from the operating system can be avoided. Note that [http://www.jsoftware.com/help/dictionary/dx009.htm 9!:21 and/or 9!:33] could also be used to prevent OS instability triggered by requesting too many resources.
 
With this procedure we are able to conduct the entire search for this list of names:
 
<langsyntaxhighlight lang="j">$R=: seqs pokenames
1248 23</langsyntaxhighlight>
 
With this data set, we have 1248 sequences of names which have the longest possible length, and those sequences are 23 names long. Here's one of them:
 
<langsyntaxhighlight lang="j"> >pokenames {~{.R
machamp
petilil
Line 969 ⟶ 2,312:
exeggcute
emolga
audino </langsyntaxhighlight>
 
=={{header|Java}}==
<syntaxhighlight lang="java">// derived from C
final class LastLetterFirstLetter {
static int maxPathLength = 0;
static int maxPathLengthCount = 0;
static final StringBuffer maxPathExample = new StringBuffer(500);
 
static final String[] names = {"audino", "bagon", "baltoy", "banette",
"bidoof", "braviary", "bronzor", "carracosta", "charmeleon",
"cresselia", "croagunk", "darmanitan", "deino", "emboar",
"emolga", "exeggcute", "gabite", "girafarig", "gulpin",
"haxorus", "heatmor", "heatran", "ivysaur", "jellicent",
"jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba",
"loudred", "lumineon", "lunatone", "machamp", "magnezone",
"mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu",
"pinsir", "poliwrath", "poochyena", "porygon2", "porygonz",
"registeel", "relicanth", "remoraid", "rufflet", "sableye",
"scolipede", "scrafty", "seaking", "sealeo", "silcoon",
"simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga",
"trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
"wailord", "wartortle", "whismur", "wingull", "yamask"};
 
static void recursive(String[] part, int offset) {
if (offset > maxPathLength) {
maxPathLength = offset;
maxPathLengthCount = 1;
} else if (offset == maxPathLength) {
maxPathLengthCount++;
maxPathExample.setLength(0);
for (int i = 0; i < offset; i++) {
maxPathExample.append((i % 5 == 0 ? "\n " : " "));
maxPathExample.append(part[i]);
}
}
final char lastChar = part[offset - 1].charAt(part[offset - 1].length()-1);
for (int i = offset; i < part.length; i++) {
if (part[i].charAt(0) == lastChar) {
String tmp = names[offset];
names[offset] = names[i];
names[i] = tmp;
recursive(names, offset+1);
names[i] = names[offset];
names[offset] = tmp;
}
}
}
 
public static void main(String[] args) {
for (int i = 0; i < names.length; i++) {
String tmp = names[0];
names[0] = names[i];
names[i] = tmp;
recursive(names, 1);
names[i] = names[0];
names[0] = tmp;
}
System.out.println("maximum path length : " + maxPathLength);
System.out.println("paths of that length : " + maxPathLengthCount);
System.out.println("example path of that length:" + maxPathExample);
}
}
</syntaxhighlight>
 
Output:<pre>maximum path length : 23
paths of that length : 1248
example path of that length:
machamp pinsir rufflet trapinch heatmor
remoraid darmanitan nosepass starly yamask
kricketune exeggcute emboar relicanth haxorus
simisear registeel landorus seaking girafarig
gabite emolga audino
</pre>
 
=={{header|JavaScript}}==
{{Works with|Node.js}} (Required for the ''process'' object)
<syntaxhighlight lang="javascript">/**
* Find the letter the word ends on
* @param {string} word
* @returns {string}
*/
const endsWith = word => word[word.length - 1];
 
/**
* Remove the used elements from the candidate elements
* @param {Array<string>} words Candidate words
* @param {Array<string>} used Used words
* @returns {*}
*/
const getCandidates = (words, used) => words.filter(e => !used.includes(e));
 
/**
* Build a map of letters to words that start with that letter
* @param {Array<string>} words
* @returns {Map<string, Array<string>>}
*/
const buildLookup = words => {
const lookup = new Map();
words.forEach(e => {
const start = e[0];
lookup.set(start, [...(lookup.get(start) || []), e]);
});
return lookup;
};
 
 
/**
* Main function
* @param {Array<string>} names
*/
const findPaths = names => {
const t0 = process.hrtime();
console.log('Checking:', names.length, 'names');
const lookup = buildLookup(names);
 
let maxNum = 0;
let maxPaths = [];
 
const parseResult = arr => {
if (typeof arr[0] === 'object') {
arr.forEach(el => parseResult(el))
} else {
if (arr.length > maxNum) {
maxNum = arr.length;
maxPaths = [arr];
}
if (arr.length === maxNum) {
maxPaths.push(arr)
}
}
};
 
const searchWords = (word, res) => {
const cs = getCandidates(lookup.get(endsWith(word)) || [], res);
return cs.length ? cs.map(e => searchWords(e, [...res, e])) : res;
};
 
names.forEach(word => {
const res = searchWords(word, [word]);
parseResult(res);
});
 
const t1 = process.hrtime(t0);
console.info('Execution time (hr): %ds %dms', t1[0], t1[1] / 1000000);
console.log('Max Path:', maxNum);
console.log('Matching Paths:', maxPaths.length);
console.log('Example Path:', maxPaths[0]);
 
};
 
const pokimon = ["audino", "bagon", "baltoy", "banette",
"bidoof", "braviary", "bronzor", "carracosta", "charmeleon",
"cresselia", "croagunk", "darmanitan", "deino", "emboar",
"emolga", "exeggcute", "gabite", "girafarig", "gulpin",
"haxorus", "heatmor", "heatran", "ivysaur", "jellicent",
"jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba",
"loudred", "lumineon", "lunatone", "machamp", "magnezone",
"mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu",
"pinsir", "poliwrath", "poochyena", "porygon2", "porygonz",
"registeel", "relicanth", "remoraid", "rufflet", "sableye",
"scolipede", "scrafty", "seaking", "sealeo", "silcoon",
"simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga",
"trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
"wailord", "wartortle", "whismur", "wingull", "yamask"];
 
findPaths(pokimon);
</syntaxhighlight>
 
<pre>
Checking: 70 names
Execution time (hr): 2s 121.778223ms
Max Path: 23
Matching Paths: 1249
Example Path: [
'machamp',
'petilil',
'landorus',
'scrafty',
'yamask',
'kricketune',
'emboar',
'registeel',
'loudred',
'darmanitan',
'nosepass',
'simisear',
'relicanth',
'heatmor',
'rufflet',
'trapinch',
'haxorus',
'seaking',
'girafarig',
'gabite',
'exeggcute',
'emolga',
'audino' ]
</pre>
 
=={{header|jq}}==
Short and sweet, with a nod to efficiency in the form of a dictionary for lookup of still-available words.
 
jq's "debug" filter is used to illustrate how progress can be monitored.
It writes to stderr. If your jq does not include "debug", simply remove or comment-out the entire line.
 
'''Utility functions''':
<syntaxhighlight lang="jq"># convert a list of unique words to a dictionary
def dictionary:
reduce .[] as $word ({}; .[$word[0:1]] += [$word]) ;
 
# remove "word" from the input dictionary assuming the key is already there:
def remove(word):
.[word[0:1]] -= [word];</syntaxhighlight>
 
'''The last-letter/first-letter game''':
<syntaxhighlight lang="ja"># left-right admissibility
def admissible:
.[0][-1:] == .[1][0:1];
 
# input: [word, dictionary_of_available_words_excluding_word]
# output: a (possibly empty) stream of admissible values: [next_word, updated_dictionary],
# where next_word can follow the given word.
def next:
.[0] as $word
| if $word == null then empty
else .[1] as $dictionary
| $word[-1:] as $last
| (($dictionary[$last] // []) | .[]) as $next
| [ $next, ($dictionary | remove($next)) ]
end ;
 
# Produce an array representing a thread starting at "word":
# Input: [word, dictionary_of_available_words]
def thread:
if .[1] == [] then [ .[0] ]
else (next // null) as $next
| [.[0]] + (if $next then ($next | thread) else [] end)
end ;
 
# Input: list of words
# Output: [ maximal_length, maximal_thread]
def maximal:
def maximum(start):
. as $dictionary
| reduce ( [start, ($dictionary | remove(start))] | thread ) as $thread
([0, null];
($thread|length) as $l
| if $l > .[0] then [$l, $thread] else . end );
 
dictionary as $dictionary
| reduce .[] as $name
( [0,null];
($dictionary | maximum($name)) as $ans
# If your jq does not include "debug", simply remove or comment-out the following line:
| ([$name, $ans[0]] | debug) as $debug
| if $ans[0] > .[0] then $ans else . end );</syntaxhighlight>
'''Example''':
<syntaxhighlight lang="jq">def names:
["audino", "bagon", "baltoy", "banette",
"bidoof", "braviary", "bronzor", "carracosta", "charmeleon",
"cresselia", "croagunk", "darmanitan", "deino", "emboar",
"emolga", "exeggcute", "gabite", "girafarig", "gulpin",
"haxorus", "heatmor", "heatran", "ivysaur", "jellicent",
"jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba",
"loudred", "lumineon", "lunatone", "machamp", "magnezone",
"mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu",
"pinsir", "poliwrath", "poochyena", "porygon2", "porygonz",
"registeel", "relicanth", "remoraid", "rufflet", "sableye",
"scolipede", "scrafty", "seaking", "sealeo", "silcoon",
"simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga",
"trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
"wailord", "wartortle", "whismur", "wingull", "yamask" ] ;
 
names | maximal</syntaxhighlight>
 
{{out}} (scrollable)
The "DEBUG" lines are included to illustrate how progress can be monitored. They show the maximal length for the indicated initial word.
<div style="overflow:scroll; height:400px;">
<syntaxhighlight lang="sh">$ jq -n -f Last_letter-first_letter.jq
["DEBUG:",["audino",1]]
["DEBUG:",["bagon",20]]
["DEBUG:",["baltoy",21]]
["DEBUG:",["banette",20]]
["DEBUG:",["bidoof",1]]
["DEBUG:",["braviary",21]]
["DEBUG:",["bronzor",22]]
["DEBUG:",["carracosta",2]]
["DEBUG:",["charmeleon",20]]
["DEBUG:",["cresselia",2]]
["DEBUG:",["croagunk",21]]
["DEBUG:",["darmanitan",20]]
["DEBUG:",["deino",1]]
["DEBUG:",["emboar",19]]
["DEBUG:",["emolga",2]]
["DEBUG:",["exeggcute",19]]
["DEBUG:",["gabite",20]]
["DEBUG:",["girafarig",20]]
["DEBUG:",["gulpin",20]]
["DEBUG:",["haxorus",20]]
["DEBUG:",["heatmor",20]]
["DEBUG:",["heatran",20]]
["DEBUG:",["ivysaur",22]]
["DEBUG:",["jellicent",21]]
["DEBUG:",["jumpluff",1]]
["DEBUG:",["kangaskhan",20]]
["DEBUG:",["kricketune",20]]
["DEBUG:",["landorus",21]]
["DEBUG:",["ledyba",2]]
["DEBUG:",["loudred",21]]
["DEBUG:",["lumineon",20]]
["DEBUG:",["lunatone",20]]
["DEBUG:",["machamp",23]]
["DEBUG:",["magnezone",20]]
["DEBUG:",["mamoswine",20]]
["DEBUG:",["nosepass",19]]
["DEBUG:",["petilil",22]]
["DEBUG:",["pidgeotto",1]]
["DEBUG:",["pikachu",1]]
["DEBUG:",["pinsir",22]]
["DEBUG:",["poliwrath",21]]
["DEBUG:",["poochyena",2]]
["DEBUG:",["porygon2",1]]
["DEBUG:",["porygonz",1]]
["DEBUG:",["registeel",21]]
["DEBUG:",["relicanth",21]]
["DEBUG:",["remoraid",21]]
["DEBUG:",["rufflet",21]]
["DEBUG:",["sableye",20]]
["DEBUG:",["scolipede",20]]
["DEBUG:",["scrafty",21]]
["DEBUG:",["seaking",21]]
["DEBUG:",["sealeo",1]]
["DEBUG:",["silcoon",20]]
["DEBUG:",["simisear",21]]
["DEBUG:",["snivy",21]]
["DEBUG:",["snorlax",1]]
["DEBUG:",["spoink",21]]
["DEBUG:",["starly",21]]
["DEBUG:",["tirtouga",2]]
["DEBUG:",["trapinch",20]]
["DEBUG:",["treecko",1]]
["DEBUG:",["tyrogue",20]]
["DEBUG:",["vigoroth",21]]
["DEBUG:",["vulpix",1]]
["DEBUG:",["wailord",21]]
["DEBUG:",["wartortle",20]]
["DEBUG:",["whismur",22]]
["DEBUG:",["wingull",22]]
["DEBUG:",["yamask",20]]
[
23,
[
"machamp",
"petilil",
"landorus",
"scrafty",
"yamask",
"kricketune",
"emboar",
"registeel",
"loudred",
"darmanitan",
"nosepass",
"simisear",
"relicanth",
"heatmor",
"rufflet",
"trapinch",
"haxorus",
"seaking",
"girafarig",
"gabite",
"exeggcute",
"emolga",
"audino"
]
]</syntaxhighlight></div>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
{{trans|Python}}
 
<syntaxhighlight lang="julia">using IterTools.groupby
 
orderwords(words::Vector) = Dict(w[1][1] => Set(w) for w in groupby(first, words))
longest(a, b) = ifelse(length(a) > length(b), a, b)
function linkfirst(byfirst::Dict, sofar::Vector)
@assert(!isempty(sofar))
chmatch = sofar[end][end]
if ! haskey(byfirst, chmatch) return sofar end
options = setdiff(byfirst[chmatch], sofar)
if isempty(options)
return sofar
else
alternatives = ( linkfirst(byfirst, vcat(sofar, word)) for word in options )
mx = reduce(longest, alternatives)
return mx
end
end
function llfl(words)
byfirst = orderwords(words)
alternatives = ( linkfirst(byfirst, [word]) for word in words )
return reduce(longest, alternatives)
end
 
pokemon = String.(unique(split("""
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask
""")))
 
l = llfl(pokemon)
println("Example of longest seq.:\n", join(l, ", "))
println("Max length: ", length(l)</syntaxhighlight>
 
{{out}}
<pre>Example of longest seq.:
machamp, pinsir, relicanth, heatmor, registeel, landorus, starly, yamask, kricketune, emboar, rufflet, trapinch, haxorus, simisear, remoraid, darmanitan, nosepass, seaking, girafarig, gabite, exeggcute, emolga, audino
Max length: 23</pre>
 
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="scala">// version 1.1.2
 
var maxPathLength = 0
var maxPathLengthCount = 0
val maxPathExample = StringBuilder(500)
 
val names = arrayOf(
"audino", "bagon", "baltoy", "banette", "bidoof",
"braviary", "bronzor", "carracosta", "charmeleon", "cresselia",
"croagunk", "darmanitan", "deino", "emboar", "emolga",
"exeggcute", "gabite", "girafarig", "gulpin", "haxorus",
"heatmor", "heatran", "ivysaur", "jellicent", "jumpluff",
"kangaskhan", "kricketune", "landorus", "ledyba", "loudred",
"lumineon", "lunatone", "machamp", "magnezone", "mamoswine",
"nosepass", "petilil", "pidgeotto", "pikachu", "pinsir",
"poliwrath", "poochyena", "porygon2", "porygonz", "registeel",
"relicanth", "remoraid", "rufflet", "sableye", "scolipede",
"scrafty", "seaking", "sealeo", "silcoon", "simisear",
"snivy", "snorlax", "spoink", "starly", "tirtouga",
"trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
"wailord", "wartortle", "whismur", "wingull", "yamask"
)
 
fun search(part: Array<String>, offset: Int) {
if (offset > maxPathLength) {
maxPathLength = offset
maxPathLengthCount = 1
}
else if (offset == maxPathLength) {
maxPathLengthCount++
maxPathExample.setLength(0)
for (i in 0 until offset) {
maxPathExample.append(if (i % 5 == 0) "\n " else " ")
maxPathExample.append(part[i])
}
}
val lastChar = part[offset - 1].last()
for (i in offset until part.size) {
if (part[i][0] == lastChar) {
val tmp = names[offset]
names[offset] = names[i]
names[i] = tmp
search(names, offset + 1)
names[i] = names[offset]
names[offset] = tmp
}
}
}
 
fun main(args: Array<String>) {
for (i in 0 until names.size) {
val tmp = names[0]
names[0] = names[i]
names[i] = tmp
search(names, 1)
names[i] = names[0]
names[0] = tmp
}
println("Maximum path length : $maxPathLength")
println("Paths of that length : $maxPathLengthCount")
println("Example path of that length : $maxPathExample")
}</syntaxhighlight>
 
{{out}}
<pre>
Maximum path length : 23
Paths of that length : 1248
Example path of that length :
machamp pinsir rufflet trapinch heatmor
remoraid darmanitan nosepass starly yamask
kricketune exeggcute emboar relicanth haxorus
simisear registeel landorus seaking girafarig
gabite emolga audino
</pre>
=={{header|Lua}}==
In lieu of the poorly-specified extra-credit portion (e.g. are the two Nidoran's to be considered same or unique?), I chose to expand on the output portion of the core task.
<syntaxhighlight lang="lua">-- BUILDING:
pokemon = [[
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask]]
words, inits, succs = {}, {}, {}
for word in pokemon:gmatch("%S+") do
table.insert(words, word)
local ch = word:sub(1,1)
inits[ch] = inits[ch] or {}
table.insert(inits[ch], word)
end
for _,word in pairs(words) do
succs[word] = {}
local ch = word:sub(-1,-1)
if inits[ch] then
for _,succ in pairs(inits[ch]) do
if succ~=word then
table.insert(succs[word],succ)
end
end
end
end
 
-- SEARCHING:
function expand(list, used, answer)
local word = list[#list]
for _,succ in ipairs(succs[word]) do
if not used[succ] then
used[succ] = true
list[#list+1] = succ
if #list == answer.len then
local perm = table.concat(list," ")
answer.perms[perm] = perm
answer.num = answer.num + 1
elseif #list > answer.len then
answer.len = #list
local perm = table.concat(list," ")
answer.perms = {[perm] = perm}
answer.num = 1
end
expand(list, used, answer)
list[#list] = nil
used[succ] = nil
end
end
end
answers = {}
for _,word in ipairs(words) do
local answer = { word=word, len=0, num=0, perms={} }
answers[#answers+1] = answer
expand({word}, {[word]=true}, answer)
end
 
-- REPORTING:
table.sort(answers, function(a,b) return a.len<b.len or (a.len==b.len and a.word<b.word) end)
print("first word length count example")
print("---------- ------ ----- -------...")
for _,answer in pairs(answers) do
local perm = next(answer.perms) or ""
print(string.format("%10s %6d %5d %s", answer.word, answer.len, answer.num, perm))
end</syntaxhighlight>
{{out}}
<pre>first word length count example
---------- ------ ----- -------...
audino 0 0
bidoof 0 0
deino 0 0
jumpluff 0 0
pidgeotto 0 0
pikachu 0 0
porygon2 0 0
porygonz 0 0
sealeo 0 0
snorlax 0 0
treecko 0 0
vulpix 0 0
carracosta 2 1 carracosta audino
cresselia 2 1 cresselia audino
emolga 2 1 emolga audino
ledyba 2 1 ledyba audino
poochyena 2 1 poochyena audino
tirtouga 2 1 tirtouga audino
emboar 19 96 emboar relicanth heatmor rufflet trapinch haxorus simisear registeel landorus seaking girafarig gulpin nosepass scrafty yamask kricketune exeggcute emolga audino
exeggcute 19 96 exeggcute emboar relicanth haxorus seaking girafarig gulpin nosepass simisear rufflet trapinch heatmor registeel landorus snivy yamask kricketune emolga audino
nosepass 19 192 nosepass snivy yamask kricketune exeggcute emboar rufflet trapinch heatmor registeel landorus simisear relicanth haxorus seaking girafarig gabite emolga audino
bagon 20 192 bagon nosepass simisear relicanth heatmor rufflet trapinch haxorus scrafty yamask kricketune emboar registeel landorus seaking girafarig gabite exeggcute emolga audino
banette 20 192 banette exeggcute emboar relicanth heatmor registeel landorus starly yamask kangaskhan nosepass simisear rufflet trapinch haxorus seaking girafarig gabite emolga audino
charmeleon 20 192 charmeleon nosepass simisear relicanth heatmor rufflet trapinch haxorus seaking girafarig gabite emboar registeel landorus starly yamask kricketune exeggcute emolga audino
darmanitan 20 192 darmanitan nosepass seaking girafarig gabite exeggcute emboar relicanth haxorus simisear rufflet trapinch heatmor registeel landorus starly yamask kricketune emolga audino
gabite 20 96 gabite emboar rufflet trapinch heatmor relicanth haxorus simisear registeel landorus seaking girafarig gulpin nosepass snivy yamask kricketune exeggcute emolga audino
girafarig 20 480 girafarig gabite emboar registeel landorus spoink kangaskhan nosepass simisear rufflet trapinch heatmor relicanth haxorus snivy yamask kricketune exeggcute emolga audino
gulpin 20 192 gulpin nosepass simisear rufflet trapinch heatmor relicanth haxorus snivy yamask kricketune emboar registeel landorus seaking girafarig gabite exeggcute emolga audino
haxorus 20 288 haxorus starly yamask kricketune exeggcute emboar registeel landorus simisear rufflet trapinch heatmor remoraid darmanitan nosepass seaking girafarig gabite emolga audino
heatmor 20 432 heatmor rufflet trapinch heatran nosepass simisear relicanth haxorus seaking girafarig gabite emboar registeel landorus starly yamask kricketune exeggcute emolga audino
heatran 20 192 heatran nosepass simisear relicanth haxorus seaking girafarig gabite exeggcute emboar rufflet trapinch heatmor registeel landorus starly yamask kricketune emolga audino
kangaskhan 20 192 kangaskhan nosepass seaking girafarig gabite exeggcute emboar relicanth haxorus simisear rufflet trapinch heatmor registeel landorus starly yamask kricketune emolga audino
kricketune 20 96 kricketune exeggcute emboar relicanth heatmor rufflet trapinch haxorus simisear registeel landorus scrafty yamask kangaskhan nosepass seaking girafarig gabite emolga audino
lumineon 20 192 lumineon nosepass seaking girafarig gabite exeggcute emboar rufflet trapinch heatmor relicanth haxorus simisear registeel landorus starly yamask kricketune emolga audino
lunatone 20 192 lunatone emboar rufflet trapinch heatmor registeel landorus starly yamask kangaskhan nosepass simisear relicanth haxorus seaking girafarig gabite exeggcute emolga audino
magnezone 20 192 magnezone exeggcute emboar registeel landorus snivy yamask kangaskhan nosepass simisear relicanth heatmor rufflet trapinch haxorus seaking girafarig gabite emolga audino
mamoswine 20 192 mamoswine exeggcute emboar relicanth haxorus seaking girafarig gulpin nosepass simisear rufflet trapinch heatmor registeel landorus snivy yamask kricketune emolga audino
sableye 20 192 sableye emboar relicanth heatmor registeel landorus simisear rufflet trapinch haxorus seaking girafarig gulpin nosepass starly yamask kricketune exeggcute emolga audino
scolipede 20 192 scolipede exeggcute emboar relicanth haxorus seaking girafarig gulpin nosepass simisear rufflet trapinch heatmor registeel landorus snivy yamask kricketune emolga audino
silcoon 20 192 silcoon nosepass simisear rufflet trapinch haxorus scrafty yamask kricketune exeggcute emboar relicanth heatmor registeel landorus seaking girafarig gabite emolga audino
trapinch 20 576 trapinch heatmor registeel landorus simisear remoraid darmanitan nosepass scrafty yamask kricketune exeggcute emboar relicanth haxorus seaking girafarig gabite emolga audino
tyrogue 20 192 tyrogue emboar rufflet trapinch heatmor registeel landorus seaking girafarig gulpin nosepass simisear relicanth haxorus snivy yamask kricketune exeggcute emolga audino
wartortle 20 192 wartortle exeggcute emboar registeel landorus snivy yamask kangaskhan nosepass simisear relicanth heatmor rufflet trapinch haxorus seaking girafarig gabite emolga audino
yamask 20 96 yamask kangaskhan nosepass seaking girafarig gabite emboar rufflet trapinch heatmor registeel landorus simisear relicanth haxorus spoink kricketune exeggcute emolga audino
baltoy 21 96 baltoy yamask kangaskhan nosepass simisear rufflet trapinch heatmor relicanth haxorus seaking girafarig gabite exeggcute emboar registeel landorus spoink kricketune emolga audino
braviary 21 96 braviary yamask kangaskhan nosepass seaking girafarig gabite exeggcute emboar relicanth haxorus simisear rufflet trapinch heatmor registeel landorus spoink kricketune emolga audino
croagunk 21 288 croagunk kangaskhan nosepass seaking girafarig gabite emboar rufflet trapinch heatmor registeel landorus simisear relicanth haxorus starly yamask kricketune exeggcute emolga audino
jellicent 21 768 jellicent trapinch haxorus seaking girafarig gabite exeggcute emboar relicanth heatmor remoraid darmanitan nosepass simisear registeel landorus snivy yamask kricketune emolga audino
landorus 21 192 landorus seaking girafarig gabite emboar relicanth heatmor rufflet trapinch haxorus simisear registeel loudred darmanitan nosepass starly yamask kricketune exeggcute emolga audino
loudred 21 192 loudred darmanitan nosepass seaking girafarig gabite exeggcute emboar rufflet trapinch haxorus simisear relicanth heatmor registeel landorus snivy yamask kricketune emolga audino
poliwrath 21 912 poliwrath heatmor remoraid darmanitan nosepass simisear registeel landorus seaking girafarig gabite exeggcute emboar rufflet trapinch haxorus scrafty yamask kricketune emolga audino
registeel 21 192 registeel landorus simisear rufflet trapinch heatmor remoraid darmanitan nosepass seaking girafarig gabite exeggcute emboar relicanth haxorus starly yamask kricketune emolga audino
relicanth 21 240 relicanth heatmor rufflet trapinch haxorus simisear registeel landorus seaking girafarig gabite exeggcute emboar remoraid darmanitan nosepass starly yamask kricketune emolga audino
remoraid 21 192 remoraid darmanitan nosepass simisear relicanth heatmor registeel landorus scrafty yamask kricketune exeggcute emboar rufflet trapinch haxorus seaking girafarig gabite emolga audino
rufflet 21 240 rufflet trapinch heatmor remoraid darmanitan nosepass seaking girafarig gabite emboar registeel landorus simisear relicanth haxorus starly yamask kricketune exeggcute emolga audino
scrafty 21 96 scrafty yamask kricketune exeggcute emboar rufflet trapinch heatmor relicanth haxorus spoink kangaskhan nosepass simisear registeel landorus seaking girafarig gabite emolga audino
seaking 21 192 seaking girafarig gabite emboar rufflet trapinch heatmor relicanth haxorus simisear registeel landorus snivy yamask kangaskhan nosepass spoink kricketune exeggcute emolga audino
simisear 21 384 simisear rufflet trapinch haxorus spoink kricketune exeggcute emboar relicanth heatmor registeel landorus snivy yamask kangaskhan nosepass seaking girafarig gabite emolga audino
snivy 21 96 snivy yamask kricketune exeggcute emboar registeel landorus simisear rufflet trapinch heatmor relicanth haxorus spoink kangaskhan nosepass seaking girafarig gabite emolga audino
spoink 21 288 spoink kangaskhan nosepass snivy yamask kricketune emboar relicanth heatmor rufflet trapinch haxorus simisear registeel landorus seaking girafarig gabite exeggcute emolga audino
starly 21 96 starly yamask kangaskhan nosepass simisear rufflet trapinch heatmor relicanth haxorus seaking girafarig gabite exeggcute emboar registeel landorus spoink kricketune emolga audino
vigoroth 21 912 vigoroth haxorus simisear registeel landorus starly yamask kricketune exeggcute emboar rufflet trapinch heatmor remoraid darmanitan nosepass seaking girafarig gabite emolga audino
wailord 21 192 wailord darmanitan nosepass seaking girafarig gabite exeggcute emboar rufflet trapinch haxorus simisear relicanth heatmor registeel landorus snivy yamask kricketune emolga audino
bronzor 22 864 bronzor registeel landorus seaking girafarig gabite emboar rufflet trapinch heatmor remoraid darmanitan nosepass simisear relicanth haxorus snivy yamask kricketune exeggcute emolga audino
ivysaur 22 864 ivysaur registeel landorus seaking girafarig gabite emboar rufflet trapinch heatmor remoraid darmanitan nosepass simisear relicanth haxorus snivy yamask kricketune exeggcute emolga audino
petilil 22 384 petilil landorus simisear rufflet trapinch heatmor relicanth haxorus starly yamask kricketune exeggcute emboar registeel loudred darmanitan nosepass seaking girafarig gabite emolga audino
pinsir 22 864 pinsir rufflet trapinch heatmor registeel landorus seaking girafarig gabite exeggcute emboar relicanth haxorus simisear remoraid darmanitan nosepass snivy yamask kricketune emolga audino
whismur 22 864 whismur registeel landorus seaking girafarig gabite emboar rufflet trapinch heatmor remoraid darmanitan nosepass simisear relicanth haxorus snivy yamask kricketune exeggcute emolga audino
wingull 22 384 wingull landorus snivy yamask kricketune emboar rufflet trapinch haxorus simisear relicanth heatmor registeel loudred darmanitan nosepass seaking girafarig gabite exeggcute emolga audino
machamp 23 1248 machamp petilil landorus simisear relicanth haxorus starly yamask kricketune exeggcute emboar rufflet trapinch heatmor registeel loudred darmanitan nosepass seaking girafarig gabite emolga audino</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">longestChain[list_] :=
NestWhileList[
Append @@@
Select[DeleteDuplicatesBy[
Tuples[{#, list}], {#[[1, 1]], #[[2]]} &], ! MemberQ @@ # &&
StringTake[#[[1, -1]], -1] == StringTake[#[[2]], 1] &] &,
List /@ list, # != {} &][[-2, 1]];
Print[longestChain[{"audino", "bagon", "baltoy", "banette", "bidoof",
"braviary", "bronzor", "carracosta", "charmeleon", "cresselia",
"croagunk", "darmanitan", "deino", "emboar", "emolga",
"exeggcute", "gabite", "girafarig", "gulpin", "haxorus",
"heatmor", "heatran", "ivysaur", "jellicent", "jumpluff",
"kangaskhan", "kricketune", "landorus", "ledyba", "loudred",
"lumineon", "lunatone", "machamp", "magnezone", "mamoswine",
"nosepass", "petilil", "pidgeotto", "pikachu", "pinsir",
"poliwrath", "poochyena", "porygon2", "porygonz", "registeel",
"relicanth", "remoraid", "rufflet", "sableye", "scolipede",
"scrafty", "seaking", "sealeo", "silcoon", "simisear", "snivy",
"snorlax", "spoink", "starly", "tirtouga", "trapinch", "treecko",
"tyrogue", "vigoroth", "vulpix", "wailord", "wartortle",
"whismur", "wingull", "yamask"}]];</syntaxhighlight>
Uses the tactic of only checking chains with the same starting and ending values.
{{out}}
<pre>{baltoy, yamask, kangaskhan, nosepass, sableye, emboar, registeel, landorus, scolipede, emolga, audino}</pre>
 
=={{header|Nim}}==
Using bit sets of indexes. The program runs in 0.5s.
<syntaxhighlight lang="nim">import tables
 
const Names = ["audino", "bagon", "baltoy", "banette", "bidoof", "braviary", "bronzor",
"carracosta", "charmeleon", "cresselia", "croagunk", "darmanitan", "deino",
"emboar", "emolga", "exeggcute", "gabite", "girafarig", "gulpin", "haxorus",
"heatmor", "heatran", "ivysaur", "jellicent", "jumpluff", "kangaskhan",
"kricketune", "landorus", "ledyba", "loudred", "lumineon", "lunatone",
"machamp", "magnezone", "mamoswine", "nosepass", "petilil", "pidgeotto",
"pikachu", "pinsir", "poliwrath", "poochyena", "porygon2", "porygonz",
"registeel", "relicanth", "remoraid", "rufflet", "sableye", "scolipede",
"scrafty", "seaking", "sealeo", "silcoon", "simisear", "snivy", "snorlax",
"spoink", "starly", "tirtouga", "trapinch", "treecko", "tyrogue", "vigoroth",
"vulpix", "wailord", "wartortle", "whismur", "wingull", "yamask"]
 
type
Index = range[0..Names.len-1]
IndexSet = set[Index]
Successors = Table[Index, IndexSet]
 
const All = {Index.low..Index.high} # All indexes.
 
 
func initSuccessors(): Successors {.compileTime.} =
## Build the mapping from name indexes to set of possible successor indexes.
 
var names: Table[char, IndexSet] # Map first char to IndexSet.
for idx, name in Names:
names.mgetOrPut(name[0], {}).incl(idx)
for idx, name in Names:
result[idx] = names.getOrDefault(name[^1]) - {idx}
 
# Mapping name index -> set of successor indexes.
const Succ = initSuccessors()
 
 
proc search(starts, available: IndexSet): seq[Index] =
## Search one of the longest sequence of indexes for given
## starting indexes and given available name indexes.
var maxLen = -1
for idx in starts * available:
let list = search(Succ[idx], available - {idx})
if list.len > maxLen:
result = idx & list
maxLen = list.len
 
 
let list = search(starts = All, available = All)
echo "Longest lists have length: ", list.len
echo "One of these lists is:"
for idx in list: echo Names[idx]</syntaxhighlight>
 
{{out}}
<pre>Longest lists have length: 23
One of these lists is:
machamp
petilil
landorus
scrafty
yamask
kricketune
emboar
registeel
loudred
darmanitan
nosepass
simisear
relicanth
heatmor
rufflet
trapinch
haxorus
seaking
girafarig
gabite
exeggcute
emolga
audino</pre>
 
=={{header|ooRexx}}==
<syntaxhighlight lang="oorexx">
-- create the searcher and run it
searcher = .chainsearcher~new
 
::class chainsearcher
::method init
expose max searchsize currentlongest
 
pokemon_names = "audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon" -
"cresselia croagunk darmanitan deino emboar emolga exeggcute gabite" -
"girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan" -
"kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine" -
"nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2" -
"porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking" -
"sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko" -
"tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask"
 
pokemon = pokemon_names~makearray(" ")
searchsize = pokemon~items
currentlongest = 0
say "searching" searchsize "names..."
longestchain = .array~new
-- run the sequence using each possible starting pokemon
loop i = 1 to pokemon~items
-- swap the ith name to the front of our list
self~swap(pokemon, 1, i)
-- run the chain from here
self~searchChain(pokemon, longestchain, 2)
-- swap the name back so we have the list in original form
self~swap(pokemon, 1, i)
end
say "maximum path length:" longestchain~items
say "paths of that length:" max
say "example path of that length:"
 
loop name over longestchain
say " "name
end
 
::method swap
use arg list, a, b
tmp = list[a]
list[a] = list[b]
list[b] = tmp
 
-- recursive search routine for adding to the chain
::method searchChain
expose max searchsize currentlongest
use arg pokemon, longestchain, currentchain
 
-- get the last character
lastchar = pokemon[currentchain - 1]~right(1)
-- now we search through all of the permutations of remaining
-- matches to see if we can find a longer chain
loop i = currentchain to searchsize
-- for every candidate name from here, recursively extend the chain.
if pokemon[i]~left(1) == lastchar then do
if currentchain == currentLongest then max += 1
-- have we now gone deeper than the current longest chain?
else if currentchain > currentLongest then do
-- chuck this result and refill with current set
longestchain~empty
longestchain~appendall(pokemon~section(1, currentchain - 1))
longestchain~append(pokemon[i])
max = 1
currentLongest = currentchain
end
-- perform the swap again
self~swap(pokemon, currentchain, i)
-- run the chain from here
self~searchChain(pokemon, longestchain, currentchain + 1)
-- swap the name back so we have the list in original form
self~swap(pokemon, currentchain, i)
end
end
</syntaxhighlight>
<pre>
searching 70 names...
maximum path length: 23
paths of that length: 1248
example path of that length:
machamp
petilil
landorus
scrafty
yamask
kricketune
emboar
registeel
loudred
darmanitan
nosepass
simisear
relicanth
heatmor
rufflet
trapinch
haxorus
seaking
girafarig
gabite
exeggcute
emolga
audino
</pre>
 
=={{header|OpenEdge/Progress}}==
The following gets the job done, but the time taken (40 minutes) is somewhat worrying when compared to other language solutions. So I am not going after the brownie points just yet...
 
<langsyntaxhighlight lang="progress">DEFINE VARIABLE cpokemon AS CHARACTER INITIAL "audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon ~
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite ~
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan ~
Line 1,057 ⟶ 3,256:
IF lcontinue = FALSE THEN
STOP.
END.</langsyntaxhighlight>
 
Output:
Line 1,073 ⟶ 3,272:
Yes No
---------------------------</pre>
 
=={{header|Perl}}==
This is rather 'one liner' code, not to be used in production.
 
The idea is to try all possible variants recursively.
 
*First, it creates the map-like structure: first letter → array of (name + last letter).
*During the cycle it uses @w as stack;
*@m keeps the longest sequence which is copied from @w;
*to prevent the words from appearing twice, they are (temporarily) deleted from the structure keeping the value in a stack variable.
<syntaxhighlight lang="perl">use strict;
my(%f,@m);
 
/^(.).*(.)$/,$f{$1}{$_}=$2 for qw(
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask
);
 
sub poke {
our @w;
my $h = $f{$_[0]};
for my $word (keys %$h) {
my $v = $h->{$word};
delete $h->{$word};
push @w, $word;
@m = @w if @w > @m;
poke($v);
pop @w;
$h->{$word} = $v;
}
}
 
poke($_) for keys %f;
print @m.": @m\n";</syntaxhighlight>
{{out}}
<pre>23: machamp petilil landorus seaking girafarig gabite emboar registeel loudred darmanitan nosepass simisear relicanth heatmor rufflet trapinch haxorus scrafty yamask kricketune exeggcute emolga audino</pre>
 
=={{header|Phix}}==
Using simple start-with-same-letter word chains to minimise the number of elements we have to consider:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">words</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"audino"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"bagon"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"baltoy"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"banette"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"bidoof"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"braviary"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"bronzor"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"carracosta"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"charmeleon"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"cresselia"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"croagunk"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"darmanitan"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"deino"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"emboar"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"emolga"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"exeggcute"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"gabite"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"girafarig"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"gulpin"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"haxorus"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"heatmor"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"heatran"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"ivysaur"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"jellicent"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"jumpluff"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"kangaskhan"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"kricketune"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"landorus"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"ledyba"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"loudred"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"lumineon"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"lunatone"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"machamp"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"magnezone"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"mamoswine"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"nosepass"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"petilil"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"pidgeotto"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"pikachu"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"pinsir"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"poliwrath"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"poochyena"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"porygon2"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"porygonz"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"registeel"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"relicanth"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"remoraid"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"rufflet"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"sableye"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"scolipede"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"scrafty"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"seaking"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"sealeo"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"silcoon"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"simisear"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"snivy"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"snorlax"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"spoink"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"starly"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"tirtouga"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"trapinch"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"treecko"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"tyrogue"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"vigoroth"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"vulpix"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"wailord"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"wartortle"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"whismur"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"wingull"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"yamask"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">word_chains</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">first</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">256</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- start of chains for a given letter
-- first['a']=1, first['b']=2, first['c']=8, etc.</span>
<span style="color: #000000;">snext</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- chains of words starting with the same letter
-- a: snext[1]=0, b: snext[2..7]={3,4,5,6,7,0}, etc.</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">first</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">first</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">ch</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">snext</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">j</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">first</span><span style="color: #0000FF;">,</span><span style="color: #000000;">snext</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">first</span><span style="color: #0000FF;">,</span><span style="color: #000000;">snext</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">word_chains</span><span style="color: #0000FF;">()</span>
<span style="color: #000080;font-style:italic;">-- maintain words already taken as a linked list:</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">tstart</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">taken</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- 0=no, -1=end of chain, +ve=next
-- and keep a copy of the best for later</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">bstart</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">best</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">maxn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">count</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">find_path</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">last</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">next</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">first</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">next</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">taken</span><span style="color: #0000FF;">[</span><span style="color: #000000;">next</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">taken</span><span style="color: #0000FF;">[</span><span style="color: #000000;">last</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">next</span>
<span style="color: #000000;">taken</span><span style="color: #0000FF;">[</span><span style="color: #000000;">next</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
<span style="color: #000000;">find_path</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">next</span><span style="color: #0000FF;">][$],</span><span style="color: #000000;">next</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">taken</span><span style="color: #0000FF;">[</span><span style="color: #000000;">last</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
<span style="color: #000000;">taken</span><span style="color: #0000FF;">[</span><span style="color: #000000;">next</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">next</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">snext</span><span style="color: #0000FF;">[</span><span style="color: #000000;">next</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #000000;">maxn</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">bstart</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tstart</span>
<span style="color: #000000;">best</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">taken</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">maxn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">n</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">elsif</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">maxn</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">tstart</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #000000;">taken</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span>
<span style="color: #000000;">find_path</span><span style="color: #0000FF;">(</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][$],</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">taken</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</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;">"Runtime: %2.3f seconds. Max length:%d, found %d of such, one of which is:\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">maxn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">count</span><span style="color: #0000FF;">})</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">bstart</span><span style="color: #0000FF;">!=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">words</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bstart</span><span style="color: #0000FF;">])</span>
<span style="color: #000000;">bstart</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">best</span><span style="color: #0000FF;">[</span><span style="color: #000000;">bstart</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">maxn</span><span style="color: #0000FF;">)</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: #7060A8;">join_by</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">))</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Runtime: 0.625 seconds. Max length:23, found 1248 of such, one of which is:
machamp petilil landorus scrafty yamask kricketune emboar registeel loudred darmanitan
nosepass simisear relicanth heatmor rufflet trapinch haxorus seaking girafarig gabite
exeggcute emolga audino
</pre>
My claim for the extra brownie points, using the list from the Racket entry:
<pre>
Runtime: 0.000 seconds. Max length:2, found 9 of such, one of which is:
Porygon-Z Zubat
</pre>
Which is quite correct: 9 names begin with 'Z', and plenty with 'T' but none with 't' ;-)<br>
Adding a couple of upper(), it found a 302 in a couple of minutes but was still on permutations starting
with word[1] when I got bored and killed it, quickly calculating at the very least another 4.5 days and
quite probably not finishing within my lifetime...
 
=={{header|Picat}}==
It's a little faster with the words sorted on decreasing lengths (<code>words2</code>): 9.43s vs 11.742s.
<syntaxhighlight lang="picat">go =>
words(Words),
% Words that starts with same letter as <this words>'s last letter.
Starts = new_map(),
foreach(Word in Words)
S = [ Word2 : Word2 in Words, Word != Word2, Word.last() = Word2.first()],
Starts.put(Word,S)
end,
% Sort the words according to lengths in decreasing order.
Words2 = [W : W=_ in Starts.map_to_list().qsort(sort_len)],
 
% Start the search
MaxLen = _,
Continue := true,
foreach(Len in 2..Words.len, break(Continue == false))
if play1(Words2,Starts,Len,_List) then
MaxLen := Len
else
Continue := false
end
end,
println(maxLen=MaxLen),
% And present the result.
println("\nGet some (5) solutions:"),
get_some_solutions(Words2, Starts, MaxLen,5),
 
println("\nNnumber of optimal solutions:"),
NumSols = count_all(play1(Words2,Starts,MaxLen,_List)),
println(num_sols=NumSols),
nl.
 
 
% Check if it's possible to create a list of length Len.
play1(Words, Starts, Len, LLFL) :-
LLFL1 = new_list(Len),
select(LLFL1[1], Words, Rest),
C = 2,
while (C <= Len)
Among = Starts.get(LLFL1[C-1]),
Among != [],
select(Word,Among,Rest2),
not membchk(Word,LLFL1[1..C-1]),
LLFL1[C] := Word,
Rest := Rest2,
C := C + 1
end,
LLFL = LLFL1.
 
 
% Print NumSols solutions
get_some_solutions(Words,Starts,FoundLen,NumSols) =>
Map = get_global_map(),
Map.put(count,1),
play1(Words, Starts, FoundLen, LLFL),
println(LLFL),
C = Map.get(count),
if C < NumSols then Map.put(count,C+1), fail end.
 
 
% qsort(List, SortFunction)
% returns a sorted list according to the sort function SortFunction.
qsort([],_F) = [].
qsort([H|T],F) = qsort([E : E in T, call(F,E,H)], F)
++ [H] ++
qsort([E : E in T, not call(F,E,H)],F).
 
% Sort according to length
sort_len((_K1=V1),(_K2=V2)) :-
V1.len >= V2.len.
 
words(Words) =>
Words =
[
"audino", "bagon", "baltoy", "banette", "bidoof", "braviary", "bronzor", "carracosta", "charmeleon",
"cresselia", "croagunk", "darmanitan", "deino", "emboar", "emolga", "exeggcute", "gabite",
"girafarig", "gulpin", "haxorus", "heatmor", "heatran", "ivysaur", "jellicent", "jumpluff", "kangaskhan",
"kricketune", "landorus", "ledyba", "loudred", "lumineon", "lunatone", "machamp", "magnezone", "mamoswine",
"nosepass", "petilil", "pidgeotto", "pikachu", "pinsir", "poliwrath", "poochyena", "porygon2",
"porygonz", "registeel", "relicanth", "remoraid", "rufflet", "sableye", "scolipede", "scrafty", "seaking",
"sealeo", "silcoon", "simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga", "trapinch", "treecko",
"tyrogue", "vigoroth", "vulpix", "wailord", "wartortle", "whismur", "wingull", "yamask"
].</syntaxhighlight>
 
 
{{out}}
<pre>maxLen = 23
 
Get some (5) solutions:
[machamp,petilil,landorus,scrafty,yamask,kricketune,emboar,registeel,loudred,darmanitan,nosepass,simisear,relicanth,heatmor,rufflet,trapinch,haxorus,seaking,girafarig,gabite,exeggcute,emolga,audino]
[machamp,petilil,landorus,scrafty,yamask,kricketune,emboar,registeel,loudred,darmanitan,nosepass,simisear,rufflet,trapinch,heatmor,relicanth,haxorus,seaking,girafarig,gabite,exeggcute,emolga,audino]
[machamp,petilil,landorus,scrafty,yamask,kricketune,emboar,relicanth,haxorus,simisear,rufflet,trapinch,heatmor,registeel,loudred,darmanitan,nosepass,seaking,girafarig,gabite,exeggcute,emolga,audino]
[machamp,petilil,landorus,scrafty,yamask,kricketune,emboar,relicanth,heatmor,registeel,loudred,darmanitan,nosepass,simisear,rufflet,trapinch,haxorus,seaking,girafarig,gabite,exeggcute,emolga,audino]
[machamp,petilil,landorus,scrafty,yamask,kricketune,emboar,relicanth,heatmor,rufflet,trapinch,haxorus,simisear,registeel,loudred,darmanitan,nosepass,seaking,girafarig,gabite,exeggcute,emolga,audino]
 
Nnumber of optimal solutions:
num_sols = 1248</pre>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de pokemonChain (File)
(let Names (make (in File (while (read) (link @))))
(for Name Names
Line 1,089 ⟶ 3,532:
(setq Res Lst) )
(mapc recurse (val Name) (circ Lst)) ) ) ) )
(flip Res) ) ) )</langsyntaxhighlight>
Test:
<pre>
Line 1,098 ⟶ 3,541:
: (length @)
-> 23
</pre>
 
=={{header|Prolog}}==
Works with SWI-Prolog and module '''lambda.pl''' written by '''Ulrich Neumerkel''' found there http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl
<syntaxhighlight lang="prolog">:- use_module(library(lambda)).
 
:- dynamic res/3.
 
last_first(Len, Nb, L) :-
retractall(res(_,_,_)),
assert(res(0, 0, [])),
% compute all the lists of connected words
last_first,
res(Len, Nb, L1),
% to have only the words
maplist(\X^Y^(X = [Y, _, _]), L1, L).
 
% create the lists of connected words (initiate the first word)
last_first :-
init(L),
forall(select(Word, L, L1),
\+lance_p([Word | L1])).
 
% compute all the lists beginning with a word
% memorize the longest
lance_p(L) :-
p(LF, L),
retract(res(Len, Nb, Lst)),
length(LF, Len1),
( Len1 > Len
-> assert(res(Len1, 1, LF))
; Len1 = Len
-> Nb1 is Nb + 1,
assert(res(Len, Nb1, Lst))
; assert(res(Len, Nb, Lst))),
fail.
 
% describe the property of the list of connected words
p([A | T], [A | L]) :-
select(B, L, L1),
p0(A,B),
T = [B | T1],
p([B | T1], [B | L1]).
 
% a list with one element is valid
p([_], _).
 
 
% are words conected ?
p0([_, _, W], [_, W, _]).
 
% each word is associated with its first and last letters
% audino --> [audino, a, o]
init(L) :-
 
L0 = [ audino, bagon, baltoy, banette, bidoof, braviary, bronzor,
carracosta, charmeleon, cresselia, croagunk, darmanitan, deino,
emboar, emolga, exeggcute, gabite, girafarig, gulpin, haxorus,
heatmor, heatran, ivysaur, jellicent, jumpluff, kangaskhan,
kricketune, landorus, ledyba, loudred, lumineon, lunatone,
machamp, magnezone, mamoswine, nosepass, petilil, pidgeotto,
pikachu, pinsir, poliwrath, poochyena, porygon2, porygonz,
registeel, relicanth, remoraid, rufflet, sableye, scolipede,
scrafty, seaking, sealeo, silcoon, simisear, snivy, snorlax,
spoink, starly, tirtouga, trapinch, treecko, tyrogue, vigoroth,
vulpix, wailord, wartortle, whismur, wingull, yamask],
maplist(init_, L0, L).
 
% audino --> [audino, a, o]
init_(W, [W, F, L]) :-
first_letter(W, F),
last_letter(W, L).
 
 
first_letter(A, F) :-
atom_chars(A, [F | _]).
 
last_letter(A, L) :-
atom_chars(A, LC),
reverse(LC, [L | _]).
</syntaxhighlight>
Output :
<pre>?- time(last_first(Len, Nb, L)).
% 592,161,339 inferences, 125.690 CPU in 128.264 seconds (98% CPU, 4711284 Lips)
Len = 23,
Nb = 1248,
L = [machamp,petilil,landorus,scrafty,yamask,kricketune,emboar,registeel,loudred,darmanitan,nosepass,simisear,relicanth,heatmor,rufflet,trapinch,haxorus,seaking,girafarig,gabite,exeggcute,emolga,audino].
</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">from collections import defaultdict
 
def order_words(words):
Line 1,147 ⟶ 3,677:
l = llfl(pokemon)
for i in range(0, len(l), 8): print(' '.join(l[i:i+8]))
print(len(l))</langsyntaxhighlight>
 
;Sample output
<pre>machamp pinsir relicanth heatmor remoraid darmanitan nosepass snivy
<pre>audino bagon baltoy banette bidoof braviary bronzor carracosta
yamask kricketune exeggcute emboar registeel landorus simisear rufflet
charmeleon cresselia croagunk darmanitan deino emboar emolga exeggcute
trapinch haxorus seaking girafarig gabite emolga audino
gabite girafarig gulpin haxorus heatmor heatran ivysaur jellicent
23</pre>
===Alternative version===
Adapted from the D version. This uses Psyco.
<langsyntaxhighlight lang="python">import psyco
 
nsolutions = 0
Line 1,230 ⟶ 3,760:
 
psyco.full()
main()</langsyntaxhighlight>
Output:
<pre>Maximum path length: 23
Line 1,240 ⟶ 3,770:
emolga audino</pre>
Run time: about 0.44 seconds with Psyco and Python 2.6.6.
 
=={{header|Racket}}==
This is a naive solution, which works fast enough as is (takes about 5 seconds on an old machine):
<syntaxhighlight lang="racket">#lang racket
 
(define names "
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite girafarig
gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone
mamoswine nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena
porygon2 porygonz registeel relicanth remoraid rufflet sableye scolipede
scrafty seaking sealeo silcoon simisear snivy snorlax spoink starly tirtouga
trapinch treecko tyrogue vigoroth vulpix wailord wartortle whismur wingull
yamask")
 
(struct word (first last string) #:prefab)
(define words
(for/list ([str (string-split names)])
(word (string->symbol (substring str 0 1))
(string->symbol (substring str (sub1 (string-length str))))
str)))
 
(define (find-longest last words)
(for/fold ([best '()])
([w (in-list words)]
#:when (or (not last) (eq? last (word-first w))))
(define long (cons w (find-longest (word-last w) (remq w words))))
(if (> (length long) (length best)) long best)))
 
(define longest (find-longest #f words))
(printf "Longest chain found has ~a words:\n ~a\n"
(length longest) (string-join (map word-string longest) " -> "))
</syntaxhighlight>
{{out}}
<pre>
Longest chain found has 23 words:
machamp -> petilil -> landorus -> scrafty -> yamask -> kricketune -> emboar -> registeel -> loudred -> darmanitan -> nosepass -> simisear -> relicanth -> heatmor -> rufflet -> trapinch -> haxorus -> seaking -> girafarig -> gabite -> exeggcute -> emolga -> audino
</pre>
 
This is a (probably over-)complex version which tries to construct longest
chains using three different combination/relinking functions. Not that the
definiton of `word` is slightly different here.
<syntaxhighlight lang="racket">#lang racket
(require "pokemon-names.rkt")
 
;;; Some fundamentals... finding the first (henceforth referred to as "a") and last ("z")
;;; letters of a word can be computationally intensive... look at symbol->word, and you'll
;;; see that when we have to deal with a name like: "Mime Jr.", the last alphabetic letter
;;; is not the last character. And the first and last characters (at least) have to be
;;; case-normalised so they can be compared with char=? (it's not particulary helpful to
;;; map them down to integer character codes; we'll want to see them for debugging).
(define-struct word (sym char-a char-z) #:prefab)
 
;;; names are input as symbols both for ease of comparsion, and because it's easier to type
(define (symbol->word sym)
(let* ((str (symbol->string sym))
(chrs (string->list str))
(fst (for/first ((c chrs) #:when (char-alphabetic? c)) (char-downcase c)))
(lst (for/last ((c chrs) #:when (char-alphabetic? c)) (char-downcase c))))
(make-word sym fst lst)))
 
;;; We're sometimes not interested in debugging a chain of; just in knowing how long it is
;;; and what its extreme characters are. This does the trick.
(define (summarise-chain c)
(format "(~a.~a.~a)" (word-char-a (first c)) (sub1 (length c)) (word-char-z (last c))))
 
;; Test the above (run `raco test last_letter-first_letter-common.rkt`)
(define-syntax-rule (hash-set-or-remove hsh key val remove-pred?)
(let ((v val))
(if (remove-pred? v)
(hash-remove hsh key)
(hash-set hsh key v))))
 
(define-syntax-rule (find-a-in-chain-pool chains a dont-match-sym)
(for/first ((c chains)
(i (in-naturals)) ;; usually need an index for regenerating chains pool
;; a word can only exist in one chain, so this compares chains' identities
#:unless (eq? (word-sym (first c)) dont-match-sym)
#:when (char=? (word-char-a (first c)) a))
(cons i c)))
 
(define-syntax-rule (copy-list-ignoring-indices lst i1 i2)
(for/list ((idx (in-naturals))
(e (in-list lst))
#:unless (= idx i1)
#:unless (= idx i2))
e))
 
;; Simple ... find a chain that can be put on the end of c... append it, and
;; reiterate
(define (append-ab..bz-chains chain chain-idx chains)
(let* ((a1.chain-a (find-a-in-chain-pool chains (word-char-z (last chain)) (word-sym (first chain)))))
(and a1.chain-a
(let ((a1.chain-idx (first a1.chain-a))
(a1.chain-chain (rest a1.chain-a)))
(cons (append chain a1.chain-chain)
(copy-list-ignoring-indices chains chain-idx a1.chain-idx))))))
 
;; If chain has an a..a loop in it, then we see if we can take that loop, and
;; place it in a longer chain at a point where a is used.
;;
;; `chain` is the shorter chain containing the loop
(define (merge-chain-into-chain-accepting-a..a-in-chain chain chain-idx chains)
;; for a..a loops in chain, returns a hash from the looped char, to the longest
;; found loop
(define (find-a..a-loops chain)
(let ((chain-length (length chain)))
(for*/fold
((hsh (hash)))
((sub-range-start (in-range chain-length))
(aa (in-value (word-char-a (list-ref chain sub-range-start))))
(sub-range-end (in-range sub-range-start chain-length))
#:when (eq? aa (word-char-z (list-ref chain sub-range-end)))
(range-length (in-value (add1 (- sub-range-end sub-range-start)))))
(hash-update
hsh aa
(lambda (longest-range)
(if (and longest-range (> (third longest-range) range-length))
longest-range
(list sub-range-start sub-range-end range-length)))
#f))))
(let* ((chain-first-name (word-sym (first chain)))
(chain-length (length chain))
(a..a-list (sort (hash->list (find-a..a-loops chain)) > #:key third)))
(for*/first (((chain2 chain2-idx) (in-parallel (in-list chains) (in-naturals)))
#:unless (eq? chain-first-name (word-sym (car chain2)))
(chain2-length (in-value (length chain2)))
#:when (>= chain2-length chain-length) ; only move the largest a..a-subchain into a larger chain
(a..a (in-list a..a-list))
((insertion-point-word insertion-point-idx) (in-parallel (in-list chain2) (in-naturals)))
#:when (eq? (car a..a) (word-char-a insertion-point-word)))
(let* ((new-chain (append (take chain (second a..a)) (drop chain (add1 (third a..a)))))
(a..a-chain (take (drop chain (second a..a)) (fourth a..a)))
(new-chain2 (append (take chain2 insertion-point-idx) a..a-chain (drop chain2 insertion-point-idx))))
(let ((new-chains (copy-list-ignoring-indices chains chain-idx chain2-idx)))
(if (null? new-chain) (cons new-chain2 new-chains)
(cons new-chain (cons new-chain2 new-chains))))))))
 
;; this is a bit more combinatorially intensive... for all c2, substitute a
;; subrange in c2 that is longer than an equivalent subrange in c
(define (merge-subranges-of-chains-into-chain chain chain-idx chains)
(let ((chain-first-name (word-sym (first chain)))
(chain-length (length chain))
(chain-first-a (word-char-a (first chain)))
(chain-last-z (word-char-z (last chain))))
(for*/first ; try to replace a subrange in c2 with c
(((chain2 chain2-idx) (in-parallel (in-list chains) (in-naturals)))
(chain2-length (in-value (length chain2)))
#:unless (eq? chain-first-name (word-sym (car chain2)))
(c2-sub-range-start (in-range chain2-length))
(c2-sub-range-end (in-range c2-sub-range-start
(min chain2-length (+ c2-sub-range-start chain-length))))
#:unless (and (= c2-sub-range-start 0) (= c2-sub-range-end (sub1 chain2-length)))
#:when (or (zero? c2-sub-range-start)
(eq? (word-char-a (list-ref chain2 c2-sub-range-start))
chain-first-a))
#:when (or (= (sub1 chain2-length) c2-sub-range-end)
(eq? (word-char-z (list-ref chain2 c2-sub-range-end))
chain-last-z))
(c2-sub-range-len (in-value (add1 (- c2-sub-range-end c2-sub-range-start))))
#:when (> chain-length c2-sub-range-len)
(c2-sub-range (in-value (take (drop chain2 c2-sub-range-start) c2-sub-range-len)))
(new-c2 (in-value (append (take chain2 c2-sub-range-start)
chain
(drop chain2 (add1 c2-sub-range-end))))))
(cons c2-sub-range ; put the subrange back into the chains pool
(cons new-c2 ; put the modified onto the chains pool
(copy-list-ignoring-indices chains chain-idx chain2-idx))))))
 
(define (longest-chain/constructive names #:known-max (known-max +inf.0))
(define names-list (map symbol->word names))
(define (link-chains chains)
(let
((new-chains
(for*/first
(((chain chain-idx) (in-parallel (in-list chains) (in-naturals)))
(new-chains
(in-value
(or
(append-ab..bz-chains chain chain-idx chains)
(merge-chain-into-chain-accepting-a..a-in-chain chain chain-idx chains)
(merge-subranges-of-chains-into-chain chain chain-idx chains))))
#:when new-chains)
new-chains)))
(if new-chains (link-chains new-chains) chains)))
(define (keep-trying
(run-count 0)
(linked-chains (link-chains (map list (shuffle names-list))))
(previous-best null)
(previous-best-length 0)
(this-run-best-length #f))
(let* ((longest-chain (argmax length linked-chains))
(longest-chain-len (length longest-chain))
(new-best? (< previous-best-length longest-chain-len))
(best-length (if new-best? longest-chain-len previous-best-length))
(best (if new-best? longest-chain previous-best)))
(when new-best? (newline)
(displayln (list (map word-sym longest-chain) longest-chain-len))
(flush-output))
(if (and new-best? (>= best-length known-max))
(displayln "terminating: known max reached or exceeded")
(begin
(when (zero? (modulo (add1 run-count) 250)) (eprintf ".") (flush-output (current-error-port)))
(if (= run-count 1000)
(keep-trying 0 (link-chains (map list (shuffle names-list))) best best-length 0)
(let ((sorted-linked-chains (sort linked-chains #:key length >)))
(keep-trying (if new-best? 0 (add1 run-count))
(link-chains
(cons (car sorted-linked-chains)
(map list (shuffle (apply append (cdr sorted-linked-chains))))))
best best-length
(and this-run-best-length
(if new-best? #f
(if (< this-run-best-length longest-chain-len)
(begin (eprintf ">~a" longest-chain-len)
(flush-output (current-error-port))
longest-chain-len)
this-run-best-length))))))))))
(keep-trying))
 
(time (longest-chain/constructive names-70 #:known-max 23))
(longest-chain/constructive names-646)</syntaxhighlight>
 
Run with ''racket -t last_letter-first_letter-randomised.rkt 2>&1'', to redirect standard error to
standard out.
 
{{out}}
<pre>
((machamp petilil landorus seaking girafarig gabite exeggcute emboar relicanth heatran nosepass simisear registeel loudred deino) 15)
 
((machamp petilil landorus seaking girafarig gabite exeggcute emboar relicanth haxorus snivy yamask kangaskhan nosepass simisear registeel lunatone emolga audino) 19)
 
((machamp petilil landorus seaking girafarig gabite exeggcute emboar rufflet trapinch heatmor relicanth haxorus snivy yamask kangaskhan nosepass simisear registeel lunatone emolga audino) 22)
....>10>17>19....>14>17>20>21....>15>18>21>22....>16>17>22....>15>17>18>21....>19>20....>16>18>20>22....>14>21
((machamp petilil landorus seaking girafarig gabite emboar rufflet trapinch heatmor relicanth haxorus simisear registeel loudred darmanitan nosepass starly yamask kricketune exeggcute emolga audino) 23)
terminating: known max reached or exceeded
cpu time: 24077 real time: 24070 gc time: 36</pre>
As an aside... I've had this take 40 s; and I've had it run in 35 ms. It really is the luck of the draw!
</pre>
((Jellicent Tangrowth Hippopotas Slowking Gyarados Spiritomb Breloom Mandibuzz Zweilous Shellos Stoutland Deoxys Swoobat Togekiss Seedot Toxicroak Krokorok Kabutops Seadra Anorith Heracross Slakoth Haxorus Shelmet Tauros Skiploom Manectric Castform Milotic Chingling Golem Mothim Meganium Metapod Ducklett Tornadus Swellow Whismur Rufflet Taillow Wormadam Medicham Mismagius Snubbull Latias Solosis Sandshrew Woobat Teddiursa Abomasnow Wingull Lapras Seel Lillipup Paras Sandslash Hoppip Prinplup Piplup Petilil Lickilicky Yanmega Abra Ariados Solrock Klink Kingler Relicanth Hariyama Altaria Azumarill Luvdisc Charmander Rotom Maractus Skuntank Kirlia Azelf Farfetch'd Delibird Dratini Illumise Exploud Diglett Torkoal Lampent Turtwig Girafarig Golbat Tepig Grumpig Granbull Larvesta Azurill Loudred Dialga Amoonguss Sigilyph Herdier Rampardos Seaking Golett Timburr Raichu Umbreon Noctowl Latios Sawk Kyurem Miltank Klinklang Gorebyss Slaking Gliscor Rhyhorn Nidorina Alakazam Machamp Pidgeot Trubbish Hitmontop Politoed Dewgong Gardevoir Regigigas Swampert Tympole Electrode Exeggcute Eelektrik Kingdra Accelgor Remoraid Dewott Tentacool Litwick Koffing Gigalith Hypno Octillery Yanma Arcanine Elekid Dusknoir Reshiram Mesprit Tropius Swalot Tranquill Luxray Yamask Kyogre Eevee Electivire Emolga Alomomola Ampharos Spinarak Kricketune Exeggutor Roselia Arbok Krookodile Escavalier Rayquaza Aron Ninetales Serperior Registeel Lileep Patrat Throh Hitmonlee Espeon Nidoqueen Ninjask Kakuna Axew Wigglytuff Frillish Houndour Regice Eelektross Swinub Budew Whiscash Hoothoot Torterra Aipom Mareep Poliwag Grimer Roggenrola Armaldo Omastar Rhyperior Ralts Scolipede Excadrill Luxio Oshawott Togetic Crawdaunt Torchic Cofagrigus Shroomish Houndoom Marill Larvitar Raticate Electrike Ekans Starmie Emboar Regirock Karrablast Tangela Aerodactyl Lairon Nidoran Natu Unfezant Trapinch Horsea Archen Nidoran Nosepass Staravia Ambipom Murkrow Weezing Gothita Absol Lotad Darmanitan Nincada Arceus Spheal Lilligant Tynamo Omanyte Elgyem Mew Watchog Golduck Kabuto Oddish Ho-Oh Heatran Nidoking Golurk Klang Garchomp Porygon-Z Zekrom Meowth Hippowdon Nuzleaf Feraligatr Rapidash Haunter Reuniclus Seviper Raikou Ursaring Glalie Entei Igglybuff Froslass Spearow Wailord Duskull Ludicolo Onix Xatu Unown Numel Landorus Seismitoad Deerling Grovyle Empoleon Nidorino) 283)</pre>
'''...'''
<pre>((Voltorb Beartic Croconaw Wynaut Tangrowth Hippopotas Smoochum Moltres Shuppet Thundurus Slowking Gyarados Spiritomb Breloom Mandibuzz Zweilous Shellos Stoutland Deoxys Swoobat Togekiss Seedot Toxicroak Krokorok Kabutops Snorunt Tirtouga Anorith Heracross Slakoth Haxorus Shelmet Tauros Skiploom Manectric Castform Milotic Chingling Golem Mothim Meganium Metapod Ducklett Tornadus Swellow Whismur Rufflet Taillow Wormadam Medicham Mismagius Snubbull Latias Solosis Sandshrew Woobat Teddiursa Abomasnow Wingull Lapras Seel Lillipup Paras Sandslash Hoppip Prinplup Piplup Probopass Stunfisk Krabby Yanmega Abra Ariados Solrock Klink Kingler Relicanth Hariyama Altaria Azumarill Luvdisc Chatot Tyranitar Rotom Maractus Skuntank Kirlia Azelf Farfetch'd Delibird Dratini Ivysaur Riolu Uxie Electabuzz Zapdos Sawsbuck Kyogre Exploud Diglett Torkoal Lampent Turtwig Girafarig Golbat Tepig Grumpig Granbull Larvesta Azurill Loudred Dialga Amoonguss Sigilyph Herdier Rampardos Seaking Golett Timburr Raichu Umbreon Noctowl Latios Sawk Kyurem Miltank Klinklang Gorebyss Slaking Gigalith Huntail Ledyba Aggron Nidorina Alakazam Machamp Pidgeot Trubbish Hitmontop Politoed Dewgong Gardevoir Regigigas Swampert Tentacruel Lickitung Glameow Whirlipede Electrode Exeggcute Eelektrik Kingdra Accelgor Remoraid Dewott Tentacool Litwick Koffing Gloom Marshtomp Psyduck Kadabra Articuno Octillery Yanma Arcanine Elekid Dusknoir Reshiram Mesprit Tropius Swalot Tranquill Luxray Yamask Kricketot Tyrogue Eevee Electivire Emolga Alomomola Ampharos Sentret Togepi Infernape Exeggutor Roselia Arbok Krookodile Escavalier Rayquaza Aron Ninetales Serperior Registeel Lileep Patrat Throh Honchkrow Wobbuffet Totodile Espeon Nidoqueen Ninjask Kakuna Axew Wigglytuff Frillish Houndour Regice Eelektross Swinub Budew Whiscash Hoothoot Torterra Aipom Mareep Poliwag Grimer Roggenrola Armaldo Omastar Rhyperior Ralts Surskit Tympole Excadrill Lugia Audino Oshawott Togetic Crawdaunt Torchic Cofagrigus Shroomish Houndoom Mudkip Ponyta Archeops Spinarak Kricketune Electrike Ekans Simisear Raticate Emboar Regirock Karrablast Tangela Aerodactyl Liepard Dusclops Spoink Kecleon Nidoran Natu Unfezant Trapinch Horsea Archen Nidoran Nosepass Snover Rattata Ambipom Murkrow Weezing Gothita Absol Lotad Durant Terrakion Nincada Arceus Spheal Lilligant Tynamo Omanyte Elgyem Mew Watchog Golduck Kabuto Oddish Ho-Oh Heatran Nidoking Golurk Klang Garchomp Porygon-Z Zekrom Magikarp Pawniard Deerling Gurdurr Rhydon Nuzleaf Foongus Shellder Rapidash Haunter Reuniclus Seviper Raikou Ursaring Garbodor Roserade Entei Igglybuff Froslass Spearow Wailord Duskull Ludicolo Onix Xatu Unown Numel Landorus Seismitoad Drifblim Machop Palpitoad Darkrai Illumise Empoleon Nidorino) 329)</pre>
Never terminates. The longest chain I have found (so far?) is 333 long:
<pre>((Voltorb Breloom Medicham Machop Piplup Palpitoad Deerling Golett Turtwig
Glameow Wingull Lilligant Timburr Registeel Lotad Duskull Latias Serperior
Reuniclus Spinarak Krokorok Klinklang Golem Mew Whiscash Huntail Lugia Accelgor
Rattata Aerodactyl Luvdisc Chingling Grumpig Garchomp Prinplup Petilil Loudred
Ducklett Tornadus Spearow Whimsicott Tangrowth Hoothoot Tentacruel Lampent
Togekiss Skiploom Marshtomp Patrat Thundurus Solosis Sneasel Lillipup Poliwhirl
Lapras Sandslash Honchkrow Wobbuffet Torkoal Latios Slaking Gligar Rampardos
Shellos Sentret Tropius Sigilyph Herdier Remoraid Dusclops Stoutland Drilbur
Reshiram Misdreavus Slowking Golduck Klink Koffing Gyarados Shuppet Tauros
Swellow Wynaut Torchic Castform Maractus Spiritomb Bayleef Furret Tangela
Altaria Aipom Murkrow Wigglytuff Forretress Spheal Lickitung Gigalith Heracross
Snorunt Totodile Exeggcute Electrode Ekans Solrock Klang Girafarig Gorebyss
Swalot Trapinch Ho-Oh Hitmontop Porygon-Z Zapdos Shroomish Houndour Relicanth
Hoppip Poliwrath Houndoom Mareep Poliwag Golurk Kirlia Axew Wormadam Mandibuzz
Zweilous Swinub Beldum Manectric Cherrim Moltres Staraptor Rayquaza Azurill
Lairon Nidoqueen Noctowl Leavanny Yamask Kricketune Eevee Escavalier Rufflet
Torterra Archen Ninjask Kakuna Absol Lunatone Excadrill Ludicolo Octillery
Yanma Archeops Spoink Kabuto Onix Xatu Unown Nidoran Ninetales Sawsbuck Kyurem
Magikarp Politoed Dewott Trubbish Hippopotas Seel Linoone Empoleon Nincada
Amoonguss Swoobat Teddiursa Audino Oshawott Tepig Gloom Metagross Shelmet
Tentacool Larvesta Ariados Skorupi Illumise Exploud Durant Tynamo Omastar
Roggenrola Arbok Kricketot Taillow Weezing Grimer Rhyperior Rapidash Haxorus
Skuntank Kingdra Alomomola Azelf Ferroseed Drifblim Marowak Kingler Roselia
Azumarill Lanturn Natu Ursaring Golbat Toxicroak Kecleon Numel Landorus
Samurott Togepi Infernape Electrike Electivire Electabuzz Zekrom Metang
Galvantula Arceus Seedot Tirtouga Aron Nosepass Seismitoad Dialga Articuno
Oddish Horsea Alakazam Meganium Marill Liepard Deoxys Smoochum Mudkip Probopass
Stunfisk Krookodile Elekid Delibird Dratini Igglybuff Foongus Swampert
Tyranitar Raikou Uxie Eelektross Slakoth Hariyama Abra Anorith Haunter Raichu
Umbreon Nidorina Aggron Nuzleaf Floatzel Litwick Kyogre Exeggutor Raticate
Emboar Regirock Kabutops Sandshrew Watchog Gurdurr Roserade Entei Ivysaur
Regice Emolga Abomasnow Wailord Diglett Tyrogue Espeon Nidoran Nidoking
Granbull Ledyba Arcanine Elgyem Mothim Mismagius Sawk Kadabra Ampharos Snubbull
Larvitar Riolu Unfezant Togetic Charizard Dewgong Gothita Ambipom Machamp Paras
Simisear Ralts Seaking Gliscor Rotom Milotic Cyndaquil Lileep Pawniard
Dragonair Regigigas Surskit Tranquill Ledian Nidorino Omanyte Eelektrik
Karrablast Throh Happiny Yanmega Armaldo) 333)</pre>
'''File: pokemon-names.rkt'''
<syntaxhighlight lang="racket">#lang racket
(provide names-646 names-70)
(define names-70
'(audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon cresselia croagunk darmanitan deino emboar
emolga exeggcute gabite girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan kricketune
landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine nosepass petilil pidgeotto pikachu pinsir
poliwrath poochyena porygon2 porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking sealeo
silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle
whismur wingull yamask))
; If this were true, then the 2 would be ignored, which seems a bit wrong; so wordigy the "2" -> "two"
(define Porygon2 (if #f 'Porygon2 'Porygon-two))
; note that Porygon2 is used with a comma in the list below
(define names-646
`(Bulbasaur Ivysaur Venusaur Charmander Charmeleon Charizard Squirtle Wartortle Blastoise Caterpie Metapod Butterfree
Weedle Kakuna Beedrill Pidgey Pidgeotto Pidgeot Rattata Raticate Spearow Fearow Ekans Arbok Pikachu Raichu Sandshrew
Sandslash Nidoran Nidorina Nidoqueen Nidoran Nidorino Nidoking Clefairy Clefable Vulpix Ninetales Jigglypuff
Wigglytuff Zubat Golbat Oddish Gloom Vileplume Paras Parasect Venonat Venomoth Diglett Dugtrio Meowth Persian
Psyduck Golduck Mankey Primeape Growlithe Arcanine Poliwag Poliwhirl Poliwrath Abra Kadabra Alakazam Machop Machoke
Machamp Bellsprout Weepinbell Victreebel Tentacool Tentacruel Geodude Graveler Golem Ponyta Rapidash Slowpoke
Slowbro Magnemite Magneton |Farfetch'd| Doduo Dodrio Seel Dewgong Grimer Muk Shellder Cloyster Gastly Haunter Gengar
Onix Drowzee Hypno Krabby Kingler Voltorb Electrode Exeggcute Exeggutor Cubone Marowak Hitmonlee Hitmonchan
Lickitung Koffing Weezing Rhyhorn Rhydon Chansey Tangela Kangaskhan Horsea Seadra Goldeen Seaking Staryu Starmie
|Mr. Mime| Scyther Jynx Electabuzz Magmar Pinsir Tauros Magikarp Gyarados Lapras Ditto Eevee Vaporeon Jolteon
Flareon Porygon Omanyte Omastar Kabuto Kabutops Aerodactyl Snorlax Articuno Zapdos Moltres Dratini Dragonair
Dragonite Mewtwo Mew Chikorita Bayleef Meganium Cyndaquil Quilava Typhlosion Totodile Croconaw Feraligatr Sentret
Furret Hoothoot Noctowl Ledyba Ledian Spinarak Ariados Crobat Chinchou Lanturn Pichu Cleffa Igglybuff Togepi Togetic
Natu Xatu Mareep Flaaffy Ampharos Bellossom Marill Azumarill Sudowoodo Politoed Hoppip Skiploom Jumpluff Aipom
Sunkern Sunflora Yanma Wooper Quagsire Espeon Umbreon Murkrow Slowking Misdreavus Unown Wobbuffet Girafarig Pineco
Forretress Dunsparce Gligar Steelix Snubbull Granbull Qwilfish Scizor Shuckle Heracross Sneasel Teddiursa Ursaring
Slugma Magcargo Swinub Piloswine Corsola Remoraid Octillery Delibird Mantine Skarmory Houndour Houndoom Kingdra
Phanpy Donphan ,Porygon2 Stantler Smeargle Tyrogue Hitmontop Smoochum Elekid Magby Miltank Blissey Raikou Entei
Suicune Larvitar Pupitar Tyranitar Lugia Ho-Oh Celebi Treecko Grovyle Sceptile Torchic Combusken Blaziken Mudkip
Marshtomp Swampert Poochyena Mightyena Zigzagoon Linoone Wurmple Silcoon Beautifly Cascoon Dustox Lotad Lombre
Ludicolo Seedot Nuzleaf Shiftry Taillow Swellow Wingull Pelipper Ralts Kirlia Gardevoir Surskit Masquerain Shroomish
Breloom Slakoth Vigoroth Slaking Nincada Ninjask Shedinja Whismur Loudred Exploud Makuhita Hariyama Azurill Nosepass
Skitty Delcatty Sableye Mawile Aron Lairon Aggron Meditite Medicham Electrike Manectric Plusle Minun Volbeat Illumise
Roselia Gulpin Swalot Carvanha Sharpedo Wailmer Wailord Numel Camerupt Torkoal Spoink Grumpig Spinda Trapinch Vibrava
Flygon Cacnea Cacturne Swablu Altaria Zangoose Seviper Lunatone Solrock Barboach Whiscash Corphish Crawdaunt Baltoy
Claydol Lileep Cradily Anorith Armaldo Feebas Milotic Castform Kecleon Shuppet Banette Duskull Dusclops Tropius
Chimecho Absol Wynaut Snorunt Glalie Spheal Sealeo Walrein Clamperl Huntail Gorebyss Relicanth Luvdisc Bagon Shelgon
Salamence Beldum Metang Metagross Regirock Regice Registeel Latias Latios Kyogre Groudon Rayquaza Jirachi Deoxys
Turtwig Grotle Torterra Chimchar Monferno Infernape Piplup Prinplup Empoleon Starly Staravia Staraptor Bidoof Bibarel
Kricketot Kricketune Shinx Luxio Luxray Budew Roserade Cranidos Rampardos Shieldon Bastiodon Burmy Wormadam Mothim
Combee Vespiquen Pachirisu Buizel Floatzel Cherubi Cherrim Shellos Gastrodon Ambipom Drifloon Drifblim Buneary
Lopunny Mismagius Honchkrow Glameow Purugly Chingling Stunky Skuntank Bronzor Bronzong Bonsly |Mime Jr.| Happiny
Chatot Spiritomb Gible Gabite Garchomp Munchlax Riolu Lucario Hippopotas Hippowdon Skorupi Drapion Croagunk Toxicroak
Carnivine Finneon Lumineon Mantyke Snover Abomasnow Weavile Magnezone Lickilicky Rhyperior Tangrowth Electivire
Magmortar Togekiss Yanmega Leafeon Glaceon Gliscor Mamoswine Porygon-Z Gallade Probopass Dusknoir Froslass Rotom Uxie
Mesprit Azelf Dialga Palkia Heatran Regigigas Giratina Cresselia Phione Manaphy Darkrai Shaymin Arceus Victini Snivy
Servine Serperior Tepig Pignite Emboar Oshawott Dewott Samurott Patrat Watchog Lillipup Herdier Stoutland Purrloin
Liepard Pansage Simisage Pansear Simisear Panpour Simipour Munna Musharna Pidove Tranquill Unfezant Blitzle Zebstrika
Roggenrola Boldore Gigalith Woobat Swoobat Drilbur Excadrill Audino Timburr Gurdurr Conkeldurr Tympole Palpitoad
Seismitoad Throh Sawk Sewaddle Swadloon Leavanny Venipede Whirlipede Scolipede Cottonee Whimsicott Petilil Lilligant
Basculin Sandile Krokorok Krookodile Darumaka Darmanitan Maractus Dwebble Crustle Scraggy Scrafty Sigilyph Yamask
Cofagrigus Tirtouga Carracosta Archen Archeops Trubbish Garbodor Zorua Zoroark Minccino Cinccino Gothita Gothorita
Gothitelle Solosis Duosion Reuniclus Ducklett Swanna Vanillite Vanillish Vanilluxe Deerling Sawsbuck Emolga
Karrablast Escavalier Foongus Amoonguss Frillish Jellicent Alomomola Joltik Galvantula Ferroseed Ferrothorn Klink
Klang Klinklang Tynamo Eelektrik Eelektross Elgyem Beheeyem Litwick Lampent Chandelure Axew Fraxure Haxorus Cubchoo
Beartic Cryogonal Shelmet Accelgor Stunfisk Mienfoo Mienshao Druddigon Golett Golurk Pawniard Bisharp Bouffalant
Rufflet Braviary Vullaby Mandibuzz Heatmor Durant Deino Zweilous Hydreigon Larvesta Volcarona Cobalion Terrakion
Virizion Tornadus Thundurus Reshiram Zekrom Landorus Kyurem))</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
A breadth-first search that uses disk files to avoid memory exhaustion. Each candidate sequence is encoded at one character per name, so to avoid reuse of names we merely have to make sure there are no repeat characters in our encoded string. (The encoding starts at ASCII space for the first name, so newline is not among the encoded characters.)
<syntaxhighlight lang="raku" line>my @names = <
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask
>;
 
my @last = @names.map: {.substr(*-1,1).ord }
my @succs = [] xx 128;
for @names.kv -> $i, $name {
my $ix = $name.ord; # $name.substr(0,1).ord
push @succs[$ix], $i;
}
 
my $OUT = open "llfl.new", :w orelse .die;
$OUT.print: chr($_ + 32),"\n" for 0 ..^ @names;
close $OUT;
my $new = +@names;
my $len = 1;
 
while $new {
say "Length { $len++ }: $new candidates";
shell 'mv llfl.new llfl.known';
my $IN = open "llfl.known" orelse .die;
my $OUT = open "llfl.new", :w orelse .die;
$new = 0;
 
loop {
my $cand = $IN.get // last;
for @succs[@last[$cand.ord - 32]][] -> $i {
my $ic = chr($i + 32);
next if $cand ~~ /$ic/;
$OUT.print: $ic,$cand,"\n";
$new++;
}
}
$IN.close;
$OUT.close;
}
 
my $IN = open "llfl.known" orelse .die;
my $eg = $IN.lines.pick;
say "Length of longest: ", $eg.chars;
say join ' ', $eg.ords.reverse.map: { @names[$_ - 32] }</syntaxhighlight>
{{out}}
<pre>Length 1: 70 candidates
Length 2: 172 candidates
Length 3: 494 candidates
Length 4: 1288 candidates
Length 5: 3235 candidates
Length 6: 7731 candidates
Length 7: 17628 candidates
Length 8: 37629 candidates
Length 9: 75122 candidates
Length 10: 139091 candidates
Length 11: 236679 candidates
Length 12: 367405 candidates
Length 13: 516210 candidates
Length 14: 650916 candidates
Length 15: 733915 candidates
Length 16: 727566 candidates
Length 17: 621835 candidates
Length 18: 446666 candidates
Length 19: 260862 candidates
Length 20: 119908 candidates
Length 21: 40296 candidates
Length 22: 10112 candidates
Length 23: 1248 candidates
Length of longest: 23
machamp petilil loudred darmanitan nosepass simisear rufflet trapinch heatmor registeel landorus starly yamask kricketune exeggcute emboar relicanth haxorus seaking girafarig gabite emolga audino</pre>
 
=={{header|REXX}}==
{{trans|ooRexx}}
===brute force version===
(This program is modeled after the ooRexx version, but with a fixed bug.)
<br><br>This REXX version allows a limit on the word scan (very useful for testing and debugging), and
<br>also has various speed optimizations.
<syntaxhighlight 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',
'deino emboar emolga exeggcute gabite girafarig gulpin haxorus heatmor heatran ivysaur jellicent',
'jumpluff kangaskhan kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine',
'nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2 porygonz registeel relicanth',
'remoraid rufflet sableye scolipede scrafty seaking sealeo silcoon simisear snivy snorlax spoink',
'starly tirtouga trapinch treecko tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask'
#= words(@); ig= 0; !.= 0; @.= /*nullify array and the longest path. */
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
MP= 0; MPL= 0 /*the initial Maximum Path Length. */
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; say 'One example path of that length is: ' word($$$, 1)
do m=2 to g; say left('', 36) word($$$, m)
end /**/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
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 @. */
if !.1.LC==0 then return /*is this a dead─end word? */
/* [↓] PARSE obtains first char of @.i*/
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 !==MPL then MP= MP+1 /*bump the Maximum Paths Counter. */
else if !>MPL then do; $$$=@.1 /*rebuild. */
do n=2 for !-2; $$$=$$$ @.n
end /*n*/
$$$=$$$ @.i /*add last.*/
MP=1; MPL=! /*new path.*/
end
parse value @.! @.i with @.i @.!; call scan $$$, !+1
parse value @.! @.i with @.i @.!
end
end /*i*/; return /*exhausted this particular scan. */</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<pre>
Of 70 words, 1248 paths have the maximum path length of 23.
 
One example path of that length is: machamp
petilil
landorus
scrafty
yamask
kricketune
emboar
registeel
loudred
darmanitan
nosepass
simisear
relicanth
heatmor
rufflet
trapinch
haxorus
seaking
girafarig
gabite
exeggcute
emolga
audino
</pre>
 
===optimized version===
This optimized version has two major improvements:
::* &nbsp; removes dead words (words that cannot be used in a path)
::* &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).
<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>the recursive scan is aborted and the the next word is scanned.
<br><br>The optimized version is around &nbsp; '''25%''' &nbsp; faster than the brute-force version.
<syntaxhighlight 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',
'deino emboar emolga exeggcute gabite girafarig gulpin haxorus heatmor heatran ivysaur jellicent',
'jumpluff kangaskhan kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine',
'nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2 porygonz registeel relicanth',
'remoraid rufflet sableye scolipede scrafty seaking sealeo silcoon simisear snivy snorlax spoink',
'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. */
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 @ ──┘ */
#= 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? */
if @.v\=='' then 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
$$$= /*nullify the possible longest path. */
MP= 0; MPL= 0 /*the initial Maximum Path Length. */
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; say 'One example path of that length is: ' word($$$, 1)
do m=2 to g; say left('', 36) word($$$, m)
end /*m*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
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 @. */
if !.1.LC==0 then return /*is this a dead─end word? */
/* [↓] PARSE obtains first char of @.i*/
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 !==MPL then MP= MP+1 /*bump the Maximum Paths Counter. */
else if !>MPL then do; $$$= @.1 /*rebuild. */
do n=2 for !-2; $$$=$$$ @.n
end /*n*/
$$$= $$$ @.i /*add last.*/
MP=1; MPL=! /*new path.*/
end
parse value @.! @.i with @.i @.!; call scan $$$, !+1
parse value @.! @.i with @.i @.!
end
end /*i*/; return /*exhausted this particular scan. */</syntaxhighlight>
{{out|output|text=&nbsp; is the same as the brute force version.}}
<br><br>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Last letter-first letter
 
ready = []
names = ["audino", "bagon", "baltoy", "banette",
"bidoof", "braviary", "bronzor", "carracosta", "charmeleon",
"cresselia", "croagunk", "darmanitan", "deino", "emboar",
"emolga", "exeggcute", "gabite", "girafarig", "gulpin",
"haxorus", "heatmor", "heatran", "ivysaur", "jellicent",
"jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba",
"loudred", "lumineon", "lunatone", "machamp", "magnezone",
"mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu",
"pinsir", "poliwrath", "poochyena", "porygon2", "porygonz",
"registeel", "relicanth", "remoraid", "rufflet", "sableye",
"scolipede", "scrafty", "seaking", "sealeo", "silcoon",
"simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga",
"trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
"wailord", "wartortle", "whismur", "wingull", "yamask"]
strbegin = "gabite"
strdir = "first"
nr = 1
add(ready,strbegin)
see strbegin + nl
while true
if strdir = "first"
strc = right(strbegin, 1)
flag = 1
nr = nr + 1
if nr <= len(names)
if left(names[nr],1) = strc
for n = 1 to len(ready)
if names[nr] = ready[n]
flag = 0
ok
next
if flag = 1
add(ready,names[nr])
see names[nr] + nl
strbegin = names[nr]
nr = 0
strdir = "last"
loop
ok
ok
ok
else
strc = right(strbegin, 1)
flag = 1
nr = nr + 1
if nr <= len(names)
if left(names[nr],1) = strc
for n = 1 to len(ready)
if names[nr] = ready[n]
flag = 0
ok
next
if flag = 1
add(ready,names[nr])
see names[nr] + nl
strbegin = names[nr]
nr = 0
strdir = "first"
loop
ok
ok
ok
ok
end
</syntaxhighlight>
Output:
<pre>
gabite
emboar
registeel
landorus
sableye
emolga
audino
</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">class LastL_FirstL
def initialize(names)
@names = names.dup
@first = names.group_by {|name| name[0]}
@sequences = []
end
def add_name(seq)
last_letter = seq[-1][-1]
potentials = @first.include?(last_letter) ? (@first[last_letter] - seq) : []
if potentials.empty?
@sequences << seq
else
potentials.each {|name| add_name(seq + [name])}
end
end
def search
@names.each {|name| add_name [name]}
max = @sequences.max_by {|seq| seq.length}.length
max_seqs = @sequences.select {|seq| seq.length == max}
puts "there are #{@sequences.length} possible sequences"
puts "the longest is #{max} names long"
puts "there are #{max_seqs.length} such sequences. one is:"
max_seqs.last.each_with_index {|name, idx| puts " %2d %s" % [idx+1, name]}
end
end
 
names = %w{
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask
}
 
lf = LastL_FirstL.new(names)
lf.search</syntaxhighlight>
outputs
<pre>there are 2076396 possible sequences
the longest is 23 names long
there are 1248 such sequences. one is:
1 machamp
2 pinsir
3 rufflet
4 trapinch
5 heatmor
6 remoraid
7 darmanitan
8 nosepass
9 starly
10 yamask
11 kricketune
12 exeggcute
13 emboar
14 relicanth
15 haxorus
16 simisear
17 registeel
18 landorus
19 seaking
20 girafarig
21 gabite
22 emolga
23 audino</pre>
 
=={{header|Rust}}==
{{trans|Kotlin}}
<syntaxhighlight lang="rust">/// # Panics
///
/// If string is empty.
fn first_char(string: &str) -> char {
string.chars().next().unwrap()
}
 
/// # Panics
///
/// If string is empty.
fn first_and_last_char(string: &str) -> (char, char) {
(
first_char(string),
first_char(string.rmatches(|_: char| true).next().unwrap()),
)
}
 
struct Pokemon {
name: &'static str,
first: char,
last: char,
}
 
impl Pokemon {
fn new(name: &'static str) -> Pokemon {
let (first, last) = first_and_last_char(name);
Pokemon { name, first, last }
}
}
 
#[derive(Default)]
struct App {
max_path_length: usize,
max_path_length_count: usize,
max_path_example: Vec<&'static str>,
pokemon: Vec<Pokemon>,
}
 
impl App {
fn search(&mut self, offset: usize) {
if offset > self.max_path_length {
self.max_path_length = offset;
self.max_path_length_count = 1;
} else if offset == self.max_path_length {
self.max_path_length_count += 1;
self.max_path_example.clear();
self.max_path_example.extend(
self.pokemon[0..offset]
.iter()
.map(|Pokemon { name, .. }| *name),
);
}
 
let last_char = self.pokemon[offset - 1].last;
for i in offset..self.pokemon.len() {
if self.pokemon[i].first == last_char {
self.pokemon.swap(offset, i);
self.search(offset + 1);
self.pokemon.swap(offset, i);
}
}
}
}
 
fn main() {
let pokemon_names = [
"audino",
"bagon",
"baltoy",
"banette",
"bidoof",
"braviary",
"bronzor",
"carracosta",
"charmeleon",
"cresselia",
"croagunk",
"darmanitan",
"deino",
"emboar",
"emolga",
"exeggcute",
"gabite",
"girafarig",
"gulpin",
"haxorus",
"heatmor",
"heatran",
"ivysaur",
"jellicent",
"jumpluff",
"kangaskhan",
"kricketune",
"landorus",
"ledyba",
"loudred",
"lumineon",
"lunatone",
"machamp",
"magnezone",
"mamoswine",
"nosepass",
"petilil",
"pidgeotto",
"pikachu",
"pinsir",
"poliwrath",
"poochyena",
"porygon2",
"porygonz",
"registeel",
"relicanth",
"remoraid",
"rufflet",
"sableye",
"scolipede",
"scrafty",
"seaking",
"sealeo",
"silcoon",
"simisear",
"snivy",
"snorlax",
"spoink",
"starly",
"tirtouga",
"trapinch",
"treecko",
"tyrogue",
"vigoroth",
"vulpix",
"wailord",
"wartortle",
"whismur",
"wingull",
"yamask",
];
 
let mut app = App {
pokemon: pokemon_names
.iter()
.map(|name| Pokemon::new(name))
.collect(),
..App::default()
};
 
for i in 0..app.pokemon.len() {
app.pokemon.swap(0, i);
app.search(1);
app.pokemon.swap(0, i);
}
 
println!("Maximum path length: {}", app.max_path_length);
println!("Paths of that length: {}", app.max_path_length_count);
println!(
"Example path of that length: {}",
app.max_path_example.join(" "),
);
}
</syntaxhighlight>
Recommend you run as `release` or at least with `opt-level=1`
{{out}}
<pre>
Maximum path length: 23
Paths of that length: 1248
Example path of that length: machamp pinsir rufflet trapinch heatmor remoraid darmanitan nosepass starly yamask kricketune exeggcute emboar relicanth haxorus simisear registeel landorus seaking girafarig gabite emolga audino
</pre>
 
=={{header|Scala}}==
===Naive===
<syntaxhighlight lang="scala">object LastLetterFirstLetterNaive extends App {
def solve(names: Set[String]) = {
def extend(solutions: List[List[String]]): List[List[String]] = {
val more = solutions.flatMap{solution =>
val lastLetter = solution.head takeRight 1
(names -- solution).filter(_.take(1) equalsIgnoreCase lastLetter).map(_ :: solution)
}
if (more.isEmpty) solutions else extend(more)
}
 
extend(names.toList.map(List(_))).map(_.reverse)
}
 
val names70 = Set("audino", "bagon", "baltoy", "banette", "bidoof", "braviary", "bronzor", "carracosta", "charmeleon", "cresselia", "croagunk", "darmanitan", "deino", "emboar", "emolga", "exeggcute", "gabite", "girafarig", "gulpin", "haxorus", "heatmor", "heatran", "ivysaur", "jellicent", "jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba", "loudred", "lumineon", "lunatone", "machamp", "magnezone", "mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu", "pinsir", "poliwrath", "poochyena", "porygon2", "porygonz", "registeel", "relicanth", "remoraid", "rufflet", "sableye", "scolipede", "scrafty", "seaking", "sealeo", "silcoon", "simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga", "trapinch", "treecko", "tyrogue", "vigoroth", "vulpix", "wailord", "wartortle", "whismur", "wingull", "yamask")
 
val solutions = solve(names70)
println(s"Maximum path length: ${solutions.head.length}")
println(s"Paths of that length: ${solutions.size}")
println("Example path of that length:")
println(solutions.head.sliding(7,7).map(_.mkString(" ")).map(" "+_).mkString("\n"))
}</syntaxhighlight>
Output:
<pre>Maximum path length: 23
Paths of that length: 1248
Example path of that length:
machamp petilil loudred darmanitan nosepass snivy yamask
kricketune emboar rufflet trapinch heatmor relicanth haxorus
simisear registeel landorus seaking girafarig gabite exeggcute
emolga audino</pre>
===With Lookup Table (Faster)===
<syntaxhighlight lang="scala">object LastLetterFirstLetterLookup extends App {
def solve(names: Set[String]) = {
val transitions = {
val startsWith = names.groupBy(_.take(1).toLowerCase).withDefaultValue(Set.empty)
names.map{name => name -> startsWith(name.takeRight(1).toLowerCase)}.toMap
}
 
def extend(solutions: List[List[String]]): List[List[String]] =
solutions.flatMap{solution =>
(transitions(solution.head) -- solution).map(_ :: solution)
} match {
case Nil => solutions
case more => extend(more)
}
 
extend(names.toList.map(List(_))).map(_.reverse)
}
 
val names70 = Set("audino", "bagon", "baltoy", "banette", "bidoof", "braviary", "bronzor", "carracosta", "charmeleon", "cresselia", "croagunk", "darmanitan", "deino", "emboar", "emolga", "exeggcute", "gabite", "girafarig", "gulpin", "haxorus", "heatmor", "heatran", "ivysaur", "jellicent", "jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba", "loudred", "lumineon", "lunatone", "machamp", "magnezone", "mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu", "pinsir", "poliwrath", "poochyena", "porygon2", "porygonz", "registeel", "relicanth", "remoraid", "rufflet", "sableye", "scolipede", "scrafty", "seaking", "sealeo", "silcoon", "simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga", "trapinch", "treecko", "tyrogue", "vigoroth", "vulpix", "wailord", "wartortle", "whismur", "wingull", "yamask")
 
val solutions = solve(names70)
println(s"Maximum path length: ${solutions.head.length}")
println(s"Paths of that length: ${solutions.size}")
println("Example path of that length:")
println(solutions.head.sliding(7,7).map(_.mkString(" ")).map(" "+_).mkString("\n"))
}</syntaxhighlight>
===Parallelised With Lookup Table (Faster)===
<syntaxhighlight lang="scala">object LastLetterFirstLetterLookupParallel extends App {
def solve(names: Set[String]) = {
val transitions = {
val startsWith = names.groupBy(_.take(1).toLowerCase).withDefaultValue(Set.empty)
names.map{name => name -> startsWith(name.takeRight(1).toLowerCase)}.toMap
}
 
import scala.collection.parallel.immutable.ParSeq
def extend(solutions: ParSeq[List[String]]): ParSeq[List[String]] =
solutions.flatMap{solution =>
(transitions(solution.head) -- solution).map(_ :: solution)
} match {
case seq if seq.isEmpty => solutions
case more => extend(more)
}
 
extend(names.toList.map(List(_)).par).map(_.reverse)
}
 
val names70 = Set("audino", "bagon", "baltoy", "banette", "bidoof", "braviary", "bronzor", "carracosta", "charmeleon", "cresselia", "croagunk", "darmanitan", "deino", "emboar", "emolga", "exeggcute", "gabite", "girafarig", "gulpin", "haxorus", "heatmor", "heatran", "ivysaur", "jellicent", "jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba", "loudred", "lumineon", "lunatone", "machamp", "magnezone", "mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu", "pinsir", "poliwrath", "poochyena", "porygon2", "porygonz", "registeel", "relicanth", "remoraid", "rufflet", "sableye", "scolipede", "scrafty", "seaking", "sealeo", "silcoon", "simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga", "trapinch", "treecko", "tyrogue", "vigoroth", "vulpix", "wailord", "wartortle", "whismur", "wingull", "yamask")
 
val solutions = solve(names70)
println(s"Maximum path length: ${solutions.head.length}")
println(s"Paths of that length: ${solutions.size}")
println("Example path of that length:")
println(solutions.head.sliding(7,7).map(_.mkString(" ")).map(" "+_).mkString("\n"))
}</syntaxhighlight>
 
=={{header|Seed7}}==
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
var integer: maxPathLength is 0;
var integer: maxPathLengthCount is 0;
var string: maxPathExample is "";
 
var array string: names is [] (
"audino", "bagon", "baltoy", "banette", "bidoof", "braviary", "bronzor",
"carracosta", "charmeleon", "cresselia", "croagunk", "darmanitan", "deino",
"emboar", "emolga", "exeggcute", "gabite", "girafarig", "gulpin", "haxorus",
"heatmor", "heatran", "ivysaur", "jellicent", "jumpluff", "kangaskhan",
"kricketune", "landorus", "ledyba", "loudred", "lumineon", "lunatone",
"machamp", "magnezone", "mamoswine", "nosepass", "petilil", "pidgeotto",
"pikachu", "pinsir", "poliwrath", "poochyena", "porygon2", "porygonz",
"registeel", "relicanth", "remoraid", "rufflet", "sableye", "scolipede",
"scrafty", "seaking", "sealeo", "silcoon", "simisear", "snivy", "snorlax",
"spoink", "starly", "tirtouga", "trapinch", "treecko", "tyrogue", "vigoroth",
"vulpix", "wailord", "wartortle", "whismur", "wingull", "yamask");
 
const proc: recursive (in array string: part, in integer: offset) is func
local
var integer: index is 0;
var char: lastChar is ' ';
var string: tmp is "";
begin
if pred(offset) > maxPathLength then
maxPathLength := pred(offset);
maxPathLengthCount := 1;
elsif pred(offset) = maxPathLength then
incr(maxPathLengthCount);
maxPathExample := "";
for index range 1 to pred(offset) do
if pred(index) rem 5 = 0 then
maxPathExample &:= "\n ";
else
maxPathExample &:= " ";
end if;
maxPathExample &:= part[index];
end for;
end if;
lastChar := part[pred(offset)][length(part[pred(offset)])];
for index range offset to length(part) do
if part[index][1] = lastChar then
tmp := names[offset];
names[offset] := names[index];
names[index] := tmp;
recursive(names, succ(offset));
names[index] := names[offset];
names[offset] := tmp;
end if;
end for;
end func;
 
const proc: main is func
local
var integer: index is 0;
var string: tmp is "";
begin
for index range 1 to length(names) do
tmp := names[1];
names[1] := names[index];
names[index] := tmp;
recursive(names, 2);
names[index] := names[1];
names[1] := tmp;
end for;
writeln("maximum path length: " <& maxPathLength lpad 4);
writeln("paths of that length: " <& maxPathLengthCount lpad 4);
writeln("example path of that length:" <& maxPathExample);
end func;</syntaxhighlight>
 
Output:
<pre>
maximum path length: 23
paths of that length: 1248
example path of that length:
machamp pinsir rufflet trapinch heatmor
remoraid darmanitan nosepass starly yamask
kricketune exeggcute emboar relicanth haxorus
simisear registeel landorus seaking girafarig
gabite emolga audino
</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">class LLFL(Array words) {
 
has f = Hash()
 
method init {
words.each {|w|
var m = w.match(/^(.).*(.)$/)
f{m[0]}{w} = m[1]
}
}
 
method longest_chain {
 
var stack = []
var longest = []
 
func poke(c) {
var h = f{c}
 
h.each_k { |word|
var v = h.delete(word)
stack.push(word)
longest[] = stack[] if (stack.len > longest.len)
__FUNC__(v) if f.exists(v)
stack.pop
h{word} = v
}
}
 
f.each_k { poke(_) }
return longest
}
}
 
var words = %w(
audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask
)
 
var obj = LLFL(words)
var longest = obj.longest_chain()
 
say "#{longest.len}: #{longest.join(' ')}"</syntaxhighlight>
{{out}}
<pre>
23: machamp petilil landorus scrafty yamask kricketune exeggcute emboar registeel loudred darmanitan nosepass simisear rufflet trapinch heatmor relicanth haxorus seaking girafarig gabite emolga audino
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc search {path arcs} {
set solutions {}
set c [string index [lindex $path end] end]
Line 1,281 ⟶ 4,946:
}
set path [firstlast $names]
puts "Path (length: [llength $path]): $path"</langsyntaxhighlight>
Output:
<pre>
Line 1,289 ⟶ 4,954:
=={{header|Ursala}}==
 
<langsyntaxhighlight Ursalalang="ursala">#import std
 
mon =
Line 1,307 ⟶ 4,972:
#show+
 
example = ~&h poke mon</langsyntaxhighlight>output:
<pre>machamp
petilil
Line 1,331 ⟶ 4,996:
emolga
audino
</pre>
 
=={{header|VBScript}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="vb">' Last letter-first letter - VBScript - 11/03/2019
names = array( _
"audino", "bagon", "baltoy", "banette", _
"bidoof", "braviary", "bronzor", "carracosta", "charmeleon", _
"cresselia", "croagunk", "darmanitan", "deino", "emboar", _
"emolga", "exeggcute", "gabite", "girafarig", "gulpin", _
"haxorus", "heatmor", "heatran", "ivysaur", "jellicent", _
"jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba", _
"loudred", "lumineon", "lunatone", "machamp", "magnezone", _
"mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu", _
"pinsir", "poliwrath", "poochyena", "porygon2", "porygonz", _
"registeel", "relicanth", "remoraid", "rufflet", "sableye", _
"scolipede", "scrafty", "seaking", "sealeo", "silcoon", _
"simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga", _
"trapinch", "treecko", "tyrogue", "vigoroth", "vulpix", _
"wailord", "wartortle", "whismur", "wingull", "yamask")
 
maxPathLength = 0
maxPathLengthCount = 0
maxPathExample = ""
t1=timer
 
For i = 0 To ubound(names)
'swap names(0), names(i)
temp=names(0): names(0)=names(i): names(i)=temp
Call lastfirst(names, 1)
'swap names(0), names(i)
temp=names(0): names(0)=names(i): names(i)=temp
Next 'i
buf = buf & "Maximum length = " & maxPathLength & vbCrLf
buf = buf & "Number of solutions with that length = " & maxPathLengthCount & vbCrLf
buf = buf & "One such solution: " & vbCrLf & maxPathExample & vbCrLf
t2=timer
MsgBox buf,,"Last letter-first letter - " & Int(t2-t1) & " sec"
 
Sub lastfirst(names, offset)
dim i, l
If offset > maxPathLength Then
maxPathLength = offset
maxPathLengthCount = 1
ElseIf offset = maxPathLength Then
maxPathLengthCount = maxPathLengthCount + 1
maxPathExample = ""
For i = 0 To offset-1
maxPathExample = maxPathExample & names(i) & vbCrLf
Next 'i
End If
l = Right(names(offset - 1),1)
For i = offset To ubound(names)
If Left(names(i),1) = l Then
'swap names(i), names(offset)
temp=names(offset): names(offset)=names(i): names(i)=temp
Call lastfirst(names, offset+1)
'swap names(i), names(offset)
temp=names(offset): names(offset)=names(i): names(i)=temp
End If
Next 'i
End Sub 'lastfirst </syntaxhighlight>
{{out}}
<pre>
Maximum length = 23
Number of solutions with that length = 1248
One such solution:
machamp
pinsir
rufflet
trapinch
heatmor
remoraid
darmanitan
nosepass
starly
yamask
kricketune
exeggcute
emboar
relicanth
haxorus
simisear
registeel
landorus
seaking
girafarig
gabite
emolga
audino
</pre>
Duration : 69 sec
 
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="wren">var maxPathLength = 0
var maxPathLengthCount = 0
var maxPathExample = ""
 
var names = [
"audino", "bagon", "baltoy", "banette", "bidoof",
"braviary", "bronzor", "carracosta", "charmeleon", "cresselia",
"croagunk", "darmanitan", "deino", "emboar", "emolga",
"exeggcute", "gabite", "girafarig", "gulpin", "haxorus",
"heatmor", "heatran", "ivysaur", "jellicent", "jumpluff",
"kangaskhan", "kricketune", "landorus", "ledyba", "loudred",
"lumineon", "lunatone", "machamp", "magnezone", "mamoswine",
"nosepass", "petilil", "pidgeotto", "pikachu", "pinsir",
"poliwrath", "poochyena", "porygon2", "porygonz", "registeel",
"relicanth", "remoraid", "rufflet", "sableye", "scolipede",
"scrafty", "seaking", "sealeo", "silcoon", "simisear",
"snivy", "snorlax", "spoink", "starly", "tirtouga",
"trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
"wailord", "wartortle", "whismur", "wingull", "yamask"
]
 
var search // recursive function
search = Fn.new { |part, offset|
if (offset > maxPathLength) {
maxPathLength = offset
maxPathLengthCount = 1
} else if (offset == maxPathLength) {
maxPathLengthCount = maxPathLengthCount + 1
maxPathExample = ""
for (i in 0...offset) {
maxPathExample = maxPathExample + ((i % 5 == 0) ? "\n " : " ") + part[i]
}
}
var lastChar = part[offset - 1][-1]
for (i in offset...part.count) {
if (part[i][0] == lastChar) {
var tmp = names[offset]
names[offset] = names[i]
names[i] = tmp
search.call(names, offset + 1)
names[i] = names[offset]
names[offset] = tmp
}
}
}
 
for (i in 0...names.count) {
var tmp = names[0]
names[0] = names[i]
names[i] = tmp
search.call(names, 1)
names[i] = names[0]
names[0] = tmp
}
System.print("Maximum path length : %(maxPathLength)")
System.print("Paths of that length : %(maxPathLengthCount)")
System.print("Example path of that length : %(maxPathExample)")</syntaxhighlight>
 
{{out}}
<pre>
Maximum path length : 23
Paths of that length : 1248
Example path of that length :
machamp pinsir rufflet trapinch heatmor
remoraid darmanitan nosepass starly yamask
kricketune exeggcute emboar relicanth haxorus
simisear registeel landorus seaking girafarig
gabite emolga audino
</pre>
 
=={{header|Yabasic}}==
{{trans|Phix}}
<syntaxhighlight lang="yabasic">all$ = "audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon "
all$ = all$ + "cresselia croagunk darmanitan deino emboar emolga exeggcute gabite "
all$ = all$ + "girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan "
all$ = all$ + "kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine "
all$ = all$ + "nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2 "
all$ = all$ + "porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking "
all$ = all$ + "sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko "
all$ = all$ + "tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask"
 
dim word$(1)
lnames = token(all$, word$())
 
dim first(256), snext(lnames)
for i = 1 to lnames
ch = asc(left$(word$(i), 1))
if first(ch)=0 then
first(ch) = i
end if
for j=i+1 to lnames
if asc(left$(word$(j), 1))=ch then
snext(i) = j
break
end if
next
next
dim taken(lnames), best(lnames)
sub try(ch, last, n)
local nex, i
nex = first(ch)
while(nex <> 0)
if taken(nex)=0 then
taken(last) = nex
taken(nex) = -1
try(asc(right$(word$(nex), 1)),nex,n+1)
taken(last) = -1
taken(nex) = 0
end if
nex = snext(nex)
wend
if n>maxn then
bstart = tstart
for i = 1 to lnames
best(i) = taken(i)
next
maxn = n
count = 1
elsif n=maxn then
count = count + 1
end if
end sub
for i=1 to lnames
tstart = i
taken(i) = -1
try(asc(right$(word$(i), 1)),i,1)
taken(i) = 0
next
 
print "Runtime: ", peek("millisrunning")/1000, " seconds. Max length: ", maxn, ", found ", count, " of such, one of which is:\n"
do
print word$(bstart), " ";
bstart = best(bstart)
if bstart = -1 break
loop</syntaxhighlight>
 
=={{header|zkl}}==
This solution creates a hash table to all the possible word/following words to minimize search times.
 
No speed records were approached but 25sec seems fine for a one off walk the entire tree.
 
<syntaxhighlight lang="zkl">pokemon:=("audino bagon baltoy banette bidoof braviary "
"bronzor carracosta charmeleon cresselia croagunk darmanitan deino "
...
"whismur wingull yamask").split();
 
tree:=pokemon.pump(Dictionary(),'wrap(name){ //--> Hash("aB":("Bc","Bd",,,) )
T( name, pokemon.filter('wrap(nm){ name[-1]==nm[0] }) )
});
 
fcn maxPath([(a,_)]ab,[(c,_)]cd){ if(a>c) ab else cd }
fcn walk(name,pathLen,path,tree){ //-->longest path for name
names:=tree.find(name,T); tree[name]=T; // nuke cycle
np:=names.reduce('wrap(np,name){
maxPath(np,walk(name,pathLen+1,String(path," ",name),tree));
},T(0,""));
tree[name]=names;
if(np[0]>pathLen) return(np);
return(pathLen,path);
}
 
pokemon.reduce('wrap(np,name){ maxPath(walk(name,1,name,tree),np) },T(0,""))
.println();</syntaxhighlight>
{{out}}
<pre>
L(23,"machamp pinsir rufflet trapinch heatmor remoraid darmanitan nosepass
starly yamask kricketune exeggcute emboar relicanth haxorus simisear
registeel landorus seaking girafarig gabite emolga audino")
</pre>