Kum kütlesini tamamlayın


12

( Sonsuz kumpikleri ve kumpillerinin kimlik öğelerini bulma ile ilgili sorular vardır .)

Negatif olmayan tamsayıların bir matrisi göz önüne alındığında, aynı boyutlarda bir matris döndürün , ancak devrildi :

  1. Matris 4'ten büyük bir değer içermiyorsa, döndürün.
  2. 3'ten büyük olan her "hücre" 4 ile azalır ve varsa doğrudan komşu hücrelerin tümü (yukarıda, aşağıda, solda ve sağda) artar.
  3. GOTO 1.

Örnekler:

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

(Yalnızca nihai sonucu döndürmeniz gerekir. Oraya ulaştığınız yol, burada gösterilen yoldan farklı olabilir: Devirme işlemlerini hangi sırayla gerçekleştirdiğiniz önemli değildir, hepsi aynı sonuca götürür.)

Daha derin bir açıklama ve bazı motivasyon için bkz bu Numberphile videoyu veya Wikipedia article Abelyen sandpile modeli .

Kurallar:

  • Giriş ve çıkışları standart yollardan herhangi biriyle
  • Loopholes yasaktır
  • Giriş ve çıkış:
    • iç içe bir liste: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    • basit bir liste: [1, 2, 3, 4, 5, 6, 7, 8, 9] ve şekil
    • bir tür yerli matris türü
    • bir dize, ör. 1 2 3\n4 5 6\n7 8 9
    • veya kendi dilinizde başka ne çalışıyorsa.
  • Giriş ve çıkış aynı biçimde olmalıdır
  • Giriş, burada gösterilenlerden daha büyük sayılar içerebilir, ancak boyut dilinizin sınırlarına bağlı olabilir (varsa MAXINT eşdeğeri)
  • Matris herhangi bir şekle sahip olabilir (örneğin 1x1, 2x2, 3x3, 4x4, 2x7, 11x3, ...)
  • Şeklin 0xN veya Nx0 olduğu durumda işlem yapmanız gerekmez.

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

Bu , en kısa kod (dil başına) kazanıyor.


Tüm ara sonuçları görüntülemek uygun mudur?
feersum

@feersum Sanırım, nihai sonucun ne olduğu açık olduğu sürece.
L3viathan

Yanıtlar:


8

MATL , 17 bayt

tss:"t3>t1Y6Z+w4*-+

MATL Online'da deneyin ! Veya tüm test senaryolarını doğrulayın .

açıklama

Program, girdinin toplamı kadar tekrar eder. Bu, gerekli yineleme sayısında gevşek bir üst sınırdır.

Her bir yinelemede için aşan sandpile matrisinde girişleri 3bir matris verir tespit edilir 1ve 04-komşu bir maske konvolüsyon karakterize edilmektedir. 3Kumlu matriste aşan girdiler azaltılır 4ve kıvrım sonucu eklenir.

Kumsal matrisin aşan sayıları olmadığı son iterasyonlar için 3sıfırlar çıkarılır ve buna eklenir, bu nedenle etkilenmez.

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
Kıvrım çak bir beşlik.
Martin Ender

@MartinEnder Ah, sen de bunu kullandın :-) Bir dost kıvrım görmek güzel! Eminim kusur yakında bize katılacak
Luis Mendo

2
@LuisMendo Convolutionista
Suever

4

Mathematica, 65 bayt

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

açıklama

#//.s_:>...&

3'ten büyük tüm yığınları devirerek girdiyi tekrar tekrar dönüştürün. Bu işlem, dönüşüm matrisi değiştiremediğinde (yani artık büyük kazıklar olmadığında) otomatik olarak durur. Aşağıdaki ifadede matris çağrılır s.

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

1Geçerli matris bir 4veya daha büyük olduğunda bir ve başka türlü sıfır olan bir matris oluşturun . Bu esasen hangi kazıkların devrilmesi gerektiğini gösteren bir maskedir. Maskeyi arayın x.

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

İlk olarak devrilen komşu kazıklar nedeniyle her kazığa eklenen kum sayısını hesaplıyoruz. Bu, aşağıdaki matrisin üzerinde bir kıvrım ile yapılır x:

0 1 0
1 0 1
0 1 0

Esasen, maskedeki von-Neumann komşularının her biri için mevcut hücreye bir tane ekler.

s+...-4x

Önceki sonucu ekleriz ve daha ssonra devrilen yığınları azaltmak için maskeden dört kez çıkarırız.


3

Oktav, 65 bayt

Bu pek iyi gözükmüyor, bazı püf noktaları kaçırmalıyım ...

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

Hangi Octave sürümünü kullanıyorsunuz input(0)?
Suever

@Suever>> version ans = 4.0.1
feersum

2

JavaScript (ES6), 101 95 bayt

Curry sözdiziminde matrisin genişliğini wve bir dizi değeri alır . Bir değer dizisi döndürür.a(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)

Biçimlendirilmiş ve yorumlanmış

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

Test senaryoları


1

JavaScript (ES6), 118 114 104 bayt

@Neil sayesinde 2 bayt kaydedildi

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

Yardımcı (i-=x)|y-j?i*i+olur mu?
Neil

@Neil Gerçekten, teşekkürler!
ETHproductions 30:17

... telefondaydım ama ben de düşünüyordum a.find(...b.find(...c>3&&a.map(...)))&&f(a).
Neil

@Neil Bunun işe yaradığını düşünmüyorum, çünkü .mapmutasyona
uğramaz

Görünüşe göre haritayı mutasyona uğratmak, haritayı bulgunun içine taşımaktan biraz daha az: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 bayt

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

Girişi bir vektör vektörüne referans olarak alır ve doğrudan değiştirir.

Çevrimiçi deneyin!

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.