Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re^3: Play and win the word morph game with the help of Perl :)

by Limbic~Region (Chancellor)
on Jun 29, 2006 at 12:11 UTC ( [id://558298]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Play and win the word morph game with the help of Perl :)
in thread Play and win the word morph game with the help of Perl :)

Ieronim,
I am glad you learned something from my code. It was intended to be concise while also being straight forward. DBM::Deep is not currently designed to be fast as it is written in pure perl. If you want speed - try the version below which uses Storable. I believe it outperforms yours though I have not Benchmarked it.

I admit that I have not had a chance to disect your code but I am interested in how you build bridges for words not in the dictionary. If it is only the endpoints, then modifying my code to do the same would be trivial. I am going to spend some time disecting your code and may update the version below if all you are handling is end-points.

#!/usr/bin/perl use strict; use warnings; use Storable; use Text::LevenshteinXS 'distance'; my $db = -e 'dictionary.db' ? retrieve('dictionary.db') : build_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'; } # Runs once and can be removed after DB is built sub build_db { open (my $dict, '<', '2of12.txt') or die "Unable to open '2of12.tx +t' for reading: $!"; my ($db, %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; } } } } store $db, 'dictionary.db'; return retrieve('dictionary.db'); }

Cheers - L~R

Replies are listed 'Best First'.
Re^4: Play and win the word morph game with the help of Perl :)
by Ieronim (Friar) on Jun 29, 2006 at 13:01 UTC
    of course the non-dictionary words can appear only at the endpoints.

    The variant with Storable is about 10 time faster than mine :) great :)

      Ieronim,
      I truly like the elegance of my previous solution. It is Concise, straight forward, and fast. You can even remove the build_db() after the database has been compiled as I have shown below in about 20 lines of code: For the sake of completeness, I am providing the following version which allows you to use non-dictionary words at the endpoints. Feel free to adjust this as you see fit.

      Cheers - L~R

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://558298]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (2)
As of 2024-04-26 03:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found