Gravidade de comutação


14

Desafio

Você recebe uma representação de caracteres ASCII-art em um plano como entrada por qualquer método razoável. Isso conterá apenas:

  • [a-z]representando caracteres móveis. Cada letra aparecerá no quadro no máximo uma vez.
  • # representando paredes imóveis
  • . representando espaço vazio

Por exemplo:

abcdef.gh#..
.......ij.#.
#..#.......#
...#.#...###
.#.......#q#
.........###

Você também recebe uma string representando as mudanças na gravidade. Isso conterá apenas:

  • > representando uma mudança na gravidade para a direita
  • < representando uma mudança na gravidade para a esquerda
  • ^ representando uma mudança na gravidade ascendente
  • v representando uma mudança na gravidade descendente

Por exemplo:

v>^

Seu programa deve simular cada alteração na gravidade sequencialmente até que todos os personagens parem de se mover (eles atingem uma parede ou outro personagem). Os caracteres que "caem da borda do mapa" são removidos permanentemente e os caracteres podem "empilhar" uns sobre os outros.

Neste exemplo, no início há gravidade para baixo ( v), então c, e, g, h, i, e jcair fora da parte inferior do mapa. Todos os outros personagens deslizam para baixo até atingir uma parede, deixando o mapa assim:

.........#..
a..d......#.
#..#.f.....#
.b.#.#...###
.#.......#q#
.........###

Em seguida, passamos à gravidade para a direita ( >), o que nos deixa com isso: Observe como as apilhas ao lado de d.

.........#..
........ad#.
#..#......f#
..b#.#...###
.#.......#q#
.........###

Finalmente, simulamos a gravidade ascendente ( ^), durante a qual o ae o bcaem do mapa.

.........#..
.........d#.
#..#......f#
...#.#...###
.#.......#q#
.........###

Sua tarefa é produzir os caracteres restantes após as mudanças gravitacionais. Eles podem ser dados em qualquer ordem. Neste exemplo, você pode gerar qualquer permutação de dfq.

Casos de teste

Para o seguinte mapa:

abcde
.....
##.##
v   =  abde
v>  =  <nothing>

Para o seguinte mapa:

######
#....#
abcdef
#.gh..
######
>   = <nothing>
<   = gh
^>  = bcde
v<  = bghef

Como a entrada é fornecida? Lista de strings? Argumento de função? STDIN?
Leaky Nun #

@KennyLau Todas essas opções são boas. Entrada e saída podem ser razoáveis ​​para o seu idioma.
jrich

Respostas:


4

JavaScript (ES6), 251 233 bytes

(m,d,r=`replace`)=>[...d].map(c=>[...`<^>v`].map(d=>m=[...(m=(c==d?m[r](/[.\w]+/g,s=>s[r](/\./g,``)+s[r](/\w/g,``))[r](/^\w+/gm,s=>s[r](/./g,`.`)):m).split`
`)[0]].map((_,i)=>m.map(s=>s[i]).join``).reverse().join`
`))&&m[r](/\W/g,``)

Editar: salvou 18 bytes graças a @WashingtonGuedes.

Funciona girando a grade de entrada quatro vezes para cada caractere direcional, mas na direção em que o caractere direcional corresponde ao caractere de loop, fazemos a coisa da gravidade esquerda. Pseudo-código:

function slideleft(map) {
    map = map.replace(/[.\w+]/g, match=>movedotstoend(match));
    map = map.replace(/^\w+/gm, match=>changetodots(match));
}
function rotate(map) {
    return joinrows(reverse([for each (column of rows(map)[0])
            joinrow([for each (row of rows(map)) row[column]])
           ]));
}
function gravity(map, directions) {
    for each (direction of directions) {
        for each (angle of '<^>v') {
            if (direction == angle) map = slideleft(map);
            map = rotate(map);
        }
    }
    return letters(map);
}

3

JavaScript (ES6), 199

O mesmo algoritmo da resposta de @ Neil. A grade é girada quatro vezes para cada caractere direcional, quando na posição direita o deslocamento da gravidade para a esquerda é aplicado a cada linha.

x=>y=>(x=>{for(d of y){R='';for(e of'^>v<')x=[...x[0]].map((c,i)=>e!=d?x.map(r=>r[i]).join``:x.map(r=>(c=r[i])<'.'?(q+=p+c,p=''):c>'.'&&q?(q+=c,R+=c):p+='.',q=p='')&&q+p).reverse();}})(x.split`
`)||R

F=x=>y=>(x=>{for(d of y){R='';for(e of'^>v<')x=[...x[0]].map((c,i)=>e!=d?x.map(r=>r[i]).join``:x.map(r=>(c=r[i])<'.'?(q+=p+c,p=''):c>'.'&&q?(q+=c,R+=c):p+='.',q=p='')&&q+p).reverse();}})(x.split`
`)||R

// Less golfed

U=(x,y)=>
{
  x = x.split`\n`;
  for(d of y)
  {
    R = '';
    for(e of '^>v<')
      x = [...x[0]].map( 
        (c,i) => e != d
        ? x.map( r => r[i] ).join`` // basic rotation
        : x.map( // rotation with gravity shift
          r=> (c=r[i])<'.' ? (q+=p+c,p='') : c>'.'&&q?(q+=c,R+=c) : p+='.', q=p=''
        ) && q+p
      ).reverse();
  }
  return R
}

