Gravity Controls

8

1

Your task is to find the total destination of objects that are falling to a planet, you will get inputs like this:

7
...#...     
.......  
#..O..#
.......  
...#...
.......
.......

where O is the planet and # are the objects, note that the planet will attract objects from the for basic directions(NEWS). You should output:

    #
   #O#
    #

i.e the objects after reaching their destination.

The first number given as an input is the length of the grid(nxn), in the above example it is 7.

The object should always move in the shortest direction(note that the allowed directions are only horizontal and vertical; the object can't move diagonally)

If an object is equidistant from two directions it should go in a clock wise direction:

    ..#       
    ...  
    O..  

Will reach this side:

    ...
    ...
    O#.

If an object collides with the planet, it will stop. If it collides with another object they become one object,

 4
 .#..
 #...
 ....  
 .O..

would become:

  ....
  ....
  .#..
  .O..

One final example:

6
..#...
.#....
......
.#O...
....#.
......

Output:

......
......
..#...
.#O#..
......
......

Note: You should output the final shape, so all outputs are accepted as long as they show the final shape of the planet.

for example for this input:

...#
....
.O..
....

Should output:

O#

or

....
....
.O#.
....

Both of these are accepted.

This is so the shortest answer will win

Note 2:

As you may have noticed a . represents vaccum so the shortest path is the shortest number of dots.

For example:

.#.
...
.O.

Is not accepted to be

O#

since the shortest path is vertical. Note3:

The object should always move to be in the same line with the planet in one of the four directions(choosing the shortest)

     |<#
     |
     |  
-----O------
     |

Restrictions:

2<=n<=100

Mhmd

Posted 2014-04-14T14:47:59.627

Reputation: 2 019

What are the possible input sizes? – undergroundmonorail – 2014-04-14T15:01:42.130

2Please clarify "shortest direction." – Ken A – 2014-04-14T15:50:37.617

@KenA I think it could be rephrased like: objects travel diagonally towards the planet until they are in line with the planet (after which they'll move straight towards the planet); if an object ends up touching the the planet diagonally, move one final step in counter-clockwise direction. This should lead to the same result as the OP's specification. But clarification by the OP would be nice. – Martin Ender – 2014-04-14T20:37:45.320

I noticed your example above has some trailing whitespace at the end of some lines. Is it safe to assume the same may be true of the input the program is expected to handle? – skibrianski – 2014-04-15T00:27:21.193

@skib no. It might be a typo but the inputs do not have trailing whitespace. – Mhmd – 2014-04-15T06:34:40.087

@Mhmd In your fourth example the result has an object on the left, right and top. In order to get the one at the right it moved up one row, which would be incorrect since that is counter clockwise, shouldnt it be at the bottom? – Teun Pronk – 2014-04-15T09:48:47.970

@TeunPronk no because it only has to move up by 1 unit, but would have to move to the left by 2 units. So the right side is closer to the object than the bottom. – Martin Ender – 2014-04-15T10:11:19.540

@m.buettner Yes but he has to move up 1 unit and then 1 unit to the left, which is still 2 steps – Teun Pronk – 2014-04-15T10:20:25.520

@TeunPronk hm, interesting. by this interpretation, every object that is not in line with the planet is equidistant from two final positions. I figured the OP meant that the object first moves to be in line with the planet along the shorter axis. But he should probably clarify that. – Martin Ender – 2014-04-15T10:31:07.090

Answers

2

Perl, 156 153 148

$n=$_+1;
s/.+\n//;
$o=index$_,O;
$x=$o%$n-$-[0]%$n,
pos=$o+(($==($o-$-[0])/$n)&&$x/$=>-1&&$x/$=<=1?$=>0?-$n:$n:0<=>$x),
s/\G./x/ while s/#/./;
y/x/#/

Newlines for readability. Run with -0777p (5 added to count), input through STDIN.

More readable:

$n=$_+1;
s/.+\n//;
$o=index$_,O;
while(s/#/./){
    $x=$o%$n-$-[0]%$n;
    $==($o-$-[0])/$n;
    pos=$o+(
        $=
        &&$x/$=>-1
        &&$x/$=<=1
            ?$=>0
                ?-$n
                :$n
            :0<=>$x

    );
    s/\G./x/
}
y/x/#/

user2846289

Posted 2014-04-14T14:47:59.627

Reputation: 1 541

Wow oO =) more explanation would be nice for those who aren't intimately familiar with Perl's re engine and special variables. – skibrianski – 2014-04-20T14:40:38.340

@skibrianski, thanks. Though I did nothing special and it was easier for me to answer after notes were added to the OP, you are right: we should document our code. – user2846289 – 2014-04-21T05:34:08.130

What's maybe not obvious at first glance is using $= 'magick' variable (which can be only integer - saves us 5 characters 'int()'), and using \G anchor in search pattern. Here we set its position by assigning to pos function (whose default argument is $_). – user2846289 – 2014-04-21T05:44:55.630

6

Mathematica, 206 bytes

f=(m=Characters@StringSplit@#;o=#-Join@@m~(p=Position)~"O"&/@m~p~"#";h=If[MemberQ[#3/@o,{m_,n_}/;m#<0&&m#<=n#2<-m#],"#",e]&;{e=".",h[1,1,#&],e,n="\n",h[1,-1,r=Reverse],"O",h[-1,1,r],n,e,h[-1,-1,#&],e}<>"")&

Somewhat more readable:

f[input_] := (
  map = Characters @ StringSplit @ input;
  planet = Flatten[Position[map, "O"]];
  objects = Map[# - planet &, Position[map, "#"]];
  helper[pattern_] := If[
    Length[Position[objects, pattern]] > 0, 
    "#", 
    "."
  ];
  StringJoin[{
    ".", h[{m_, n_} /; m < 0 && m <= n < -m], ".", "\n",
    h[{m_, n_} /; n < 0 && n < m <= -n], "O", h[{m_, n_} /; n > 0 && -n <= m < n], "\n",
    ".", h[{m_, n_} /; m > 0 && -m < n <= m], "."
  }]
);

As you can see, I only take a single input which is the string containing the input map. This is because I wouldn't use the size integer anyway. If you insist on the input format, I can change the input string to the second argument for one more character.

As for the algorithm, I'm just collecting all the {Δx, Δy} pairs of the objects and look for one pair in each quadrant with the conditions passed to h. I suspect this is also the part that could be golfed down further.

Martin Ender

Posted 2014-04-14T14:47:59.627

Reputation: 184 808

I didn't know you were a Mathematica enthusiast as well! – Andrew Cheong – 2014-04-19T08:08:49.067

1@AndrewCheong I suppose that comes naturally when you're a software developer studying physics. ;) – Martin Ender – 2014-04-19T08:11:24.127

5

perl, 270 chars

3 steps: 1) find the planet and satellites in the input, 2) determine quadrant for each satellite, 3) output

