Ieronim,
I first posted untested code because I was about to leave work and
DBM::Deep takes forever to build the database. I have subsequently updated it to use a recursive BFS, optimized the build_db() routine, and verified it works correctly. I hope you enjoy though it is much slower than I hoped due to requiring a BFS to find the shortest path.
#!/usr/bin/perl
use strict;
use warnings;
use DBM::Deep;
use Text::LevenshteinXS 'distance';
my $db = DBM::Deep->new('dict.db');
build_db($db) if ! scalar keys %$db;
my ($src, $tgt) = @ARGV;
# Error handle defined, length, exist in $db and distance() > 1
my $len = length($tgt);
my $list = $db->{$len};
my $path = find_path($src, $tgt, $list);
print "$path\n";
sub find_path {
my ($src, $tgt, $list, $seen, $work) = @_;
@$work = map {key => $_ => path => "$src->$_"}, @{$list->{$src}} i
+f ! defined $work;
my $next = [];
for (@$work) {
my ($word, $path) = @{$_}{qw/key path/};
next if $seen->{$word}++;
return $path if $word eq $tgt;
push @$next, map {key => $_, path => "$path->$_"}, @{$list->{$
+word}};
}
return find_path($src, $tgt, $list, $seen, $next) if @$next;
return 'path not found';
}
sub build_db {
my $db = shift @_;
open (my $dict, '<', '2of12.txt') or die "Unable to open '2of12.tx
+t' for reading: $!";
my %data;
while (<$dict>) {
chomp;
push @{$data{length()}}, $_;
}
for my $len (keys %data) {
my $end = $#{$data{$len}};
for my $i (0 .. $end - 1) {
my $word = $data{$len}[$i];
for my $j ($i + 1 .. $end) {
my $test = $data{$len}[$j];
if (distance($word, $test) == 1) {
push @{$db->{$len}{$word}}, $test;
push @{$db->{$len}{$test}}, $word;
}
}
}
}
}
You also have a bug: try 'foot' and 'fool'