Schwerkraft wechseln

14

Herausforderung

Sie erhalten eine ASCII-artige Darstellung von Zeichen in einer Ebene als Eingabe nach einer beliebigen vernünftigen Methode. Dies wird nur enthalten:

  • [a-z]bewegliche Figuren darstellen. Jeder Buchstabe erscheint höchstens einmal an der Tafel.
  • # unbewegliche Wände darstellen
  • . leeren Raum darstellen

Beispielsweise:

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

Sie erhalten auch eine Zeichenfolge, die die Schwerkraftänderungen darstellt. Dies wird nur enthalten:

  • > eine Änderung der Schwerkraft nach rechts darstellt
  • < eine Änderung der Schwerkraft nach links darstellt
  • ^ eine Änderung der Aufwärtsschwerkraft darstellt
  • v eine Änderung der abwärts gerichteten Schwerkraft darstellt

Beispielsweise:

v>^

Ihr Programm muss jede Änderung der Schwerkraft nacheinander simulieren, bis sich alle Zeichen nicht mehr bewegen (sie treffen auf eine Wand oder ein anderes Zeichen). Zeichen, die "vom Rand der Karte fallen", werden dauerhaft entfernt, und Zeichen können übereinander "gestapelt" werden.

In diesem Beispiel zu Beginn gibt es nach unten Gewicht ( v), so c, e, g, h, i, und jdie Unterseite der Karte fallen. Alle anderen Zeichen gleiten nach unten, bis sie auf eine Wand treffen, und verlassen die Karte wie folgt:

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

Dann bewegen wir uns weiter zur Schwerkraft nach rechts ( >), was uns dazu veranlasst: Beachten Sie, wie die aStapel neben dem d.

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

Zum Schluss simulieren wir die Aufwärtsschwerkraft ( ^), während derer das aund das bvon der Karte fallen.

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

Ihre Aufgabe ist es, die verbleibenden Zeichen nach den Gravitationsverschiebungen auszugeben. Sie können in beliebiger Reihenfolge angegeben werden. In diesem Beispiel können Sie eine beliebige Permutation von ausgeben dfq.

Testfälle

Für die folgende Karte:

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

Für die folgende Karte:

######
#....#
abcdef
#.gh..
######
>   = <nothing>
<   = gh
^>  = bcde
v<  = bghef
jrich
quelle
Wie erfolgt die Eingabe? Liste der Zeichenfolgen? Funktionsargument? STDIN?
Undichte Nonne
@KennyLau All diese Optionen sind in Ordnung. Eingabe und Ausgabe können für Ihre Sprache alles Mögliche sein.
Jrich
Etwas verwandt.
Martin Ender

Antworten:

4

JavaScript (ES6), 251 233 Byte

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

Bearbeiten: 18 Bytes dank @WashingtonGuedes gespeichert.

Arbeitet durch viermaliges Drehen des Eingabegitters für jedes Richtungszeichen, aber in der Richtung, in der das Richtungszeichen mit dem Schleifenzeichen übereinstimmt, machen wir die Sache mit der linken Schwerkraft. 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
quelle
3

JavaScript (ES6), 199

Gleiche Antwort von @ Neil. Das Gitter wird für jedes Richtungszeichen viermal gedreht, wenn in der rechten Position die Schwerkraftverschiebung nach links auf jede Zeile angewendet wird.

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
quelle
2

Pyth, 143 Bytes

(Brauchen wir wirklich so viele 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

Probieren Sie es online!

Wie es funktioniert

Wir definieren eine Funktion, leftdie die Schwerkraft nach links ausübt.

Dann werden die anderen Richtungen implementiert, indem mit dem Array so gearbeitet wird, dass die gewünschte Richtung nach links zeigt left.

Der Algorithmus von leftist hier:

  • Gehen Sie wie folgt vor, bis Sie idempotent sind:
  • Ersetzen ".X"durch "X.", wobei Xein Buchstabe steht.

Das gesamte Programm ist in die folgenden 6 Abschnitte unterteilt:

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

Erster Abschnitt

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

Zweiter Abschnitt

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

Dritter Abschnitt

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)

Vierter Abschnitt

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

Fünfter Abschnitt

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)

Sechster Abschnitt

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

Ruby, 306 Bytes

Anonyme Funktion. Ziemlich umständliche Technik, die wahrscheinlich optimiert werden könnte.

->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}
Wert Tinte
quelle