โค่นล้มทราย


12

(มีคำถามที่เกี่ยวข้องเกี่ยวกับทรายแบบไม่สิ้นสุดและการค้นหาองค์ประกอบตัวตนของทราย )

ให้เมทริกซ์ของจำนวนเต็มไม่เป็นลบคืนเมทริกซ์ที่มีขนาดเท่ากัน แต่ล้มลง :

  1. ถ้าเมทริกซ์ไม่มีค่าใด ๆ ที่มากกว่า 4 ให้คืนค่า
  2. "เซลล์" ทุกอันที่มีขนาดใหญ่กว่า 3 จะลดลง 4 และเซลล์ที่อยู่ใกล้เคียงโดยตรง (ด้านบนด้านล่างซ้ายและขวา) จะเพิ่มขึ้นหากมีอยู่
  3. GOTO 1

ตัวอย่าง:

0 1 0        0 2 0
2 4 0   ->   3 0 1
0 0 3        0 1 3

1 2 3    2 3 4    2 5 1    4 1 2    0 3 3    0 3 3    0 3 3
4 5 6 -> 2 4 4 -> 4 2 3 -> 0 5 4 -> 3 2 1 -> 3 3 1 -> 3 3 2
7 8 9    5 7 7    2 6 5    4 3 2    0 5 3    1 1 4    1 2 0

(คุณจะต้องส่งคืนผลลัพธ์ขั้นสุดท้ายเท่านั้นเส้นทางที่คุณไปถึงอาจแตกต่างจากที่แสดงไว้ที่นี่: ไม่สำคัญว่าคุณจะดำเนินการโค่นล้มได้อย่างไร

สำหรับคำอธิบายลึกและแรงจูงใจบางคนเห็นวิดีโอนี้ Numberphileหรือบทความวิกิพีเดียในรูปแบบ sandpile คริสต์

กฎ:

  • คุณสามารถรับอินพุตและเอาต์พุตด้วยวิธีมาตรฐาน
  • ช่องโหว่เป็นสิ่งต้องห้าม
  • อินพุตและเอาต์พุตอาจเป็น:
    • รายการซ้อน: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    • รายการง่าย: [1, 2, 3, 4, 5, 6, 7, 8, 9]และรูปร่าง
    • ชนิดเมทริกซ์ดั้งเดิมบางชนิด
    • สตริงเช่น 1 2 3\n4 5 6\n7 8 9
    • หรืออะไรก็ได้ที่ทำงานในภาษาของคุณ
  • อินพุตและเอาต์พุตต้องอยู่ในรูปแบบเดียวกัน
  • ข้อมูลที่ป้อนอาจมีจำนวนมากกว่าที่แสดงที่นี่ แต่ขนาดอาจถูก จำกัด ด้วยขีด จำกัด ของภาษาของคุณ (เทียบเท่ากับ MAXINT หากมี)
  • เมทริกซ์อาจมีรูปร่างใด ๆ (เช่น 1x1, 2x2, 3x3, 4x4, 2x7, 11x3, ... )
  • คุณไม่จำเป็นต้องจัดการเคสที่มีรูปร่างเป็น 0xN หรือ Nx0

Testcases

[[2, 5, 4], [8, 6, 4], [1, 2, 3]] -> [[3, 3, 0], [1, 2, 2], [1, 3, 2]]
[[0, 0, 2], [1, 3, 3], [0, 0, 0]] -> [[0, 0, 2], [1, 3, 3], [0, 0, 0]]
[[9, 9, 9], [9, 9, 9], [9, 9, 9]] -> [[1, 3, 1], [3, 1, 3], [1, 3, 1]]
[[4, 5], [2, 3]] -> [[2, 3], [0, 1]]
[[2, 3, 5], [2, 2, 0]] -> [[3, 0, 2], [2, 3, 1]]
[[7]] -> [[3]]

นี่คือรหัสที่สั้นที่สุด (ต่อภาษา) จะชนะ


ตกลงเพื่อแสดงผลลัพธ์ระดับกลางทั้งหมดหรือไม่
feersum

@feersum ฉันเดาว่าตราบใดที่มันชัดเจนว่าผลลัพธ์สุดท้ายคืออะไร
L3viathan

คำตอบ:


8

MATL , 17 ไบต์

tss:"t3>t1Y6Z+w4*-+

ลองที่MATL Online! หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย

โปรแกรมวนซ้ำหลาย ๆ ครั้งเท่ากับผลรวมของอินพุต นี่เป็นขอบเขตสูงสุดที่หลวมตามจำนวนการวนซ้ำที่ต้องการ

สำหรับการวนซ้ำแต่ละครั้งรายการในเมทริกซ์ sandpile ที่มากเกินไป3จะถูกตรวจจับโดยให้เมทริกซ์ของ1และ0ซึ่งถูกผูกไว้กับมาสก์แบบ 4 เพื่อนบ้าน รายการที่เกิน3ในเมทริกซ์ sandpile จะถูกลดลง4และผลลัพธ์ของการแปลงจะถูกเพิ่มเข้าไป

สำหรับการทำซ้ำครั้งล่าสุดซึ่งเมทริกซ์ของ Sandpile มีจำนวนไม่เกิน3ศูนย์จะถูกลบออกและเพิ่มเข้าไปดังนั้นจึงไม่ได้รับผลกระทบใด ๆ

t       % Implicit input (matrix). Duplicate
ss      % Sum of matrix entries
:"      % Repeat that many times
  t     %   Duplicate
  3>    %   True for matrix entries that exceed 3
  t     %   Duplicate
  1Y6   %   Push predefined literal [0, 1, 0; 1, 0, 1; 0, 1, 0]
  Z+    %   2D convolution, keeping size
  w     %   Swap
  4*    %   Multiply by 4
  -     %   Subtract
  +     %   Add
        % Implicit end. Implicit display

3
Convolution สูงห้า
Martin Ender

@MartinEnder อ่าคุณยังใช้มัน :-) ดีใจที่ได้เห็นเพื่อนร่วมทาง! ฉันแน่ใจว่าข้อบกพร่องจะเข้าร่วมกับเราเร็ว ๆ นี้
Luis Mendo

