Cambio de gravedad

14

Desafío

Se le da una representación ASCII-art de caracteres en un plano como entrada por cualquier método razonable. Esto solo contendrá:

  • [a-z]representando personajes movibles. Cada letra aparecerá en la pizarra como máximo una vez.
  • # representando paredes inamovibles
  • . representando el espacio vacío

Por ejemplo:

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

También se le da una cadena que representa los cambios en la gravedad. Esto solo contendrá:

  • > representando un cambio a la gravedad hacia la derecha
  • < representando un cambio a la gravedad hacia la izquierda
  • ^ representando un cambio a la gravedad ascendente
  • v representando un cambio a la gravedad descendente

Por ejemplo:

v>^

Su programa debe simular cada cambio de gravedad secuencialmente hasta que todos los personajes dejen de moverse (golpean una pared u otro personaje). Los personajes que "caen del borde del mapa" se eliminan permanentemente, y los personajes pueden "apilarse" uno encima del otro.

En este ejemplo, en el inicio hay gravedad hacia abajo ( v), por lo que c, e, g, h, i, y jcaen fuera de la parte inferior del mapa. Todos los demás personajes se deslizan hacia abajo hasta golpear una pared, dejando el mapa así:

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

Luego, pasamos a la gravedad hacia la derecha ( >), lo que nos deja con esto: tenga en cuenta cómo las apilas al lado de d.

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

Finalmente, simulamos la gravedad hacia arriba ( ^), durante la cual la ay la bcaída del mapa.

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

Su tarea es generar los caracteres restantes después de los cambios gravitacionales. Se pueden dar en cualquier orden. Para este ejemplo, puede generar cualquier permutación de dfq.

Casos de prueba

Para el siguiente mapa:

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

Para el siguiente mapa:

######
#....#
abcdef
#.gh..
######
>   = <nothing>
<   = gh
^>  = bcde
v<  = bghef
jrich
fuente
¿Cómo se da la entrada? Lista de cadenas? Argumento de la función? STDIN?
Leaky Nun
@KennyLau Todas esas opciones están bien. La entrada y la salida pueden ser razonables para su idioma.
jrich
Algo relacionado.
Martin Ender

Respuestas:

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: 18 bytes guardados gracias a @WashingtonGuedes.

Funciona girando la cuadrícula de entrada cuatro veces para cada carácter direccional, pero en la dirección donde el carácter direccional coincide con el carácter de bucle, hacemos lo de la gravedad izquierda. Pseudocó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);
}
Neil
fuente
3

JavaScript (ES6), 199

El mismo algoritmo de la respuesta de @ Neil. La cuadrícula se gira cuatro veces para cada carácter direccional, cuando en la posición derecha se aplica el desplazamiento de gravedad a la izquierda a cada fila.

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>

edc65
fuente
2

Pyth, 143 bytes

(¿Realmente necesitamos 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

Pruébalo en línea!

Cómo funciona

Definimos una función leftque hace lo de la gravedad hacia la izquierda.

Luego, las otras direcciones se implementan jugando con la matriz de modo que la dirección deseada esté hacia la izquierda, luego hazlo left.

El algoritmo de leftestá aquí:

  • Haga lo siguiente hasta que sea idempotente:
  • Reemplazar ".X"con "X.", donde Xrepresenta una letra.

Todo el programa se divide en las siguientes 6 secciones:

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

Primera sección

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

Segunda sección

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+"."

Tercera sección

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)

Cuarta sección

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 sección

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 sección

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

Rubí, 306 bytes

Función anónima. Técnica bastante tortuosa que probablemente podría optimizarse.

->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}
Tinta de valor
fuente