เครื่องจำลองแรงโน้มถ่วง


33

คำแถลง

คุณจะได้รับชุดของลูกตกอยู่ในตาราง 2D ตารางนี้ล้อมรอบด้วยกำแพงที่ไม่เปลี่ยนรูปและไม่สามารถแตกได้ดังนั้นการกระทำทั้งหมดที่อยู่ในนั้น งานของคุณคือการกำหนดสถานการณ์ของสถานการณ์ที่จะเกิดขึ้นหลังจากแรงโน้มถ่วงทำงานทั้งหมด

องค์ประกอบภายในกริด

  • - พื้นไม่เปลี่ยนทิศทางของลูกบอลตก
  • \ เลื่อนไปทางขวาเปลี่ยนเส้นทางของลูกบอลหนึ่งตำแหน่ง (1) ทางขวา
  • / สไลด์ซ้ายเปลี่ยนเส้นทางของลูกบอลหนึ่งตำแหน่งที่เหลือ (1)
  • o ลูกบอล.

กฎระเบียบ

  • ลูกตก
  • ชั้นและภาพนิ่งไม่ตก
  • หากลูกบอลกระทบกับสไลเดอร์ที่จะผ่านกำแพง ( \#หรือ#/) หรือข้ามผ่านพื้นสไลด์จะทำหน้าที่เป็นพื้น
  • เมื่อลูกบอลกระทบกับลูกบอลอีกลูกหนึ่งจะกลายเป็นลูกบอลหนึ่งลูก แต่เพิ่มพลังของพวกเขาให้เท่ากับจำนวนลูกทั้ง
  • ลูกใหม่ (เข้าร่วม) จะยังคงทำงานตามปกติ
  • เมื่อลูกบอลไม่สามารถเคลื่อนที่ได้อีกต่อไปมันจะถูกแทนที่ด้วยพลังของมัน
  • พลังของลูกบอลจะต้องไม่เกิน 9

อินพุต

กริดจะได้รับในตัวแปรสตริงที่มีชื่อสั้นที่สุดในภาษาที่คุณเลือก โดยค่าเริ่มต้นเราจะใช้aเป็นอินพุต ตัวอย่างของอินพุตตรงตามที่ได้รับ:

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

สำหรับกริดสุ่มที่สร้างขึ้นใช้ https://repl.it/B1j3/2 ใช้หน้าสร้างของฉันแทน (ไม่มีโฆษณาไม่มีอึเพียงแค่อินพุตและเอาต์พุต)

หมายเหตุ\nแบ่งสาย การพิมพ์อินพุตไปยังหน้าจอ (ไม่จำเป็นสำหรับความท้าทาย) จะแสดงสิ่งต่าง ๆ เช่นนี้ แม้ว่าฉันจะวางสี่จิ๊กซอร์ไว้ในที่ปลอดภัย

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

เอาท์พุต

กริดเดียวกันพิมพ์ไปที่หน้าจอพร้อมผลสุดท้ายของกำลังบอล คำตอบที่ถูกต้องจะเป็นหนึ่งใน (1) ปริศนาต่อไปนี้ซึ่งแต่ละตัวสอดคล้องกับอินพุตที่ตำแหน่งเดียวกันแน่นอนถ้าอินพุตแตกต่างกันคุณควรปรับเอาต์พุต ไม่ จำกัด เฉพาะสี่ตัวนั้น!

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

คะแนน

ภาษาจะแข่งขันกับตนเองดังนั้นอย่าลังเลที่จะใช้ภาษา nongolf ในการตรวจสอบโซลูชันฉันจะต้องสามารถทดสอบได้ที่ใดที่หนึ่งเพื่อดูว่าใช้งานได้!

คะแนนคือจำนวนไบต์ ในกรณีที่เสมอกันคำตอบแรกที่ชนะคะแนนเสมอจะชนะ

คำเตือน

  • หากไม่แน่ใจว่าลูกบอลควรตอบสนองอย่างไรให้ถามฉันและฉันจะชี้แจงว่าฉันชัดเจนที่สุดเท่าที่จะทำได้ แต่ฉันแน่ใจว่ามีบางกรณีที่ทำให้เกิดความสับสน
  • สไลด์จะถูกขี่หากคุณสามารถออกจากพวกเขาคิดว่ามันเหมือนสไลด์จริง มีผู้ชายคนหนึ่งที่อยู่ด้านบนที่ไม่ยอมให้คุณทะลุผ่านลูกเว้นแต่ว่ามันจะวิ่งออกจากอีกด้านหนึ่ง

ชี้แจงตัวอย่างการเคลื่อนที่ของลูกบอล

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

การปรับปรุง

ฉันจะทดสอบได้อย่างไรว่าคำตอบของฉันถูกต้อง?

ฉันได้ตั้งหน้าง่ายในหนึ่งในเว็บไซต์ของฉันที่จะให้ปริศนาแบบสุ่มและคำตอบให้กับคุณ ใช้อินพุตและตรวจสอบกับเอาต์พุต ทางออกของฉันโดยไม่ต้องกังวลเกี่ยวกับการเล่นกอล์ฟมากเกินไปคือในไพ ธ อน (ตัวสร้างและหน้ายังไพ ธ อน)389b 355b

ลีดเดอร์บอร์ด


1
ฉันนึกถึงMarbelous
Arcturus

10
คะแนนโบนัสถ้าใครตอบใน Marbelous
Mego


เสียงเหมือนอาจเป็นเกมพินบอล
พิสดาร

@ JuanCortésทำไมคุณไม่ใช้รหัสผู้นำของกลุ่มแฟนซีเพื่อที่คุณจะได้ไม่ต้องอัพเดทการจัดอันดับด้วยตัวคุณเอง?
usandfriends

คำตอบ:


6

JavaScript (ES6), 157 196

แก้ไขถ่านด้วยถ่านแทนที่จะทำทีละแถวผลลัพธ์ที่ดีกว่ามาก

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

หมายเหตุ: ไม่จัดการกับค่าบอล> 9. แต่ทำได้โดยมีค่าใช้จ่าย 18 ไบต์ ดูรหัสพื้นฐานด้านล่าง

ตัวอย่างการทดสอบ (เต็มหน้าดีกว่า)

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>


ดี! ฉันมีจำนวนมากที่จะเรียนรู้ในวิธีการเล่นกอล์ฟ
usandfriends

คุณไม่ควรจับคู่ค่า> 9 ด้วยv>9?9:v?
ติตัส

@Titus ฉันทำได้ แต่อันที่จริงฉันสามารถทำอะไรก็ได้ที่ฉันต้องการเพราะไม่คาดหวังค่า> 9 เห็นความคิดเห็นโดย OP ตอบคำถามของฉัน
edc65

5

Javascript (ES6), 453 426 409 306 290 286 ไบต์

ทางออกแรกและชัดเจนที่สุดที่อยู่ในใจของฉันคือโซลูชันที่มองไปรอบ ๆ สไลด์แล้วผสานหรือแทนที่

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

ทดสอบเช่น:

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

ขอบคุณที่: @ edc65


ฉันจะโพสต์หลามของฉันเมื่อฉันแน่ใจว่าฉันไม่สามารถตีกอล์ฟได้อีกต่อไป แต่จนถึงตอนนี้มันเป็นรหัสไพ ธ อนที่สร้างคำตอบ มีวิธีใดที่ฉันสามารถทดสอบโค้ดกอล์ฟของคุณที่ไหนสักแห่งเพื่อที่ฉันจะได้ปรากฏบนกระดานผู้นำ? (jsfiddle, jsbin, ideone, อะไรก็ตาม)
Juan Cortés

รับได้ที่ 355 คุณย้าย!
Juan Cortés

@ JuanCortésเรียบร้อยแล้ว!
usandfriends

b.replace(/o/g,'1').split`` สามารถย่อให้เหลือ[...b.replace(/o/g,1)]
edc65

@ edc65 ฉันคิดว่าฉันแก้ไข โดยพื้นฐานแล้วมันจะรักษาพลังที่ต่ำกว่า 10 ไว้โดยการปรับเปลี่ยน 10.
usandfriends

4

Java, มากเกินไป 1102 987 ไบต์

เพราะจาวา

\ o / ต่ำกว่า 1,000!

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

เป้าหมายด้านได้รับความสามารถในการพิมพ์ซ้ำของคณะกรรมการทุกคน: เพียงแค่เอากลาง;ในwhile(g.i()) ; System.out.print(g.s());(แม้ว่านี้จะปิดการใช้งานการพิมพ์ที่ผ่านมาซึ่งมี 0-> การแปลงพลังงาน) น่าเสียดายที่ในรุ่นนี้แรงโน้มถ่วงทำงานได้แปลก ฉันจะผ่านบอลที่ไม่ติดอยู่ในแต่ละครั้งและย้ายมัน การลัดวงจรiterate()มีจำนวนไบต์น้อยกว่าการไปกระดานทั้งหมดแล้วกลับมาใหม่หากมีสิ่งใดเปลี่ยนแปลง

นี่เป็นคลาสหลักที่สมบูรณ์รวบรวมและรันบนบรรทัดคำสั่งพร้อมด้วยอาร์กิวเมนต์:

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

รุ่น "สามารถอ่านได้":

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

เช่น verbose java มาก +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))

ทดสอบที่นี่


0

PHP, 228 204 197 194 ไบต์

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 ใส่(int)ก่อนที่$a[$t]+$cจะแก้ไข

ทำงานด้วยphp -nr '$a="<string>";<code>'หรือลองออนไลน์

ทำให้พังถล่ม

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.