Yerçekimi simülatörü


33

Beyan

2D ızgaraya düşen bir dizi top verilir. Bu ızgara, değişmez ve kırılmaz duvarlarla çevrilidir, bu yüzden içindeki tüm hareketler içinde bulunur. Senin görevin yerçekimi tüm işleri yaptıktan sonra senaryonun durumunun ne olacağını belirlemek.

Izgara içindeki öğeler

  • - Döşeme, düşen topların yönünü değiştirmez.
  • \ Sağ slayt, topun yolunu bir (1) sağa doğru değiştirir.
  • / Sol kaydırma, topun yolunu bir (1) sola doğru değiştirir.
  • o Bir top.

kurallar

  • Toplar düşer.
  • Zeminler ve slaytlar düşmez .
  • Top bir duvardan ( \#veya #/) geçmesine ya da bir zeminden geçmesine neden olacak bir slayta çarparsa, slayt bir taban görevi görür.
  • Bir top başka bir topa çarptığında, bir top haline gelir, ancak güçlerini her iki topun toplamına yükseltir.
  • Yeni toplar (katıldı) her zamanki gibi davranmaya devam edecek.
  • Bir top artık hareket edemediğinde, gücü onun yerine geçer.
  • Bir topun gücü her zaman en fazla 9 olacaktır.

Giriş

Izgara, seçtiğiniz dilde adı en kısa olan dize değişkeninde verilecektir. Varsayılan aolarak giriş olarak kullanacağız . Tam olarak alındığı gibi bir girdi örneği:

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

Üretilen rastgele ızgaralar için, https://repl.it/B1j3/2 kullanın . Bunun yerine oluşturulan sayfamı kullan (reklam yok, saçma yok, yalnızca giriş ve çıkış)

Not satır sonları \n. Girdiyi ekrana yazdırmak (zorluk için gerekli değildir) böyle şeyleri gösterir. Yine de güvenli bir alana dört tane bulmaca koydum.

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

Çıktı

Aynı ızgara, top gücünün nihai sonucu ile ekrana basılmıştır. Geçerli bir cevap, aşağıdaki bulmacalardan biri (1) olacaktır, her biri aynı pozisyondaki girişe karşılık gelir, elbette eğer giriş farklıysa, çıkışı ayarlamanız gerekir. Bu dördü sınırlama!

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

Gol

Diller kendilerine karşı rekabet edecek, böylece nongolf dillerini kullanmaktan çekinmeyiniz. Bir çözümü doğrulamak için çalıştığını görmek için bir yerde test edebilmeliyim!

Puan bayt sayısıdır. Beraberlik durumunda, bağlı puana ulaşmak için ilk cevap kazanır.

Uyarılar

  • Bir topun nasıl tepki vermesi gerektiğinden emin değilseniz, bana sorun ve açıklığa kavuşturacağım, elimden geldiğince açık oldum ama eminim kafa karıştırıcı vakalar var.
  • Slaytlar yalnızca onlardan çıkabilirsiniz , gerçek bir slayt gibi düşünün. Tepede, diğer taraftan çıkmadığı sürece topu geçmene izin vermeyen bir adam var.

Top hareketi örnekleri açıklama

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

GÜNCEL

Cevabımın geçerli olup olmadığını nasıl test edebilirim?

Sitelerimden birinde size rastgele bir bulmaca ve cevabı verecek basit bir sayfa hazırladım . Girişi alın ve çıktıya karşı kontrol edin. Benim çözümüm, golf oynamaktan çok fazla endişe duymadan python'da (jeneratör ve sayfa da python).389b 355b

Liderler Sıralaması


1
Marbelous'u hatırlatıyorum .
Arcturus

10
Herhangi biri Marbelous dilinde cevap verirse bonus puan.
Mego


potansiyel olarak bir ascii-sanat langırt oyunu gibi geliyor
Khaled.K

@ JuanCortés neden fantezi lider pano kodunu kullanmıyorsunuz, bu yüzden sıralamaları kendiniz güncellemeniz gerekmiyor mu?
usandfriends

Yanıtlar:


6

JavaScript (ES6), 157 196

Tek tek satır yerine tek tek karakterleri düzenleyin, çok daha iyi sonuç alın

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

Not:> 9. top değerlerini işlemez. Ancak, 18 baytlık bir maliyetle olabilir. Aşağıdaki temel koda bakın.

TEST pasajı (daha iyi tam sayfa)

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>


Güzel! Golf yöntemleriyle öğrenecek çok şeyim var
usandfriends

değerleri> 9 ile eşlememelisiniz v>9?9:v?
Titus

@Titus yapabilirdim, ama aslında ne istersem yapabilirim,> 9 olması beklenmeyen bir şey olarak, OP sorumu yanıtlayan yorumuna bakın.
edc65

5

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

Aklıma gelen ilk ve en belirgin çözüm, slaytların etrafına bakan ve sonra birleşen veya değiştirilen çözümdür.

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

Gibi test edin:

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

Teşekkürler: @ edc65


Artık golf oynayamadığımdan emin olduğumda python'umu göndereceğim, ancak şu ana kadar cevabı oluşturan python kodu. Golf kodunu herhangi bir yerde test edebilmemin bir yolu seni lider panosuna sokabilir miyim? (jsfiddle, jsbin, ideone, her neyse)
Juan Cortés

355'e indirdim, hareketin!
Juan Cortés

@ JuanCortés Yapıldı!
usandfriends

b.replace(/o/g,'1').split`` kısaltılabilir[...b.replace(/o/g,1)]
edc65

@ edc65 Sanırım çözdüm. Temelde her zaman gücü 10'a göre 10'un altında tutar.
usandfriends

4

Java, Çok Fazla 1102 987 bayt

Çünkü, Java.

1000'in altında!

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

Bir yan Amaç kurulu her yinelemesini yazdırmak mümkün ediliyordu: Sadece orta kaldırmak ;inwhile(g.i()) ; System.out.print(g.s()); (bu 0-> güç dönüşüm vardır son baskı devre dışı yapar rağmen). Ne yazık ki, bu versiyonda, yerçekimi garip bir şekilde çalışıyor. Her geçişte ilk sıkışmış topu alıyorum ve hareket ettiriyorum. Kısa devre iterate(), tüm kartın üzerinden geçip daha sonra bir şey değiştiğinde geri dönen daha az bayt vardır.

Bu tam bir ana sınıftır, komut satırında argümanla derleyin ve çalıştırın:

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

"Okunabilir" versiyonu:

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

Böyle java çok ayrıntılı. +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))

Burada test et


0

PHP, 228 204 197 194 bayt

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;

PHP 7.1’de uyarı verir. Düzeltmek için (int)önce ekleyin $a[$t]+$c.

Çevrimiçi olarak çalıştırın php -nr '$a="<string>";<code>'veya deneyin .

Yıkmak

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.