Changer de gravité

14

Défi

Vous êtes donné une représentation ASCII-art de caractères sur un plan comme entrée par toute méthode raisonnable. Il ne contiendra que:

  • [a-z]représentant des personnages mobiles. Chaque lettre apparaîtra au tableau au plus une fois.
  • # représentant des murs inamovibles
  • . représentant un espace vide

Par exemple:

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

Vous recevez également une chaîne représentant les changements de gravité. Il ne contiendra que:

  • > représentant un changement de gravité vers la droite
  • < représentant un changement de gravité vers la gauche
  • ^ représentant un changement de gravité vers le haut
  • v représentant un changement de gravité vers le bas

Par exemple:

v>^

Votre programme doit simuler chaque changement de gravité de manière séquentielle jusqu'à ce que tous les personnages cessent de bouger (ils heurtent un mur ou un autre personnage). Les personnages qui "tombent du bord de la carte" sont définitivement supprimés et les personnages peuvent "s'empiler" les uns sur les autres.

Dans cet exemple, au début il y a la gravité vers le bas ( v), donc c, e, g, h, iet jtomber en bas de la carte. Tous les autres personnages glissent vers le bas jusqu'à atteindre un mur, laissant la carte comme ceci:

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

Ensuite, nous passons à la gravité vers la droite ( >), ce qui nous laisse avec ceci: Notez comment les apiles à côté du d.

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

Enfin, nous simulons la gravité vers le haut ( ^), pendant laquelle le aet le btombent de la carte.

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

Votre tâche consiste à générer les caractères restants après les décalages gravitationnels. Ils peuvent être donnés dans n'importe quel ordre. Pour cet exemple, vous pouvez générer n'importe quelle permutation dedfq .

Cas de test

Pour la carte suivante:

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

Pour la carte suivante:

######
#....#
abcdef
#.gh..
######
>   = <nothing>
<   = gh
^>  = bcde
v<  = bghef
jrich
la source
Comment l'apport est-il donné? Liste des chaînes? Argument de fonction? STDIN?
Leaky Nun
@KennyLau Toutes ces options sont très bien. L'entrée et la sortie peuvent être tout ce qui est raisonnable pour votre langue.
jrich
Assez lié.
Martin Ender

Réponses:

4

JavaScript (ES6), 251 233 octets

(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,``)

Edit: 18 octets enregistrés grâce à @WashingtonGuedes.

Fonctionne en faisant tourner la grille d'entrée quatre fois pour chaque caractère directionnel, mais dans la direction où le caractère directionnel correspond au caractère de boucle, nous faisons la chose de gravité gauche. Pseudocode:

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
la source
3

JavaScript (ES6), 199

Même algortihm de la réponse de @ Neil. La grille est tournée quatre fois pour chaque caractère directionnel, lorsque dans la bonne position le décalage de gravité vers la gauche est appliqué à chaque ligne.

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
la source
2

Pyth, 143 octets

(Avons-nous vraiment besoin d'autant d'octets?)

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

Essayez-le en ligne!

Comment ça fonctionne

Nous définissons une fonction left qui fait la gravité vers la gauche.

Ensuite, les autres directions sont implémentées en jouant avec le tableau de sorte que la direction souhaitée soit vers la gauche, puis faites left .

L'algorithme de leftest ici:

  • Procédez comme suit jusqu'à idempotence:
  • Remplacez ".X"par "X.", où Xreprésente une lettre.

L'ensemble du programme est divisé en 6 sections:

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

Première section

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

Deuxième section

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

Troisième section

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)

Quatrième section

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

Cinquième section

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)

Sixième section

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

Rubis, 306 octets

Fonction anonyme. Technique assez détournée qui pourrait probablement être optimisée.

->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}
Encre de valeur
la source