Controles de gravedad

8

Su tarea es encontrar el destino total de los objetos que están cayendo a un planeta, obtendrá entradas como esta:

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

donde O es el planeta y # son los objetos, tenga en cuenta que el planeta atraerá objetos desde las direcciones básicas (NOTICIAS). Deberías generar:

    #
   #O#
    #

es decir, los objetos después de llegar a su destino.

El primer número dado como entrada es la longitud de la cuadrícula (nxn), en el ejemplo anterior es 7.

El objeto siempre debe moverse en la dirección más corta (tenga en cuenta que las direcciones permitidas son solo horizontales y verticales; el objeto no puede moverse en diagonal)

Si un objeto es equidistante de dos direcciones, debe ir en sentido horario:

    ..#       
    ...  
    O..  

Llegará a este lado:

    ...
    ...
    O#.

Si un objeto choca con el planeta, se detendrá. Si choca con otro objeto, se convierten en un objeto,

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

se convertiría:

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

Un último ejemplo:

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

Salida:

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

Nota: Debe generar la forma final, de modo que todas las salidas se acepten siempre que muestren la forma final del planeta.

por ejemplo para esta entrada:

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

Debería dar salida:

O#

o

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

Ambos son aceptados.

Este es el por lo que la respuesta más corta ganará

Nota 2:

Como habrás notado, un .representa el vacío, por lo que el camino más corto es el menor número de puntos.

Por ejemplo:

.#.
...
.O.

No se acepta ser

O#

ya que el camino más corto es vertical. Nota 3:

El objeto siempre debe moverse para estar en la misma línea con el planeta en una de las cuatro direcciones (elegir la más corta)

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

Restricciones:

2 <= n <= 100

Mhmd
fuente
¿Cuáles son los tamaños de entrada posibles?
undergroundmonorail
2
Aclare "la dirección más corta".
Ken A
@KenA Creo que podría reformularse como: los objetos viajan diagonalmente hacia el planeta hasta que estén en línea con el planeta (después de lo cual se moverán directamente hacia el planeta); Si un objeto termina tocando el planeta en diagonal, mueva un paso final en sentido antihorario. Esto debería conducir al mismo resultado que la especificación del OP. Pero la aclaración por parte del OP estaría bien.
Martin Ender
Noté que su ejemplo anterior tiene algunos espacios en blanco al final de algunas líneas. ¿Es seguro asumir que lo mismo puede decirse de la entrada que se espera que maneje el programa?
skibrianski
@skib no. Puede ser un error tipográfico, pero las entradas no tienen espacios en blanco al final.
Mhmd

Respuestas:

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/#/

Nuevas líneas de legibilidad. Ejecute con -0777p(5 agregados para contar), ingrese a través de STDIN.

Más legible:

$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/#/
usuario2846289
fuente
Wow oO =) más explicación sería bueno para aquellos que no están íntimamente familiarizados con el motor de Perl y las variables especiales.
skibrianski
@skibrianski, gracias. Aunque no hice nada especial y fue más fácil para mí responder después de agregar notas al OP, tiene razón: debemos documentar nuestro código.
user2846289
Lo que tal vez no sea obvio a primera vista es usar $=la variable 'magick' (que puede ser solo un número entero; nos ahorra 5 caracteres 'int ()') y usar el \Gancla en el patrón de búsqueda. Aquí establecemos su posición asignando a la posfunción (cuyo argumento predeterminado es $_).
user2846289
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}<>"")&

Algo más legible:

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], "."
  }]
);

Como puede ver, solo tomo una sola entrada, que es la cadena que contiene el mapa de entrada. Esto se debe a que no usaría el tamaño entero de todos modos. Si insiste en el formato de entrada, puedo cambiar la cadena de entrada al segundo argumento para un carácter más.

En cuanto al algoritmo, solo estoy recopilando todos los {Δx, Δy}pares de objetos y busco un par en cada cuadrante con las condiciones a las que se pasó h. Sospecho que esta también es la parte que podría jugar más golf.

Martin Ender
fuente
¡No sabía que también eras un entusiasta de Mathematica!
Andrew Cheong
1
@ AndrewCheong Supongo que eso es natural cuando eres un desarrollador de software que estudia física. ;)
Martin Ender
5

perl, 270 caracteres

3 pasos: 1) encontrar el planeta y los satélites en la entrada, 2) determinar el cuadrante para cada satélite, 3) la salida

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

Menos golfizado:

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
fuente