Simulador de gravedad

33

Declaración

Te dan una imagen fija de una serie de bolas que caen en una cuadrícula 2D. Esta cuadrícula está rodeada de paredes inmutables e irrompibles, por lo que toda la acción está contenida dentro de ellas. Su tarea es determinar cuál será el estado del escenario después de que la gravedad haga todo su trabajo.

Elementos dentro de la cuadrícula

  • - Piso, no altera la dirección de las bolas que caen.
  • \ Deslizar hacia la derecha, altera el camino de la pelota una (1) posición hacia la derecha.
  • / Deslizar hacia la izquierda, altera el camino de la pelota una (1) posición hacia la izquierda.
  • o Una bola.

Reglas

  • Las bolas caen.
  • Los pisos y los toboganes no se caen .
  • Si la pelota golpea un tobogán que lo haría atravesar una pared ( \#o #/), o cruzar un piso, el tobogán actuará como piso.
  • Cuando una bola golpea otra bola, se convertirá en una bola, pero aumentará su poder a la suma de ambas bolas.
  • Las bolas nuevas (unidas) continuarán comportándose como de costumbre.
  • Cuando una bola ya no puede moverse, se reemplaza por su poder.
  • El poder de una pelota siempre será como máximo 9.

Entrada

La cuadrícula se proporcionará en una variable de cadena con el nombre más corto en el idioma que elija. Por defecto usaremos acomo entrada. Una muestra de una entrada, exactamente como se recibió:

##########\n# \      #\n#o       #\n#  - -\o #\n#/-    \ #\n#  \oo-/\#\n#-/ \   /#\n#   \ \  #\n#       /#\n##########

Para cuadrículas aleatorias generadas, use https://repl.it/B1j3/2 . Usar mi página generada en su lugar (sin anuncios, sin basura, solo la entrada y la salida)

Nota saltos de línea son \n. Imprimir la entrada a la pantalla (no se requiere para el desafío) mostraría cosas como esta. Aunque he puesto cuatro acertijos al lado del espacio seguro.

##########  ##########  ##########  ##########
# \      #  # o    -/#  #       o#  #-o /    #
#o       #  #    \   #  # o     -#  #-- \ /\ #
#  - -\o #  #-  \    #  #    - \o#  # - -- o-#
#/-    \ #  #        #  #o /\    #  #/ \     #
#  \oo-/\#  #o  -o-  #  # /    -o#  #/ /o oo/#
#-/ \   /#  #   -/-  #  # -  o  -#  #o/      #
#   \ \  #  #    \\  #  #   \o  /#  #o-o    o#
#       /#  # \o\  /\#  #     \o #  # -\o o /#
##########  ##########  ##########  ##########

Salida

La misma cuadrícula, impresa en la pantalla con el resultado final de la potencia de la pelota. Una respuesta válida sería uno (1) de los siguientes acertijos, cada uno corresponde a la entrada en la misma posición, por supuesto, si la entrada es diferente, debe ajustar la salida. ¡No lo limites a esos cuatro!

##########  ##########  ##########  ##########
# \      #  #      -/#  #       1#  #-1 /    #
#        #  #    \   #  #       -#  #-- \ /\ #
#1 - -\  #  #-  \    #  #    - \ #  # - --  -#
#/-    \1#  #        #  #  /\    #  #/ \     #
#  \  -/\#  #   -1-  #  # /    -2#  #/ /    /#
#-/ \   /#  #   -/-  #  # -     -#  # /      #
#   \ \  #  #    \\  #  #   \   /#  # -      #
#    2  /#  #1\2\  /\#  #2   2\1 #  #2-\3 23/#
##########  ##########  ##########  ##########

Puntuación

Los idiomas competirán contra ellos mismos, así que siéntete libre de usar idiomas que no sean de golf. Para validar una solución, debo poder probarla en algún lugar para ver si funciona.

La puntuación es el número de bytes. En caso de empate, gana la primera respuesta para alcanzar el puntaje empatado.

Advertencias

  • Si no estoy seguro de cómo debería reaccionar una pelota, pregúnteme y aclararé, he sido lo más claro posible pero estoy seguro de que hay casos que son confusos.
  • Las diapositivas solo se montan si puede salir de ellas , piense en ello como una diapositiva real. Hay un tipo en la parte superior que no te deja pasar la pelota a menos que salga por el otro lado.

Ejemplos clarificadores del movimiento de la pelota.

######                       ######
#-o- #    BALL WOULD GO RD   #- - #
# \  #                       # \o #
######                       ######

######                       ######
#-o- #     BALL WOULD STAY   #-o- #
# \\ #                       # \\ #
######                       ######

######                       ######
#  -o#     BALL WOULD STAY   #  -o#
#   \#                       #   \#
######                       ######

######                       ######
#  o #     BALL WOULD STAY   #  o #
#  \/#                       #  \/#
######                       ######

######                       ######
#-o- #    BALL WOULD GO LD   #- - #
# /\ #                       #o/\ #
######                       ######

ACTUALIZACIONES

¿Cómo puedo evaluar si mi respuesta es válida?

He configurado una página simple en uno de mis sitios que le dará un rompecabezas aleatorio y su respuesta. Tome la entrada y compárela con la salida. Mi solución, sin preocuparme demasiado por el golf, es en python (generador y página también en python)389b 355b

Tabla de clasificación

Juan Cortés
fuente
1
Me recuerda a Marbelous .
Arcturus
10
Puntos de bonificación si alguien responde en Marbelous.
Mego
Borderline dupe de A Mere Bagatelle y Not Your Routine Bean Machine
Peter Taylor
suena como potencialmente un juego de pinball ascii-art
Khaled.K
@ JuanCortés, ¿por qué no usa el código de la tabla de clasificación elegante para no tener que actualizar las clasificaciones usted mismo?
usandfriends

Respuestas:

6

JavaScript (ES6), 157196

Editar char por char en lugar de fila por fila, resultado mucho mejor

g=>(s=~g.search`
`,g=[...g]).map((c,i)=>c<' '?0:g[[0,1,-1].map(d=>!d|'\\ /'[d+1]==g[d+=i]&&+g[d+=s]?g[v+=+g[d],d+v-v]=' ':0,v=c>'a'?1:+c),i]=v?v:c)&&g.join``

Nota: no maneja valores de bola> 9. Pero podría, con un costo de 18 bytes. Vea el código básico a continuación.

Fragmento de PRUEBA (mejor página completa)

F=g=>(s=~g.search`
`,g=[...g]).map((c,i)=>c<' '?0:g[[0,1,-1].map(d=>!d|'\\ /'[d+1]==g[d+=i]&&+g[d+=s]?g[v+=+g[d],d+v-v]=' ':0,v=c=='o'?1:+c),i]=v?v:c)&&g.join``

// Basic code, starting point before golfing
B=g=>{
  s = ~g.search('\n');
  (g=[...g]).map((c,i)=>{
    v = c == 'o' ? 1 : +c
    if (c>=' ' // skip newlines
        && !isNaN(v)) // digit or space
    {
      if (w=+g[i+s]) v += w, g[i+s]=' '
      if (g[i-1]=='\\' && (w=+g[i+s-1])) v += w, g[i+s-1]=' '
      if (g[i+1]=='/' && (w=+g[i+s+1])) v += w, g[i+s+1]=' '
      if (v) g[i] = v
    }
  })      
  // return g.join``
  // To handle values > 9 ...
  return g.map(v=>+v?v%10:v).join``
}  

function test() {
  O.textContent = F(I.value)
}

test()
textarea,pre { width: 15em; height: 15em; display: block; margin: 0; }
iframe { height: 25em; width: 15em}
td { vertical-align: top }
<table>
  <tr>
    <th>Test cases</th>
    <th>Input</th>
    <td></td>
    <th>Output</th>
  </tr><tr>
    <td>
    Copy/paste test cases from here <br>(courtesy of OP)
    <button onclick="T.src='http://bohem.io/wadus/index.php'">reload</button><br>
    <iframe id=T src="http://bohem.io/wadus/index.php"></iframe>
    </td>
    <td><textarea id=I>##########
#  o  o o#
# o\o o  #
#oo o/   #
#       o#
#     /o #
#\o   o  #
# o /-   #
#   o  - #
##########</textarea></td>
    <td><button onclick='test()'>Test</button></td>
    <td><pre id=O></pre></td>
  </tr>
</table>

edc65
fuente
¡Agradable! Tengo mucho que aprender sobre golf
usandfriends
¿no deberías mapear valores> 9 con v>9?9:v?
Tito el
@Titus podría, pero de hecho podría hacer lo que quiera, ya que no se espera un valor> 9, vea el comentario de OP respondiendo mi pregunta.
edc65
5

Javascript (ES6), 453 426 409 306 290 286 bytes

La primera y más obvia solución que me vino a la mente es una que mira alrededor de las diapositivas y luego se fusiona o reemplaza.

a=>{a=a.split`
`.map(b=>[...b.replace(/o/g,'1')]);for(r=1;r<a.length-1;r++){d=a[r];for(c=1;c<d.length-1;c++){e=a[r+1];f=e[c]=='\\'?c+1:e[c]=='/'?c-1:!isNaN(+e[c])?c:null;(''+d[c]).match(/[0-9]/g)&&f!=null&&!isNaN(+e[f])?(e[f]=+e[f]+ +d[c],d[c]=' '):0}}return a.map(b=>b.join``).join`
`}

Sin golf:

func = state => {
    state = state.split `
`.map(line => [...line.replace(/o/g, '1')]);

    for (r = 1; r < state.length - 1; r++) {
        thisState = state[r];
        for (c = 1; c < thisState.length - 1; c++) {
            nextState = state[r + 1];
            nc = nextState[c] == '\\' ? c + 1 : nextState[c] == '/' ? c - 1 : !isNaN(+nextState[c]) ? c : null;

            ('' + thisState[c]).match(/[0-9]/g) && nc != null && !isNaN(+nextState[nc]) ? (
                nextState[nc] = +nextState[nc] + +thisState[c],
                thisState[c] = ' '
            ) : 0;
        }
    }

    return state.map(line => line.join ``).join `
`;
}

Prueba como:

func(`##########
# -- o - #
# \\\\\\ -  #
#-       #
# o  o   #
#o \\\\ /-\\#
#      \\ #
#/-  //  #
#   /- o #
##########`)

Gracias a: @ edc65

usandfriends
fuente
Publicaré mi python cuando esté seguro de que no puedo seguir jugando golf, pero hasta ahora es el código python el que genera la respuesta. ¿De alguna manera puedo probar su código de golf en algún lugar para que pueda aparecer en la clasificación? (jsfiddle, jsbin, ideone, lo que sea)
Juan Cortés
¡Lo bajé a 355, tu movimiento!
Juan Cortés
@ JuanCortés Hecho!
usandfriends
b.replace(/o/g,'1').split`` se puede acortar a[...b.replace(/o/g,1)]
edc65
@ edc65 Creo que lo arreglé. Básicamente, siempre mantiene el poder por debajo de 10 al modificar 10.
usandfriends
4

Java, demasiados 1102 987 bytes

Porque Java.

\ o / ¡Está por debajo de 1000!

class G{class T{char s;int p=0;T(char c){s=c;}}T A=new T(' ');T[][]o;boolean i(){for(int i=1;i<o.length;i++)for(int j=1;j<o[i].length;j++)if(o[i][j].p>0){if(m(i,j,i+1,j)||o[i+1][j].s=='/'&&m(i,j,i+1,j-1)||o[i+1][j].s=='\\'&&m(i,j,i+1,j+1))return 1>0;int w=o[i][j].p;o[i][j]=new T(Integer.toString(w).charAt(0)){{p=w;}};}return 1<0;}boolean m(int a,int b,int c,int d){if(o[c][d]==A||o[c][d].p>0){o[a][b].p+=o[c][d].p;o[c][d]=o[a][b];o[a][b]=A;return 1>0;}return 1<0;}String s(){String s="";for(T[]r:o){for(T t:r)s+=t.s;s+="\n";}return s;}void f(String s){String[]r=s.split("\\\\n");o=new T[r.length][r[0].length()];for(int i=0;i<o.length;i++)for(int j=0;j<o[i].length;j++)switch(r[i].charAt(j)){case'-':o[i][j]=new T('-');break;case'\\':o[i][j]=new T('\\');break;case'/':o[i][j]=new T('/');break;case'o':o[i][j]=new T('o'){{p=1;}};break;case'#':o[i][j]=new T('#');break;default:o[i][j]=A;}}public static void main(String[]a){G g=new G();g.f(a[0]);while(g.i());System.out.println(g.s());}}

Un objetivo secundario fue poder imprimir cada iteración de la junta: basta con retirar el medio ;en while(g.i()) ; System.out.print(g.s());(aunque esto desactivar la última impresión que tiene la> conversión de energía 0-). Desafortunadamente, en esta versión, la gravedad funciona de manera extraña. Cada pase tomo la primera bola no pegada y la muevo. Cortocircuito iterate()hay menos bytes que pasar por toda la placa y luego regresar si algo cambia.

Esta es una clase principal completa, compila y ejecuta en la línea de comando con argumento:

java -jar G.jar "##########\n# o-/    #\n#-  / -/ #\n# oo   o #\n# /   \o #\n# o   o \#\n#    o   #\n#   -\o  #\n#\  \\ o/#\n##########"

Versión "legible":

class GravitySimulator {
    class Token {
        char symbol;
        int power = 0;

        Token(char c) {
            symbol = c;
        }
    }

    Token A = new Token(' ');

    Token[][] board;

    boolean iterate() {
        for (int i=1; i<board.length; i++)
            for (int j=1; j<board[i].length; j++) 
                if (board[i][j].power>0) {
                    if (move(i,j,i+1,j) || board[i+1][j].symbol=='/' && move(i,j,i+1,j-1) || board[i+1][j].symbol=='\\' && move(i,j,i+1,j+1)) return true;
                    int pow = board[i][j].power;
                    board[i][j] = new Token(Integer.toString(pow).charAt(0)){{power=pow;}};
                }
        return false;
    }

    boolean move(int x1, int y1, int x2, int y2) {
        if (board[x2][y2] == A || board[x2][y2].power>0) {
            board[x1][y1].power += board[x2][y2].power;
            board[x2][y2] = board[x1][y1];
            board[x1][y1] = A;
            return true;
        } return false;
    }

    String string() {
        String s = "";
        for (Token[] row : board) {
            for (Token token : row) s+=token.symbol;
            s+="\n";
        }
        return s;
    }

    void fromString(String s) {
        String[] rows = s.split("\\\\n");
        board = new Token[rows.length][rows[0].length()];
        for (int i=0; i<board.length; i++) 
            for (int j=0; j<board[i].length; j++) 
                switch(rows[i].charAt(j)) {
                    case '-': board[i][j]=new Token('-');break;
                    case '\\':board[i][j]=new Token('\\');break;
                    case '/': board[i][j]=new Token('/');break;
                    case 'o': board[i][j]=new Token('o'){{power=1;}};break;
                    case '#': board[i][j]=new Token('#');break;
                    default:  board[i][j]=A;
                }
    }

    public static void main(String[] args) {
        GravitySimulator g = new GravitySimulator();
        g.fromString(args[0]);
        while(g.iterate());
        System.out.println(g.string());
    }
}
CAD97
fuente
Tal java mucho más detallado. +1
Rohan Jhunjhunwala
1

Python3, 355b

g=g.replace("o","1").split("\n")
r=1
while r:
 r=0
 for y in range(len(g)):
  for x in range(len(g[y])):
   if g[y][x].isdigit():
    h=g[y+1]
    m={"/":-1,"\\":1}
    j=x+m[h[x]]if h[x]in m else x
    if("0"+h[j].strip()).isdigit():
     r=1
     g[y+1]=h[:j]+str(int(g[y][x])+int("0"+h[j]))+h[j+1:]
     g[y]=g[y][:x]+' '+g[y][x+1:]
print("\n".join(g))

Prueba aquí

Juan Cortés
fuente
0

PHP, 228 204 197 194 bytes

for($a=strtr($a,o,1);$c=$a[$i];$i++)$c>0&&(($d=$a[$t=$i+strpos($a,"
")+1])>" "?$d!="/"?$d!="\\"?$d>0:$a[++$t]<"!"||$a[$t]>0:$a[--$t]<"!"||$a[$t]>0:1)&&$a[$t]=min($a[$t]+$c,9).!$a[$i]=" ";echo$a;

produce advertencias en PHP 7.1. Insertar (int)antes $a[$t]+$cpara arreglar.

Ejecutar php -nr '$a="<string>";<code>'o probarlo en línea .

Descompostura

for($a=strtr($a,o,1);   # replace "o" with "1"
    $c=$a[$i];$i++)     # loop through string
    $c>0                    # if character is numeric
    &&(($d=$a[                  # and ...
        $t=$i+                  # 3: target position = current position + 1 line
            strpos($a,"\n")+1   # 2: width = (0-indexed) position of first newline +1
    ])>" "                  # if target char is not space
        ?$d!="/"                # and not left slide
        ?$d!="\\"               # and not right slide
        ?$d>0                   # but numeric: go
        :$a[++$t]<"!"||$a[$t]>0     # right slide: if target+1 is space or ball, then go
        :$a[--$t]<"!"||$a[$t]>0     # left slide: if target-1 is space or ball, then go
    :1                              # space: go
    )&&                     # if go:
        $a[$t]=min($a[$t]+$c,9) # move ball/merge balls
        .!$a[$i]=" "            # clear source position
    ;
echo$a;                 # print string
Titus
fuente