console.log=x=>O.textContent+=x+'\n'

;[
  ['abcdef.gh#..\n.......ij.#.\n#..#.......#\n...#.#...###\n.#.......#q#\n.........###',
   [['v>^','dfq']]
  ],
  ['abcde\n.....\n##.##',[['v','abde'],['v>','']]],
  ['######\n#....#\nabcdef\n#.gh..\n######',[['>',''],['<','gh'],['^>','bcde'],['v<','befgh']]]
].forEach(t => {
  var i=t[0]
  console.log(i)
  t[1].forEach(([d,k])=>{
    var r=F(i)(d),ok=[...r].sort().join``==k
    console.log((ok?'OK ':'KO ')+d+' : '+r+(ok?'':' (expected '+k+')'))
  })
  console.log('')
})
<pre id=O></pre>


2

Pitão, 143 bytes

(Nós realmente precisamos de tantos bytes?)

JhQKeQMe.u:N+"\."H+H"."G;DybVkI}NG=gkN;D'bVlJ=k@JNykVkI}HG=:kH\.).?B)=XJNk;VKIqN\<'J)IqN\v=C_J'J=_CJ)IqN\>=C_CJ'J=C_CJ)IqN\^=CJ'J=CJ;VJVNI}HGpH

Experimente online!

Como funciona

Nós definimos uma função left que faz a coisa da gravidade para a esquerda.

Em seguida, as outras direções são implementadas mexendo com a matriz, para que a direção desejada fique à esquerda, e faça left.

O algoritmo de leftestá aqui:

  • Faça o seguinte até idempotente:
  • Substitua ".X"por "X.", onde Xrepresenta uma letra.

Todo o programa está dividido nas 6 seções a seguir:

JhQKeQ
Me.u:N+"\."H+H"."G;
DybVkI}NG=gkN;
D'bVlJ=k@JNykVkI}HG=:kH\.).?B)=XJNk;
VKIqN\<'J)IqN\v=C_J'J=_CJ)IqN\>=C_CJ'J=C_CJ)IqN\^=CJ'J=CJ;
VJVNI}HGpH

Primeira sessão

JhQKeQ     Q auto-initialized to evaluate(input())
JhQ        J = Q[0]
   KeQ     K = Q[len(Q)-1]

Segunda seção

Me.u:N+"\."H+H"."G;   @memoized
M                 ;   def g(G,H):
  .u             G      repeat_until_idempotent(start:G, as N):
    :Nxxxxxxyyyyy         return N.replace(xxxxxx,yyyyy)
      +"\."H                               "\."+H
            +H"."                                 H+"."

Terceira seção

DybVkI}NG=gkN;    @memoized
Dyb          ;    def y(b):
   Vk               for N in k:     --TAKES GLOBAL VARIABLE k
     I}NG             if N in G:    --G pre-initialized to "abcde...z"
         =gkN           k = g(k,N)

Quarta seção

D'bVlJ=k@JNykVkI}HG=:kH\.).?B)=XJNk;  @memoized
D'b                                ;  def single_quote(b):
   VlJ                       )          for N in range(len(J)): --TAKES GLOBAL VARIABLE J
      =k@JN                               k = J[N] --SETS GLOBAL VARIABLE k
           yk                             y(k) --returns nothing, but MODIFIES GLOBAL VARIABLE k
             Vk                           for H in k:
               I}HG      )                  if H in G:
                   =:kH\.                     k = k.replace(H,".")
                          .?                else:
                            B                 break
                              =XJNk     J[N] = k --MODIFIES GLOBAL VARIABLE J

Quinta seção

VKIqN\<'J)IqN\v=C_J'J=_CJ)IqN\>=C_CJ'J=C_CJ)IqN\^=CJ'J=CJ;
VK                                                       ; for N in K:
  IqN\<  )                                                   if N == '<':
       'J                                                      single-quote(J)
          IqN\v          )                                   if N == 'v':
               =C_J                                            J = transpose(reverse(J))
                   'J                                          single-quote(J)
                     =_CJ                                      J = reverse(transpose(J))
                          IqN\>            )                 if N == '>':
                               =C_CJ                           J = transpose(reverse(transpose(J)))
                                    'J                         single-quote(J)
                                      =C_CJ                    J = transpose(reverse(transpose(J)))
                                            IqN\^            if N == '^':
                                                 =CJ           J = transpose(J)
                                                    'J         single-quote(J)
                                                      =CJ      J = transpose(J)

Sexta seção

VJVNI}HGpH
VJ           for N in J:
  VN           for H in N:
    I}HG         if H in G: --G = "abc...z"
        pH         print(H)

1

Ruby, 306 bytes

Função anônima. Técnica bastante tortuosa que provavelmente poderia ser otimizada.

->s,d{w=[];x=y=0;m={}
s.chars.map{|c|c>?!?(c<?A?c<?.?w<<[x,y]:0:m[c]=[x,y]
x+=1):(x=0;y+=1)}
d.chars.map{|c|q=[c<?=?-1:c<?A?1:0,c>?a?1:c>?A?-1:0];e=1
(n=m.clone.each{|k,v|z=[v[0]+q[0],v[1]+q[1]]
w.index(z)||m.value?(z)?0:m[k]=z}
m.reject!{|k,v|i,j=v;i<0||i>=x||j<0||j>y}
e=(m!=n ?1:p))while e}
m.keys.join}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.