sub _{"#"}$D=<>;$\=$/;for$L(1..$D){for$M(1..$D){$/=\1;$_=<>;$p=$M,$q=$L if/O/;push@s,[$M,$L] if/#/}$/=$\;<>}for(@s){$x=$_->[0]-$p,$y=$_->[1]-$q;($x<0&&$x<$y&&$y<=-$x?$l:$x>0&&-$x<=$y&&$y<$x?$r:$y<0&&$y<=$x&&$x<-$y?$u:$d)=_}$_=$l?" #":_;$u&&print;print $l."O$r";$d&&print

Less golfed:

sub _{"#"}
$D=<>;
$\=$/;
for$L(1..$D){
  $/=\1;
  for$M(1..$D){
    $_=<>;
    $p=$M,$q=$L if/O/;
    push@s,[$M,$L] if/#/;
  }
  $/=$\;
  <>
}

for(@s){
  $x=$_->[0]-$p,$y=$_->[1]-$q;  

  ($x<0&&$x<$y&&$y<=-$x ? $l :
   $x>0&&-$x<=$y&&$y<$x ? $r :
   $y<0&&$y<=$x&&$x<-$y ? $u : $d)=_;
}

$_=$l?" #":_;
$u && print;
print$l."O$r";
$d && print;

skibrianski

Posted 2014-04-14T14:47:59.627

Reputation: 1 197