in reply to Trying to solve N-Queens

I might be wrong, but I am under the impression that you're not considering that queens can attack in columns as well as rows. You should also consider attacking squares that are "before" your current position, like in this untested snippet:

sub mark_attacks { my ($r,$c,$array) = @_; $array->[$r]->[$c] = 'Q'; # mark everything my $none; for my $i (1 .. $SIZE) { $none = 1; $none = $array->[$r]->[$c + $i] = 0 if ($c + $i < $SIZE); $none = $array->[$r]->[$c - $i] = 0 if ($c - $i >= 0); $none = $array->[$r + $i]->[$c] = 0 if ($r + $i < $SIZE); $none = $array->[$r - $i]->[$c] = 0 if ($r - $i >= 0); $none = $array->[$r - $i]->[$c - $i] = 0 if ($r - $i >= 0 and $c + - $i >= 0); $none = $array->[$r + $i]->[$c + $i] = 0 if ($r + $i < $SIZE and + $c + $i < $SIZE); $none = $array->[$r - $i]->[$c + $i] = 0 if ($r - $i >= 0 and $c + + $i < $SIZE); $none = $array->[$r + $i]->[$c - $i] = 0 if ($r + $i < $SIZE and + $c - $i >= 0); last if $none; } }
I also think than a single loop might improve performance slightly.

Good luck in your assignment.

Replies are listed 'Best First'.
Re: Re: Trying to solve N-Queens
by Solo (Deacon) on Sep 09, 2002 at 03:53 UTC
    I don't believe it is necessary to check the diagonals of previous columns, since if it were possible for a queen in col 3 to attack the Q in col 1, the reverse is also true... that is, the position the Q in col 3 would have to be in was previously ruled out by the diagonals of Q in col 1.
      I believe this depends in how are the queens placed in the board (ie, how the solutions are searched).

      For this particular case, you're correct, as queens are apparently placed in each row, from left to right.

      Regards.

(jeffa) 2Re: Trying to solve N-Queens
by jeffa (Bishop) on Sep 09, 2002 at 19:37 UTC

    "I also think than a single loop might improve performance slightly."

    Yep, and it is more simple as well:
    sub mark_attacks { my ($r,$c,$array) = @_; my ($u,$d) = ($r,$r); # to be removed - just for visualization during debugging $array->[$r]->[$c] = 'Q'; for ($c+1..$size-1) { $array->[$r]->[$_] = 0; $array->[--$u]->[$_] = 0 if $u > 0; $array->[++$d]->[$_] = 0 if $d < $size-1; } }
    Thanks for the tips. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)