Keep my Trip Cool!

11

Challenge

Walking around Marks and Spencers, I noticed that they had air conditioning units placed randomly around the shop. Wanting to keep cool, I wondered what was the easiest way to move around the whole shop without being away from an air conditioning unit for too long.

Given a map, you must find a way to travel around the whole map keeping the distance from an air conditioning unit as short as possible (even if the AC unit is on the other side of a wall).

Map

The map may be supplied in any way you like and uses the following symbols:

+ is a corner of a wall
| is a east/west facing wall
- is a north/south facing wall
X is an air conditioning unit
S is the start and end point

An example map would be:

+------S---+
|   X      |
| ---+-+ X |
|    |X|   |
| ---+ +---+
|   X      |
+----------+

or

+---+--+
| X |  |
|   |  +-----+------+
|   | X      | X    |
|     ---+       |  S
|   |    |  X    |  |
|   |  +-+-------+--+
| X    |
+------+

Travelling around the whole map means passing through every empty space and air conditioner. You cannot travel through a wall and may only travel orthogonally. A map may not always be rectangular.

Keeping the distance as short as possible from an AC unit is the sum over all time steps.

Passing through means entering and leaving.

You may output the path in any way you like. Examples include:

  • Outputting the map with the path included
  • Outputting the path as a succession of compass points (e.g. NNSESW)

Beta Decay

Posted 2014-11-02T12:42:54.627

Reputation: 21 478

6Is this an optimization problem? If not, there should be some test cases with correct outputs. – mbomb007 – 2016-12-23T17:25:56.663

1Note: |, - and + can really just be one char. They are all really just walls. – Erik the Outgolfer – 2018-06-28T16:13:30.673

Is the start point guaranteed to be at the map's edge or can there be U-shaped maps with the entrance in the center? – Jonathan Frech – 2018-08-14T15:53:30.907

@JonathanFrech Yes, it will be at the edge – Beta Decay – 2018-08-14T16:34:35.707

2Could u give us the distance for the only two possible traveling way for the first example? – mdahmoune – 2019-02-06T12:46:49.650

What does "as short as possible" mean? That we have to find the optimal solution? – Ingo Bürk – 2014-11-02T13:09:26.843

@IngoBürk Yes, you do – Beta Decay – 2014-11-02T13:14:26.527

2@BetaDecay And how is that calculated? The maximum distance at any point in time? The sum/average of the distance over all time steps? – Ingo Bürk – 2014-11-02T13:17:00.333

5It's impossible to understand what the goal of this problem is. If you must visit every square, the maximum distance is a constant. – feersum – 2014-11-02T23:37:47.627

1@feersum Why is that? Couldn't the map layout make it necessary to revisit certain squares and thus giving multiple possibilites for the pathing? – InvisiblePanda – 2014-11-03T09:09:40.827

@InvisiblePanda, the maximum is independent of ordering and duplication. I read it as asking for the sum over all time steps, which makes it a non-trivial optimisation problem. – Peter Taylor – 2014-11-03T09:33:54.640

That makes a lot of sense. Can I just claim my question was a trick question? ;) – Ingo Bürk – 2014-11-03T17:55:55.177

Answers

1

PowerShell for Windows, 376 367 bytes

Like a lazy man, I don't go to every shelf, I move from air conditioner to air conditioner in a store. I believe I traveled all over the store visiting every air conditioner in it.

$f={param($m,$d,$o=@{})$w=(($l=$m-split"
")|% le*|sort)[-1]
$m=($l|% *ht $w)-join"
"
if(!$o.$m-or$o.$m-ge$d-and$m-match'(?s)X.*S|S.*X'){$o.$m=$d++
$n=-split")X(S )X(.{$w}S S)X( S.{$w})X("|%{sls "(?s)^(.*$_.*)$" -inp $m -a|% m*|%{($_.Groups-replace'S',' ')[1,2]-join'S'}}
$d=(($n+,($m-replace"(?s)(?<=S(.{$w})?) | (?=(.{$w})?S)",'S')*!$n)|%{&$f $_ $d $o}|sort)[0]}+$d}

Try it online!

Unrolled:

$f={
    param($map,$distance,$o=@{})
    $lines = $map-split"`n"
    $width = ($lines|% length|sort)[-1]
    $map = ($lines|% padRight $width)-join"`n"                              # to rectangle

    if(!$o.$map -or $o.$map-ge$distance -and $map-match'(?s)X.*S|S.*X'){
        $o.$map = $distance++                                               # store a map to avoid recalculations
        $n = -split")X(S )X(.{$width}S S)X( S.{$width})X("|%{               # search a nearest X in 4 directions
            select-string "(?s)^(.*$_.*)$" -InputObject $map -AllMatches|% Matches|%{
                ($_.Groups-replace'S',' ')[1,2]-join'S'                     # start a new segment (reset all S and replace the nearest X by S)
            }
        }
        $stepMore = $map-replace"(?s)(?<=S(.{$w})?) | (?=(.{$w})?S)",'S'
        $n += ,$stepMore*!$n                                                # add a step if X was not found
        $distance=($n|%{&$f $_ $distance $o}|sort)[0]                       # recursive repeat
    }

    +$distance
}

mazzy

Posted 2014-11-02T12:42:54.627

Reputation: 4 832