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'
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.