2
@LuisMendo Convolutionista
Suever

4

Mathematica, 65 ไบต์

#//.s_:>s+ListConvolve[{v={0,1,0},1-v,v},x=UnitStep[s-4],2,0]-4x&

คำอธิบาย

#//.s_:>...&

แปลงอินพุตซ้ำหลายครั้งโดยการล้มกองทั้งหมดมากกว่า 3 กระบวนการนี้จะหยุดโดยอัตโนมัติเมื่อการแปลงล้มเหลวในการเปลี่ยนเมทริกซ์ (เช่นเมื่อไม่มีกองขนาดใหญ่อีกต่อไป) sในนิพจน์ต่อไปนี้เมทริกซ์ที่เรียกว่า

...x=UnitStep[s-4]...

สร้างเมทริกซ์ที่มี1ทุกครั้งที่เมทริกซ์ปัจจุบันมี4หรือมากกว่าและเป็นศูนย์ นี่คือหน้ากากที่ระบุว่าเสาเข็มต้องถูกโค่น xโทรหน้ากาก

ListConvolve[{v={0,1,0},1-v,v},x=UnitStep[s-4],2,0]

ก่อนอื่นเราคำนวณจำนวนของทรายที่เพิ่มเข้าไปในแต่ละกองเนื่องจากกองข้างเคียงล้ม สิ่งนี้ทำโดยการโน้มน้าวเมทริกซ์ต่อไปนี้ผ่านx:

0 1 0
1 0 1
0 1 0

โดยพื้นฐานแล้วมันจะเพิ่มเซลล์หนึ่งเข้าไปในเซลล์ปัจจุบันสำหรับเพื่อนบ้านของ von-Neumann ในหน้ากาก

s+...-4x

