in reply to Re: Depth First Search and Boggle
in thread Depth First Search and Boggle

I understand that, but i never pass 3|5|7... elements to dfs. I either call it

dfs(0, 0, %visited, $word)

or

dfs($x + $$_[0], $y + $$_[1], %visited, $word)

so there shouldnt be any problem with odd numbers of elements getting passed to dfs. Beyond that passing by reference would create alot more work to maintain seperate visited and work variables for the different branches in the search.

Replies are listed 'Best First'.
Re: Re: Re: Depth First Search and Boggle
by BrowserUk (Patriarch) on Aug 15, 2002 at 06:11 UTC

    The point is that all your parameters, including %visited get flattened and passed as a single list:

    ($x, $y, key1,val1,key2,val2,...,$word)

    Inside dfs(), Perl has no way to tell that the last value ($word) is not an element of the list that must be assigned to %visited, so it attempts to assign that too. Hence the odd number of elements.

    $word will never be assigned a value.

    Swap the order of %visited and $word inside dfs() and when you call dfs() and your code will (probably) work!


    What's this about a "crooked mitre"? I'm good at woodwork!
Re: Re: Re: Depth First Search and Boggle
by the_slycer (Chaplain) on Aug 15, 2002 at 06:30 UTC
    Here's a hint.
    print "'$_'\n" foreach @_ at the start of your sub (before the assignment).
    See what is happening here? You will get a printout like:
    '0'
    '0'
    ''
    hmm.. not quite what you wanted I think. You are only passing 3 defined values into the sub. Two 0's and one "". Because your hash is undefined, it doesn't show up in the @_ list.

    Just looking at this bit of code, it looks like you are trying to do the "right" thing by use'ing strict and passing your variables around to your subroutine. The thing is, if your variables have no value, then there is no reason to pass them. In fact, looking at it,there is absolutely no reason to define %visited or $word in the "main" code at all

    In this bit of code, I would personally work more like
    ... dfs(0,0); ... sub dfs { my ($x,$y,$word,%visited) = @_; #no error here! ... process code ... dfs($x,$y,$word,%visited); #recursion call }
    See the differences? First, because we only pass 2 defined values in the first call to dfs, we only assign to $x and $y. This is fine, because we don't use $word or %visited before we assign to them. Hence, we aren't using an undef'd variable. Nor are we assigning "" to the hash. Second, in subsequent calls, we pass the hash last

    BrowserUk is completely right in this. Using an assignment like in your code, you will almost always end up with an odd value assignment. You could almost call an assignment to a hash (or an array for that matter) greedy, because it will always take up the "rest" of @_, if you need to pass variables and a hash or an array, always put the hash/array last in the assignment list. If you need to pass two lists (eg 2 arrays, or a hash and an array) you MUST pass by reference.