Simulatore di gravità


33

dichiarazione

Ti viene data una serie di palle che cadono in una griglia 2D. Questa griglia è circondata da muri immutabili e infrangibili, quindi tutta l'azione è contenuta al loro interno. Il tuo compito è determinare quale sarà lo stato dello scenario dopo che la gravità farà tutto il suo lavoro.

Elementi all'interno della griglia

  • - Pavimento, non altera la direzione delle palle che cadono.
  • \ Scorrimento a destra, altera il percorso della palla di una (1) posizione a destra.
  • / Scivolo a sinistra, altera il percorso della palla di una (1) posizione a sinistra.
  • o Una palla.

Regole

  • Le palle cadono.
  • Pavimenti e scivoli non cadono .
  • Se la palla colpisce una diapositiva che la farebbe passare attraverso un muro ( \#o #/), o attraversare un pavimento, la diapositiva fungerà da pavimento.
  • Quando una palla colpisce un'altra palla diventerà una palla, ma aumenta la loro potenza alla somma di entrambe le palle.
  • I nuovi palloni (uniti) continueranno a comportarsi normalmente.
  • Quando una palla non può più muoversi, viene sostituita dal suo potere.
  • La potenza di una palla sarà sempre al massimo 9.

Ingresso

La griglia verrà data in una variabile stringa con qualunque nome sia il più breve nella tua lingua preferita. Di default useremo acome input. Un campione di un input, esattamente come ricevuto:

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

Per le griglie casuali generate utilizzare https://repl.it/B1j3/2 . Usa invece la mia pagina generata (niente pubblicità, niente schifezze, solo l'input e l'output)

Le interruzioni di riga della nota sono \n. Stampare l'input sullo schermo (non richiesto per la sfida) mostrerebbe cose come questa. Anche se ho messo quattro puzzle a fianco nello spazio sicuro.

##########  ##########  ##########  ##########
# \      #  # 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 /#
##########  ##########  ##########  ##########

Produzione

La stessa griglia, stampata sullo schermo con il risultato finale della potenza della palla. Una risposta valida sarebbe uno (1) dei seguenti puzzle, ognuno corrisponde all'ingresso nella stessa posizione, ovviamente se l'ingresso è diverso dovresti regolare l'uscita. Non limitarlo a quei quattro!

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

Punto

Le lingue competeranno contro se stesse, quindi sentiti libero di usare lingue non golf. Per convalidare una soluzione devo essere in grado di testarlo da qualche parte per vedere che funziona !.

Il punteggio è il numero di byte. In caso di pareggio, vince la prima risposta per raggiungere il punteggio pareggiato.

Avvertenze

  • Se non sei sicuro di come debba reagire una palla, chiedimi e chiarirò, sono stato il più chiaro possibile ma sono sicuro che ci sono casi che confondono.
  • Le diapositive vengono guidate solo se puoi uscirne , pensaci come una vera diapositiva. C'è un ragazzo in alto che non ti fa passare la palla a meno che non esca dall'altra parte.

Esempi chiarificatori di movimento della palla

######                       ######
#-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/\ #
######                       ######

AGGIORNAMENTI

Come posso verificare se la mia risposta è valida?

Ho creato una semplice pagina in uno dei miei siti che ti darà un puzzle casuale e la sua risposta. Prendi l'input e confrontalo con l'output. La mia soluzione, senza preoccuparsi troppo del golf, è in Python (generatore e pagina anche Python)389b 355b

Classifica


1
Mi viene in mente Marbelous .
Arturo

10
Punti bonus se qualcuno risponde in Marbelous.
Mego


sembra potenzialmente un gioco di flipper ascii-art
Khaled.K

@ JuanCortés perché non usi il codice della classifica in modo da non dover aggiornare tu stesso le classifiche?
usandfriends

Risposte:


6

JavaScript (ES6), 157 196

Modifica i caratteri per carattere anziché riga per riga, risultato molto migliore

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: non gestisce valori di palla> 9. Ma potrebbe, con un costo di 18 byte. Vedi il codice di base di seguito.

Snippet di TEST (migliore pagina intera)

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>


Bello! Ho molto da imparare sui modi del golf
usandfriends

non dovresti mappare i valori> 9 con v>9?9:v?
Tito

@Titus Potrei, ma in effetti potrei fare quello che voglio, dato che un valore> 9 non è previsto, vedi il commento di OP che risponde alla mia domanda.
edc65,

5

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

La prima e più ovvia soluzione che mi è venuta in mente è quella che si guarda intorno alle diapositive e poi si fonde o sostituisce.

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`
`}

Ungolfed:

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 `
`;
}

Prova come:

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

Grazie a: @ edc65


Pubblicherò il mio python quando sono sicuro di non poterlo più giocare a golf, ma finora è il codice python che sta generando la risposta. In qualche modo posso testare il tuo codice golf da qualche parte in modo da farti comparire in classifica? (jsfiddle, jsbin, ideone, qualunque cosa)
Juan Cortés,

ottenuto a 355, la tua mossa!
Juan Cortés,

@ JuanCortés Fatto!
usandfriends

b.replace(/o/g,'1').split`` può essere abbreviato in[...b.replace(/o/g,1)]
edc65

@ edc65 Penso di averlo corretto. Fondamentalmente mantiene sempre il potere sotto i 10 modificando 10.
Usandfriends

4

Java, troppi 1102 987 byte

Perché, Java.

\ o / È meno di 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 obiettivo lato era quello di poter stampare ogni iterazione del consiglio di amministrazione: è sufficiente rimuovere il mezzo ;in while(g.i()) ; System.out.print(g.s());(anche se questo non disabilita l'ultimo di stampa che ha il> di conversione di potenza 0-). Sfortunatamente, in questa versione, la gravità funziona in modo strano. Ad ogni passaggio prendo la prima palla non bloccata e la muovo. In corto circuito iterate()ci sono meno byte che andare su tutta la scheda e poi tornare se qualcosa è cambiato.

Questa è una classe principale completa, compilare ed eseguire sulla riga di comando con argomento:

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

Versione "leggibile":

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());
    }
}

Tale java molto prolisso. +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))

Prova qui


0

PHP, 228 204 197 194 byte

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;

genera avvisi in PHP 7.1. Inserisci (int)prima $a[$t]+$cdi risolvere.

Corri con php -nr '$a="<string>";<code>'o provalo online .

abbattersi

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.