샌드 파일 토플


12

(관련에 대한 질문이 있습니다 무한 sandpilessandpiles의 발견 정체성 요소 .)

음이 아닌 정수의 행렬이 주어지면 동일한 차원이지만 행렬이 뒤집힌 행렬을 반환합니다 .

  1. 행렬에 4보다 큰 값이 포함되어 있지 않으면 반환하십시오.
  2. 3보다 큰 모든 "셀"은 4 씩 감소하며, 직접 인접한 모든 셀 (위, 아래, 왼쪽 및 오른쪽)은 존재하는 경우 증가합니다.
  3. 고토 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

(최종 결과 만 반환하면됩니다. 도달 한 경로는 여기에 표시된 경로와 다를 수 있습니다. 토핑 작업을 수행하는 순서는 중요하지 않으며 모두 동일한 결과를 가져옵니다.)

더 자세한 설명과 동기 부여 는 Abelian sandpile 모델 에 대한 Numberphile 비디오 또는 Wikipedia 기사를 참조하십시오 .

규칙 :

  • 표준 방식으로 입력 및 출력 할 수 있습니다.
  • 허점 은 금지되어 있습니다
  • 입력 및 출력은 다음과 같습니다.
    • 중첩 된 목록 : [[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 인 경우를 처리 할 필요가 없습니다.

테스트 케이스

[[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샌드 파일 매트릭스에서 초과하는 항목 은 씩 감소 4하고 컨벌루션 결과가 추가됩니다.

sandpile 행렬의 수를 초과하지 않는 마지막 반복의 경우 30을 빼고 더하기 때문에 영향을받지 않습니다.

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
컨볼 루션 하이 파이브.
Martin Ender

@MartinEnder Ah, 당신은 또한 그것을 사용했습니다 :-) 동료 convoluter를 만나서 반갑습니다! flawr이 곧 우리와 함께 할 것이라고 확신합니다
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현재 행렬이 a 4이상일 때마다 를 갖고, 그렇지 않으면 0 을 갖는 행렬을 만듭니다 . 이것은 본질적으로 어떤 더미를 토핑해야 하는지를 나타내는 마스크입니다. 마스크를 호출하십시오 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

기본적으로 마스크의 각 폰 노이만 이웃에 대한 현재 셀에 하나를 추가합니다.

s+...-4x

이전 결과를 더한 s다음 마스크에서 마스크의 4 배를 빼서 넘어진 파일을 줄입니다.


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

자바 스크립트 (ES6), 101 95 바이트

카레 구문에서 행렬의 너비 w와 값의 배열을 가져옵니다 . 값의 배열을 반환합니다.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)

형식화 및 의견

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

자바 스크립트 (ES6) 118 114 104 바이트

@Neil 덕분에 2 바이트 절약

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

@ 닐 정말 감사합니다!
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.