Controles de gravidade

8

Sua tarefa é encontrar o destino total dos objetos que estão caindo em um planeta; você obterá entradas como esta:

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

onde O é o planeta e # são os objetos, observe que o planeta atrairá objetos das direções básicas (NEWS). Você deve produzir:

    #
   #O#
    #

ou seja, os objetos depois de chegarem ao seu destino.

O primeiro número fornecido como entrada é o comprimento da grade (nxn); no exemplo acima, é 7.

O objeto sempre deve se mover na direção mais curta (observe que as direções permitidas são apenas horizontais e verticais; o objeto não pode se mover na diagonal)

Se um objeto é equidistante de duas direções, ele deve ir no sentido horário:

    ..#       
    ...  
    O..  

Chegará a este lado:

    ...
    ...
    O#.

Se um objeto colidir com o planeta, ele irá parar. Se colidir com outro objeto, eles se tornam um objeto,

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

se tornaria:

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

Um exemplo final:

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

Resultado:

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

Nota: Você deve exibir a forma final, para que todas as saídas sejam aceitas desde que mostrem a forma final do planeta.

por exemplo para esta entrada:

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

Saída deve:

O#

ou

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

Ambos são aceitos.

Isso é então a resposta mais curta será ganha

Nota 2:

Como você deve ter notado, a .representa o vácuo, portanto, o caminho mais curto é o menor número de pontos.

Por exemplo:

.#.
...
.O.

Não é aceito para ser

O#

já que o caminho mais curto é vertical. Nota 3:

O objeto deve sempre se mover para estar na mesma linha do planeta em uma das quatro direções (escolhendo a mais curta)

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

Restrições:

2 <= n <= 100

Mhmd
fonte
Quais são os possíveis tamanhos de entrada?
Undergroundmonorail
2
Por favor, esclareça a "direção mais curta".
Ken A
@KenA Eu acho que poderia ser reformulado como: os objetos viajam na diagonal em direção ao planeta até que estejam alinhados com o planeta (depois do qual eles se movem diretamente em direção ao planeta); se um objeto acabar tocando o planeta na diagonal, mova um passo final no sentido anti-horário. Isso deve levar ao mesmo resultado que a especificação do OP. Mas o esclarecimento pelo OP seria bom.
Martin Ender
Notei que seu exemplo acima tem alguns espaços em branco no final de algumas linhas. É seguro supor que o mesmo possa ser verdade da entrada que o programa deve manipular?
precisa saber é o seguinte
@skib no. Pode ser um erro de digitação, mas as entradas não têm espaço em branco à direita.
Mhmd 15/04

Respostas:

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

Novas linhas de legibilidade. Execute com -0777p(5 adicionados à contagem), insira através de STDIN.

Mais legível:

$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
fonte
Wow oO =) mais explicações seriam legais para aqueles que não estão intimamente familiarizados com o mecanismo de ref de Perl e variáveis ​​especiais.
usar o seguinte código
@skibrianski, obrigado. Embora eu não tenha feito nada de especial e tenha sido mais fácil responder depois que as notas foram adicionadas ao OP, você está certo: devemos documentar nosso código.
user2846289
O que talvez não seja óbvio à primeira vista é usar $=a variável 'magick' (que pode ser apenas um número inteiro - economiza 5 caracteres 'int ()') e usar \Gâncora no padrão de pesquisa. Aqui, definimos sua posição atribuindo a posfunction (cujo argumento padrão é $_).
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}<>"")&

Um pouco mais legível:

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 você pode ver, apenas tomo uma entrada que é a string que contém o mapa de entrada. Isso ocorre porque eu não usaria o tamanho inteiro de qualquer maneira. Se você insistir no formato de entrada, eu posso alterar a sequência de entrada para o segundo argumento para mais um caractere.

Quanto ao algoritmo, estou apenas coletando todos os {Δx, Δy}pares dos objetos e procuro um par em cada quadrante com as condições passadas para h. Suspeito que essa também seja a parte que poderia ser jogada ainda mais.

Martin Ender
fonte
Eu também não sabia que você era um entusiasta do Mathematica!
Andrew Cheong
1
@AndrewCheong Suponho que isso ocorra naturalmente quando você é desenvolvedor de software e estuda física. ;)
Martin Enders
5

perl, 270 caracteres

3 etapas: 1) encontre o planeta e os satélites na entrada, 2) determine o quadrante para cada satélite, 3) a saída

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 golfe:

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
fonte