Simulateur de gravité

33

Déclaration

Vous obtenez une image d'une série de boules tombant dans une grille 2D. Cette grille est entourée de murs immuables et incassables afin que toute l'action soit contenue à l'intérieur. Votre tâche consiste à déterminer quel sera l'état du scénario une fois que la gravité aura fait tout son travail.

Éléments à l'intérieur de la grille

  • - Le sol ne change pas la direction des balles qui tombent.
  • \ Glisser à droite, modifie la trajectoire de la balle une (1) position à droite.
  • / Glissière gauche, modifie la trajectoire de la balle une (1) position gauche.
  • o Un ballon.

Règles

  • Les balles tombent.
  • Les sols et les toboggans ne tombent pas .
  • Si la balle heurte une glissière qui la ferait traverser un mur ( \#ou #/) ou traverserait un sol, la glissière agirait comme un sol.
  • Quand une balle frappe une autre balle, elle deviendra une balle mais augmentera sa puissance jusqu'à la somme des deux balles.
  • Les nouvelles balles (jointes) continueront à se comporter comme d'habitude.
  • Quand une balle ne peut plus bouger, elle est remplacée par sa puissance.
  • La puissance d'une balle sera toujours au maximum de 9.

Contribution

La grille sera donnée dans une variable chaîne avec le nom le plus court dans la langue de votre choix. Par défaut nous utiliserons acomme entrée. Un échantillon d'une entrée, exactement telle que reçue:

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

Pour les grilles aléatoires générées, utilisez https://repl.it/B1j3/2 . Utilisez ma page générée à la place (pas de publicité, pas de merde, juste l'entrée et la sortie)

Remarquez les sauts de ligne \n. Imprimer l'entrée à l'écran (non requis pour le défi) montrerait des choses comme ça. Bien que j'ai mis quatre énigmes à côté de l'espace sécurisé.

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

Sortie

La même grille, imprimée à l'écran avec le résultat final de la puissance de la balle. Une réponse valide serait un (1) des énigmes suivants, chacun correspondant à l’entrée à la même position. Bien entendu, si l’entrée est différente, vous devez ajuster la sortie. Pas le limiter à ces quatre!

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

But

Les langues se feront concurrence, alors n'hésitez pas à utiliser des langues non-golf. Pour valider une solution, je dois pouvoir la tester quelque part pour voir si elle fonctionne !.

Le score est le nombre d'octets. En cas d'égalité, la première réponse pour atteindre le score d'égalité l'emporte.

Avertissements

  • Si vous n'êtes pas sûr de la réaction d'un ballon, demandez-le-moi et je clarifierai. J'ai été aussi clair que possible, mais je suis sûr que certains cas prêtent à confusion.
  • Les diapositives ne sont montées que si vous pouvez les quitter , pensez-y comme une vraie diapositive. Il y a un gars au sommet qui ne vous laisse pas passer à côté du ballon, à moins que le ballon ne sorte par l'autre côté.

Clarifier des exemples de mouvement de balle

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

MISES À JOUR

Comment puis-je tester si ma réponse est valide?

J'ai mis en place une simple page sur l'un de mes sites qui vous donnera une énigme aléatoire et sa réponse. Prenez l’entrée et comparez-la à la sortie. Ma solution, sans trop m'inquiéter du golf, est en python (générateur, et page aussi en python)389b 355b

Classement

Juan Cortés
la source
1
Je me souviens de Marbelous .
Arcturus
10
Des points bonus si quelqu'un répond à Marbelous.
Mego
Cela ressemble potentiellement à un jeu de flipper ascii-art
Khaled.K
@ JuanCortés, pourquoi n'utilisez-vous pas le code du tableau des leaders de fantaisie pour ne pas avoir à mettre à jour le classement vous-même?
usandfriends

Réponses:

6

JavaScript (ES6), 157 196

Éditer caractère par caractère au lieu de ligne par ligne, résultat bien meilleur

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

Remarque: ne gère pas les valeurs de billes> 9. Mais cela pourrait arriver, avec un coût de 18 octets. Voir le code de base ci-dessous.

Extrait de test (meilleure page complète)

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
la source
Agréable! J'ai beaucoup à apprendre les façons de golf
usandfriends
ne devriez-vous pas mapper les valeurs> 9 avec v>9?9:v?
Titus
@ Titus je pouvais, mais en fait je pourrais faire ce que je veux, car une valeur> 9 n'est pas attendue, voir le commentaire de OP répondant à ma question.
edc65
5

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

La première et la plus évidente des solutions qui m’est venue à l’esprit est celle qui consiste à regarder autour des diapositives puis à les fusionner ou à les remplacer.

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

Testez comme:

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

Merci à: @ edc65

amis et amis
la source
Je posterai mon python quand je suis sûr que je ne peux plus jouer au golf, mais jusqu'à présent, c'est le code python qui génère la réponse. Est-ce que je peux tester votre code de golf quelque part pour pouvoir vous placer au classement? (jsfiddle, jsbin, ideone, peu importe)
Juan Cortés
descendu à 355, votre déménagement!
Juan Cortés
@ JuanCortés Fait!
usandfriends
b.replace(/o/g,'1').split`` peut être raccourci à[...b.replace(/o/g,1)]
edc65
@ edc65 Je pense que je l'ai corrigé. En gros, il garde toujours la puissance inférieure à 10 en mod'ing 10.
usandfriends
4

Java, trop nombreux 1102 987 octets

Parce que, Java.

\ o / il est sous 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 objectif secondaire était d' être capable d'imprimer chaque itération du conseil d' administration: il suffit de retirer le milieu ;en while(g.i()) ; System.out.print(g.s());(Bien que cela ne désactive la dernière impression qui a le front 0-> conversion de puissance). Malheureusement, dans cette version, la gravité fonctionne étrangement. À chaque passage, je prends la première balle non collée et la déplace. En court-circuitant, iterate()il y a moins d'octets que de parcourir l'ensemble du tableau puis de retourner si quelque chose change.

Ceci est une classe principale complète, compilée et exécutée sur la ligne de commande avec l'argument suivant:

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

Version "lisible":

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
la source
Une telle java beaucoup verbeuse. +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))

Testez ici

Juan Cortés
la source
0

PHP, 228 204 197 194 octets

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;

donne des avertissements en PHP 7.1. Insérer (int)avant $a[$t]+$cde réparer.

Courez avec php -nr '$a="<string>";<code>'ou essayez-le en ligne .

panne

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