เราเพิ่มผลลัพธ์ก่อนหน้าsแล้วและเราจะลบมาสก์ออกสี่เท่าเพื่อลดการโค่นล้มของกอง


3

อ็อกเทฟ 65 ไบต์

ดูเหมือนจะไม่ดีมากฉันต้องทำท่วงทำนอง ...

m=input(0);do;m+=conv2(m>3,[0 1 0;1 -4 1;0 1 0],"same")
until m<4

สิ่งที่รุ่นของคู่ที่คุณใช้ที่ช่วยให้input(0)?
Suever

@Suever>> version ans = 4.0.1
feersum

2

JavaScript (ES6), 101 95 ไบต์

นำความกว้างของเมทริกซ์wและอาเรย์ของค่านิยมในไวยากรณ์a currying (w)(a)ส่งคืนอาร์เรย์ของค่า

w=>g=a=>(b=a.map((n,i)=>n%4+(F=d=>~m|i%w&&a[i+d]>>2)(m=w)+F(-w)+F(m=-1)+F(!++i)))+0==a+0?a:g(b)

จัดรูปแบบและแสดงความคิดเห็น

w =>                      // main function: takes w as input, returns g
  g = a =>                // recursive function g: takes a as input
    (                     //
      b = a.map((n, i) => // for each element n at position i in a:
        n % 4 + (         //   keep only n MOD 4
          F = d =>        //   define F(): function that takes d as input
            ~m |          //     if m is not equal to -1
            i % w &&      //     or i MOD w is not null:
            a[i + d] >> 2 //       return a fourth of the value of the cell at i + d
        )(m = w) +        //   test the cell below the current cell
        F(-w) +           //   test the cell above
        F(m = -1) +       //   test the cell on the left
        F(!++i)           //   test the cell on the right
      )                   // end of map(): assign the result to b
    ) + 0 == a + 0 ?      // if b is equal to a:
      a                   //   stop recursion and return a
    :                     // else:
      g(b)                //   do a recursive call with b

กรณีทดสอบ


1

JavaScript (ES6), 118 114 104 ไบต์

บันทึก 2 ไบต์ขอบคุณ @Neil

f=a=>a.find(b=>++y&&b.find(c=>++x&&c>3,x=0),y=0)?f(a.map(b=>b.map(c=>c+=--i|y?i*i+y*y==1:-4,i=x,--y))):a

ไม่(i-=x)|y-j?i*i+ช่วยเหลือ?
Neil

@Neil มันทำจริงๆขอบคุณ!
ETHproductions

... ฉันใช้โทรศัพท์ แต่ฉันก็กำลังพิจารณาa.find(...b.find(...c>3&&a.map(...)))&&f(a)อยู่
Neil

@Neil ฉันไม่คิดว่าจะทำงานได้เนื่องจาก.mapไม่ได้กลายพันธุ์ ...
ETHproductions

ดูเหมือนว่าการทำให้กลายพันธุ์มีค่าใช้จ่ายน้อยกว่าการเคลื่อนย้ายแผนที่ในการค้นหาประหยัด:f=a=>a.find((b,x)=>b.find((c,y)=>c>3&&a.map(b=>b.map((_,j)=>b[j]+=x|(j-=y)?x*x+j*j==1:-4)&x--)))&&f(a)
Neil

1

C ++, 261 258 250 ไบต์

#import<vector>
#define S size()
void f(std::vector<std::vector<int>>&m){s:int i,j,r;for(i=r=0;i<m.S;++i)for(j=0;j<m[i].S;++j){if(m[i][j]>3){r=1;m[i][j]-=4;j>0&&m[i][j-1]++;i>0&&m[i-1][j]++;j<m[i].S-1&&m[i][j+1]++;i<m.S-1&&m[i+1][j]++;}}if(r)goto s;}

รับอินพุตเป็นการอ้างอิงถึงเวกเตอร์ของเวกเตอร์และแก้ไขโดยตรง

ลองออนไลน์!

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