Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re^2: Code challenge: Route planning on a 2D grid

by bliako (Monsignor)
on Mar 14, 2020 at 10:48 UTC ( [id://11114250]=note: print w/replies, xml ) Need Help??


in reply to Re: Code challenge: Route planning on a 2D grid
in thread Code challenge: Route planning on a 2D grid

OK, distance of sliding squares does not count. But when on a slide, the starting and ending square of one segment (segment=1 line, no turnings) counts. right?

I also thought whether moving backwards is allowed. That can change the problem's nature, so I suggest either no back movement or two flavours, one with back movements and one without.

  • Comment on Re^2: Code challenge: Route planning on a 2D grid

Replies are listed 'Best First'.
Re^3: Code challenge: Route planning on a 2D grid
by tybalt89 (Monsignor) on Mar 14, 2020 at 14:43 UTC

    Hey, no fair changing the rules in the middle...

    #!/usr/bin/perl use strict; # https://perlmonks.org/?node_id=11114231 use warnings; my ($startrow, $startcol, $destrow, $destcol); my @m; my @visited; my $maxrow; my $maxcol; my $maxscore; my $minlength; my $best; for my $SIZE ( 2, 3 ) # add in 1024 and be prepared to wai +t :) { # srand 42; # uncomment for the specified problem +grid my $W = $SIZE; my $H = $SIZE; my $maxscore = 10; my $Grid = []; for my $row ( 0 .. $H - 1 ) { $Grid->[$row] = [(0)x$W]; for my $col ( 0 .. $W - 1 ) { $Grid->[$row]->[$col] = $maxscore - int(rand(2*$maxscore+1)) } } # now add a highscore to stand out for just 1 cell in each column my $highscore = 21; for my $row ( 0 .. $H - 1 ) { $Grid->[$row]->[int(rand($W))] = $highscore; } for my $row ( 0 .. $H-1 ) { printf "%4d" x $W . "\n", @{ $Grid->[$row] }; } print "\n"; ($startrow, $startcol, $destrow, $destcol) = (0, 0, $H-1, $W-1); @m = @$Grid; @visited = (); $maxrow = $W-1; $maxcol = $H-1; $maxscore = undef; $minlength = undef; $best = undef; $visited[$startrow][$startcol] = 1; try( $startrow, $startcol, $m[$startrow][$startcol] ); $best or die "no best found"; # print "\n$best\n\n"; my @best = split ' ', $best; my @values; print "best path:\n"; for ( my $i = 0; $i < @best - 4; $i += 3 ) { print directions(@best[$i .. $i+5]), ' '; # push @values, $m[$best[$i]][$best[$i+1]]; push @values, $best[$i+2] eq '00' ? '00' : $m[$best[$i]][$best[$i+ +1]]; } print "\n= "; print join '+', @values, $m[$best[-3]][$best[-2]]; print "\n= $best[-1]\n\n"; } sub try { my ($row, $col, $score) = @_[-3 .. -1]; # print "$row $col $score\n"; if( $row == $destrow && $col == $destcol ) { if( $maxscore ) { if( $score > $maxscore or $score == $maxscore and $minlength > @_) { $maxscore = $score; $minlength = @_; $best = "@_"; } } else { $maxscore = $score; $minlength = @_; $best = "@_"; } return; } for my $r ( 0 .. $maxrow ) { if( ++$visited[$r][$col] == 1 ) { # if( $m[$r][$col] >= 0 || # $r == $destrow && $col == $destcol ) { if( $r < $row - 1 ) { my @slide = map {($_, $col, '00') } reverse $r + 1 .. $row - + 1; try( @_, @slide, $r, $col, $score + $m[$r][$col] ); } elsif( $r > $row + 1 ) { my @slide = map {($_, $col, '00') } $row + 1 .. $r - 1; try( @_, @slide, $r, $col, $score + $m[$r][$col] ); } else { try( @_, $r, $col, $score + $m[$r][$col] ); } } } --$visited[$r][$col]; } for my $c ( 0 .. $maxcol ) { if( ++$visited[$row][$c] == 1 ) { # if( $m[$row][$c] >= 0 || # $row == $destrow && $c == $destcol ) { if( $c < $col - 1 ) { my @slide = map {($row, $_, '00') } reverse $c + 1 .. $col - + 1; try( @_, @slide, $row, $c, $score + $m[$row][$c] ); } elsif( $c > $col + 1 ) { my @slide = map {($row, $_, '00') } $col + 1 .. $c - 1; try( @_, @slide, $row, $c, $score + $m[$row][$c] ); } else { try( @_, $row, $c, $score + $m[$row][$c] ); } } } --$visited[$row][$c]; } } sub directions { my ($rowfrom, $colfrom, $fromscore, $rowto, $colto, $toscore) = @_; return +($rowfrom != $rowto ? $rowfrom < $rowto ? 'down' : 'up' : $colfrom < $colto ? 'right' : 'left') . ($toscore eq '00' ? '-slide' : ''); }

    Sample Output:

    21 -8 5 21 best path: down right = 21+5+21 = 47 3 21 -6 9 21 10 -7 7 21 best path: down right-slide right left up down-slide down right = 3+9+00+10+21+21+00+7+21 = 92

    For a size of 1024 x 1024, run time is estimated to be either the twelfth of never, or three days after the heat death of the universe, whichever comes last.

        Yes, slides show for each cell, and the values for that cell is the special flag 00, which is a value of zero separate from an actual 0 cell.

      > no fair changing the rules

      Which rules do you apply?

      > For a size of 1024 x 1024, run time is estimated to be either the twelfth of never,

      Depends on the rules.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        The original rules.

Re^3: Code challenge: Route planning on a 2D grid
by LanX (Saint) on Mar 14, 2020 at 11:16 UTC
    I understood the OP like all turning points have to be counted.

    I'd define the length of a path by number of necessary moves. Hence length is 0 if start and end are identical. (This facilitates adding partial solutions)

    I think allowing back-moves is necessary to "solve" a 1024 x 1024 grid with an approach based on probability.

    Compare this Re: Highest total sum path problem

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re^3: Code challenge: Route planning on a 2D grid
by LanX (Saint) on Mar 15, 2020 at 13:03 UTC
    > OK, distance of sliding squares does not count.

    I hope it's obvious now that this makes it pretty much

    O(n**2)

    with

    n = length = #rows= #columns

    because the number of optimal solutions is "bigger" than eternity.

    Counting the distance of slides makes this far more complicated, such that you should change the challenge to "best solution so far" instead of "optimal solution".

    It's also important to understand that optimal sum is easy, shortest (Hamilton) path is problematic.

    My approach would be a two dimensional divide and conquer.

    Like for n=1024=2**10 solving 32 smaller grids with n=32=2**5 side length.

    One could also divide further to 5 stages since 4**5=1024.

    The basic idea is still probabilistic.

    Because of your randomization there is a probability of roughly .5 that a cell is positive.

    Hence two neighboring cells (minimal distance) have the probability of .25 to be both positive.

    This means that if you need to find a minimal transit between two areas with m neighboring cells, then the there is a 1-0.75**m to find it.

    Hence finding very good solutions is not that difficult.

    It's the optimal solution which is on another page.

    But in terms of a coding challenge this should be a big plus, because the crowd loves rankings and hates math. ;)

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

        As I said the crowd hates math.

        And I hate changing rules ... ;)

        > just have fun

        I did!

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-25 09:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found