Simulator gravitasi

33

Pernyataan

Anda diberi serangkaian bola jatuh di kotak 2D. Grid ini dikelilingi oleh dinding yang tidak bisa diubah dan tidak bisa dipecahkan sehingga semua aksi terkandung di dalamnya. Tugas Anda adalah menentukan bagaimana keadaan skenario setelah gravitasi melakukan semua itu berhasil.

Elemen di dalam kotak

  • - Lantai, tidak mengubah arah bola jatuh.
  • \ Geser ke kanan, mengubah jalur bola satu (1) posisi ke kanan.
  • / Geser kiri, mengubah jalur bola satu (1) posisi ke kiri.
  • o Bola.

Aturan

  • Bola jatuh.
  • Lantai, dan slide tidak jatuh .
  • Jika bola menyentuh slide yang akan membuatnya menembus dinding ( \#atau #/), atau melewati lantai, slide akan bertindak sebagai lantai.
  • Saat bola mengenai bola yang lain, bola itu akan menjadi satu bola, tetapi tingkatkan kekuatannya sampai jumlah kedua bola itu.
  • Bola-bola baru (bergabung) akan terus bersikap seperti biasa.
  • Ketika bola tidak bisa bergerak lagi, itu digantikan oleh kekuatannya.
  • Kekuatan bola akan selalu maksimal 9.

Memasukkan

Kotak akan diberikan dalam variabel string dengan nama apa pun yang terpendek dalam bahasa pilihan Anda. Secara default kita akan gunakan asebagai input. Contoh input, persis seperti yang diterima:

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

Untuk kisi-kisi acak yang dihasilkan, gunakan https://repl.it/B1j3/2 . Sebagai gantinya gunakan halaman saya yang dihasilkan (tidak ada iklan, tidak ada omong kosong, hanya input dan output)

Catatan jeda baris adalah \n. Mencetak input ke layar (tidak diperlukan untuk tantangan) akan menunjukkan hal-hal seperti ini. Meskipun saya telah menempatkan empat teka-teki di samping ruang yang aman.

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

Keluaran

Kisi yang sama, dicetak ke layar dengan hasil akhir dari kekuatan bola. Jawaban yang valid akan menjadi satu (1) dari teka-teki berikut, masing-masing sesuai dengan input pada posisi yang sama, tentu saja jika input berbeda Anda harus menyesuaikan output. Tidak membatasi ke empat!

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

Skor

Bahasa akan bersaing melawan diri mereka sendiri sehingga merasa bebas untuk menggunakan bahasa nongolf. Untuk memvalidasi solusi, saya harus dapat mengujinya di suatu tempat untuk melihatnya berfungsi !.

Skor adalah jumlah byte. Dalam hal seri, jawaban pertama untuk mencapai skor terikat menang.

Peringatan

  • Jika tidak yakin bagaimana seharusnya bola bereaksi, tanyakan kepada saya dan saya akan mengklarifikasi, saya sudah sejelas mungkin tapi saya yakin ada kasus yang membingungkan.
  • Slide hanya dikendarai jika Anda bisa keluar , pikirkan itu seperti slide nyata. Ada seorang pria di atas yang tidak membiarkan Anda melewati bola kecuali itu akan keluar melalui sisi lain.

Klarifikasi contoh gerakan bola

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

PEMBARUAN

Bagaimana saya bisa menguji jika jawaban saya valid?

Saya telah membuat halaman sederhana di salah satu situs saya yang akan memberi Anda teka-teki acak, dan jawabannya. Ambil input dan periksa dengan output. Solusi saya, tanpa terlalu khawatir tentang golf adalah dalam python (generator, dan halaman juga python)389b 355b

Papan peringkat

Juan Cortés
sumber
1
Saya teringat Marbelous .
Arcturus
10
Poin bonus jika ada yang menjawab di Marbelous.
Mego
Borderline dupe dari A Mere Bagatelle dan Bukan Mesin Bean Rutin Anda
Peter Taylor
sepertinya berpotensi permainan pinball ascii-art
Khaled.K
@ JuanCortés mengapa Anda tidak menggunakan kode papan pemimpin yang mewah sehingga Anda tidak perlu memperbarui peringkat sendiri?
teman

Jawaban:

6

JavaScript (ES6), 157 196

Edit char by char daripada baris demi baris, hasil yang jauh lebih baik

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

Catatan: tidak menangani nilai bola> 9. Tapi itu bisa, dengan biaya 18 byte. Lihat kode dasar di bawah ini.

Cuplikan TEST (halaman penuh lebih baik)

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
sumber
Bagus! Saya harus banyak belajar di golf
usandfriends
bukankah seharusnya Anda memetakan nilai> 9 dengan v>9?9:v?
Titus
@Titus saya bisa, tetapi sebenarnya saya bisa melakukan apa pun yang saya inginkan, karena nilai> 9 tidak diharapkan, lihat komentar oleh OP menjawab pertanyaan saya.
edc65
5

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

Solusi pertama dan paling jelas yang muncul di benak saya adalah solusi yang melihat-lihat slide dan kemudian digabung atau diganti.

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

Tidak Disatukan:

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

Tes seperti:

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

Terima kasih kepada: @ edc65

kita dan teman
sumber
Saya akan memposting python saya ketika saya yakin saya tidak bisa golf lagi, tapi sejauh ini kode python yang menghasilkan jawabannya. Bagaimana saya bisa menguji kode golf Anda di suatu tempat sehingga saya bisa mengeluarkan Anda di papan peringkat? (jsfiddle, jsbin, ideone, apa pun)
Juan Cortés
turun ke 355, kepindahanmu!
Juan Cortés
@ JuanCortés Selesai!
usandfriends
b.replace(/o/g,'1').split`` dapat disingkat menjadi[...b.replace(/o/g,1)]
edc65
@ edc65 Saya pikir saya sudah memperbaikinya. Pada dasarnya itu selalu menjaga kekuatan di bawah 10 dengan mod'ing 10.
usandfriends
4

Java, Terlalu Banyak 1102.987 byte

Karena, Jawa.

\ o / Di bawah 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());}}

Tujuan sisi adalah mampu mencetak setiap iterasi dari papan: hanya menghapus tengah ;dalam while(g.i()) ; System.out.print(g.s());(Meskipun ini tidak menonaktifkan cetak terakhir yang memiliki 0-> konversi daya). Sayangnya, dalam versi ini, gravitasi bekerja dengan aneh. Setiap operan saya mengambil bola pertama yang tidak macet dan memindahkannya. Hubungan pendek iterate()ada lebih sedikit byte daripada pergi ke seluruh papan lalu kembali jika ada yang berubah.

Ini adalah kelas utama yang lengkap, kompilasi dan jalankan di baris perintah dengan argumen:

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

Versi "Dapat dibaca":

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
sumber
Java seperti itu banyak bertele-tele. +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))

Tes di sini

Juan Cortés
sumber
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;

menghasilkan peringatan di PHP 7.1. Masukkan (int)sebelum $a[$t]+$cuntuk memperbaikinya.

Jalankan dengan php -nr '$a="<string>";<code>'atau coba online .

kerusakan

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
sumber