http://qs321.pair.com?node_id=542969


in reply to Re^3: traversing a hash looking for path?
in thread traversing a hash looking for path?

L~R:

For some problems, recursion can be more elegant. For some other problems, it's just another way to do the job. For the remaining few problems, it's just a harder way to do things.

In fact, for this problem, it may be that recursion could be more elegant. My implementation, however, makes no such claim! Especially as you've made a few improvements! 8^)

(In Perl, I'm not very skilled (yet), so you'd be agog at how much time I spent debugging it before posting. I was happy enough to get it done! Once there, I was afraid to touch it in persuit of elegance. We need to get a good golfer in here for that...)

Regarding the altering of the search process: I'd imagine that you may be able to get there with a recursive solution, as well--not that one comes to mind for this task!

I've been meaning to beat Lisp into my brain, but after learning a few programming languages, I've adopted the policy: No learning a new language until I get paid for it! It's too bad I can't convince my boss to let me write anything in Lisp..... So, I'm trying to learn some Lisp-like Perl idioms, but I've got quite a way to go!

--roboticus

  • Comment on Re^4: traversing a hash looking for path?

Replies are listed 'Best First'.
Re^5: traversing a hash looking for path?
by Limbic~Region (Chancellor) on Apr 13, 2006 at 23:50 UTC
    roboticus,
    The problem with a recursive BFS is that you have to pass forward your nodes. You want to first check all your nodes of a distance of 1, then 2, etc until you find your destination.

    It turns out that the only real difference between this and my iterative solution is that you have 2 stacks. The first is the current work load (nodes at current distance) and the second is you future work load (nodes at the next distance) which you pass forward.

    While the find_path() sub that follows is quite elegant, the remainder of the code isn't.

    This isn't the result of recursive BFS being all that ugly or intention obfu. I was just experimenting. It can be brought back into a single sub that looks quite reasonable (which is what I started with). Since working backwards to clean code is easier, I thought you might enjoy seeing the things I played with.

    Update: Since others besides roboticus might be interested, I am providing the relatively clean version as well.

    Cheers - L~R

      Hi limbic~region,

      I would have done it something like this:

      my %net = ( ... ); my $start = '1.2.3.4'; my $end = '1.2.3.6'; print find_pathr( \%net, $end, $start ) . "\n"; sub find_pathr { my ( $net, $end, @list ) = @_; my $curr; do { $curr = shift @list; } until ( ! @list or exists $$net{ $curr } ); return "No path!" unless exists $$net{$curr}; return $end if $curr eq $end; unshift @list, @{ delete $$net{ $curr } }; return "$curr->" . find_pathr( $net, $end, @list ); }

      Now this quick implementation isn't perfect. It doesn't pretend to find the most efficient path, it finds the first path based on the order of the elements of %net. It is destructive to %net. I don't like the do ... until loop.

      But I do think it is an elegant solution, IMNSHO ;)

      Update: This is a depth-first search, not breadth-first as is limbic~region's.