爆発する数字


25

サンドボックス(削除済み)

9の行列を次のように定義してみましょう:

N=[999999999]

爆発する数を位置バツy数として定義します。これは、すべての隣接する隣人(それ自体を含む)の間で等しい整数に分解でき、各部分の絶対値は0より大きいです。

前マトリックスから、位置番号を爆発することができます11(0インデックス付き)

N=[999999999]
N=[9+19+19+19+10+19+19+19+19+1]

N=[10101010110101010]

場合によっては、結果を1より大きい有理数に分解します。これは、数値を爆発させるときに避ける必要があるものです。この場合、残りは展開された番号に割り当てられます。

それを実証するために、以前のマトリックスで作業を続けましょう。我々は位置の数を爆発する。この時間(0,0)

N=[10101010110101010]

ここには、3つのネイバーと番号自体があります。ここで式のようなものである10/4私たちに与える2をそれぞれのための2余りなど。

N=[2+210+21010+21+210101010]

N=[4121012310101010]

同様に、隣人の間で等しい部分(absが0より大きい場合)に分解されるほど大きくない場合もあります(|有理数| <1)。この場合、「0より大きい」状態を維持するために、展開された数値から「借用」する必要があります。前の例を続けると位置番号を爆発することができます1 1 11

N=[4121012310101010]

N=[4+112+110+112+10+1610+110+110+110+1]
N=[5131113511111111]


課題は、バツy位置のリストと自然数の有限の空でない配列が与えられ、位置リストの各数値が展開された後に展開された形式を返すことです。


テストケース

入力: initial matrix: [[3, 3, 3], [3, 3, 3], [3, 3, 3]], numbers: [[0,0],[0,1],[0,2]]

出力: [[1, 0, 1], [5, 6, 5], [3, 3, 3]]


入力: Initial matrix: [[9, 8, 7], [8, 9, 7], [8, 7, 9]], numbers: [[0,0],[1,1],[2,2]]

出力: [[4, 11, 8],[11, 5, 10],[9, 10, 4]]


入力: Initial matrix: [[0, 0], [0, 0]], numbers: [[0,0],[0,0],[0,0]]

出力: [[-9, 3],[3, 3]]


入力: Initial Matrix: [[10, 20, 30],[30, 20, 10],[40, 50, 60]], numbers: [[0,2],[2,0],[1,1],[1,0]]

出力: [[21, 38, 13], [9, 12, 21], [21, 71, 64]]


入力: Initial Matrix: [[1]], numbers: [[0,0]]

出力: [[1]]


入力: Initial Matrix: [[1, 2, 3]], numbers: [[0,0], [0, 1]]

出力: [[1, 1, 4]]


ノート

  • 入出力ルールが適用されます

  • 入力行列が空になることはないと想定できます

  • 座標は常に有効であると想定できます

  • テストケースの入力座標は(行、列)として与えられます。(x、y)にする必要がある場合は、値を交換できます。もしそうなら、あなたの答えにそれを述べてください


ゴルフをコーディングするのは初めてです。サンプルはこれらの行列を取り込むことができますか?言語に存在する形式はありますか?書かれているとおりの文字列形式?
rtpax

1
非正方形行列のテストケースを追加することをお勧めします。
Οurous

ええと@Ourousああ、私は戻って私が推測製図板に、それらは、正方形であることが保証されたと仮定すると、私のプログラムを書いていた
rtpax

matrix-sizeが少なくとも2 x 2であると仮定できますか?または、1行1列の行列も入力できますか?
ケビンクルーッセン

@rtpax任意のフォーマットを質問がはい、そう述べていない限り
ASCIIのみ

回答:


9

C(GCC)220 216 214 212バイト

@ceilingcatへの2バイトのクレジット

#define L(v)for(int v=2;~v--;)
#define P l/C+r<0|l/C+r>=R|l%C+c<0|l%C+c>=C
f(int R,int C,int*m){for(int*i=m+R*C;~*i;) {int*M,l=*i+++C**i++,a=0,b;L(r)L(c)P?:++a;M=m+l;b=*M/a;b+=!b;*M- =b*a;L(r)L(c)M[r*C+c]+=P?0:b;}}

ここで実行

やや少ないゴルフバージョン

#define L(v)for(int v=2;~v--;)
#define P l/C+r<0|l/C+r>=R|l%C+c<0|l%C+c>=C
f(int R, int C, int*m) {
    for(int*i=m+R*C;~*i;) {
        int*M,l=*i+++C**i++,a=0,b;
        L(r)
            L(c)
                P?:++a;
        M=m+l;
        b=*M/a;
        b+=!b;
        *M-=b*a;
        L(r)
            L(c)
                M[r*C+c]+=P?0:b;
    }
}

例付きの呼び出しコード

int main()
{
  int matrix[] = {3,3,3,3,3,3,3,3,3,0,0,0,1,0,2,-1};
  int rows = 3;
  int columns = 3;
  f(rows,columns,matrix);
  for(int r = 0; r < rows; ++r) {
    for(int c = 0; c < columns; ++c) {
      printf("%03d,",matrix[r*columns + c]);
    }
    printf("\n");
  }
}

そして出力

001,005,003,
000,006,003,
001,005,003,

11
PPCGへようこそ:)
シャギー


7

JavaScriptの(ES7)、 126の125 123  121バイト

@Shaggyのおかげで2バイト節約

入力をとして受け取ります(matrix)(list)。マトリックスを変更して出力します。

m=>a=>a.map(([Y,X])=>(g=n=>m[m.map((r,y)=>r.map((_,x)=>(x-X)**2+(y-Y)**2<3&&r[n++,x]++)),(m[Y][X]+=~n)<n||g``,Y][X]++)``)

オンラインでお試しください!

どうやって?

チャレンジで説明されているアルゴリズムに厳密に従う場合、各位置ペアに対して次の操作を実行する必要があります。 バツy

  1. 行列を調べて、近傍の数を計算します n
  2. 計算する mバツy/n 量を推測する q 各近隣に追加する必要があります
  3. マトリックスをもう一度調べて、各ネイバーを更新します
  4. 更新 mバツy

その代わりに、必要な回数だけ繰り返される単純な操作のフローを実行する再帰関数を使用します。

  1. 各隣接セルと参照セル自体に対して:セルを増やし、カウンターを増やします n (初期化済み 0
  2. 引く n+1 参照セルから
  3. 上記の結果が以上の場合 n、再帰呼び出しを行う
  4. 参照セルをインクリメントします(最後の再帰呼び出しが完了すると、この種のすべてのステップが連続して実行さます)

主な利点は、マトリックスのループが1つだけ必要なことです。2番目の利点は、商をまったく計算する必要がないことです。

M=0000260000 そして バツy=11

最初の反復のステップ1の後、次のようになります

M=1111271111 そして n=9

そして、最初の反復のステップ2の後:

M=1111171111

ここで重要な点は、参照セルはコスト(9)ゲインなしのアカウント(+1)、それからどれだけ引き出せるかを知ることができます。

その結果、セルの合計はもはや等しくなりません 26この時点で。ただし、これはプロセスの最後に修正され、参照セルでのすべてのゲインが一度に考慮されます。

ステップ3最初の反復:理由17 より大きい 9、再帰呼び出しを行います。

2回目の反復のステップ1の後、次のようになります

M=2222182222 そして n=9

そして、2回目の反復のステップ2の後:

M=222282222

ステップ32回目:この時、私たちは持っています8<9、そこで停止します。

現在、二回(基準セルをインクリメントし、ステップ4両方の反復を最終結果につながります)。

M=2222102222

コメント済み

m => a =>                     // m[] = input matrix, a[] = list of positions
  a.map(([Y, X]) => (         // for each pair (X, Y) in a[]:
    g = n =>                  //   g = recursive function expecting n = 0
      m[                      //
        m.map((r, y) =>       //     for each row r[] at position y in m[]:
          r.map((_, x) =>     //       for each value at position x in r[]:
            (x - X) ** 2 +    //         if the quadrance between (x, y)
            (y - Y) ** 2 < 3  //         and (X, Y) is less than 3:
            && r[n++, x]++    //           increment n and increment r[x]
          )                   //       end
        ),                    //     end
        (m[Y][X] += ~n)       //     subtract n + 1 from m[Y][X]
        < n                   //     if the result is greater than or equal to n:
        || g``,               //       do a recursive call
        Y                     //     
      ][X]++                  //     increment m[Y][X]
    )``                       //   initial call to g
  )                           // end

1
の両方の出現(0)箇所を2つのバックティックに置き換えることにより、数バイトを節約できます。
シャギー

6

R163の 162 161 159 155 146バイト

function(m,l){for(e in l){v=m[i<-e[1],j<-e[2]];s=m[x<--1:(i<dim(m))+i,y<--1:(j<ncol(m))+j];z=sum(1|s);d=max(1,v%/%z);m[x,y]=s+d;m[i,j]=v+d-d*z};m}

オンラインでお試しください!

説明

(以前のバージョンのコードに対応)

function(m,l) {          # Take input as matrix m and 1-indexed list of explosion points l
  for(e in l) {          # Loop over the list of explosion points
    i=e[1]; j=e[2]       # Assign current coordinates to (i,j) for brevity
    x=-1:1+i             # Assign the ranges of neighboring cells: (i-1) to (i+1),
    y=-1:1+j             # and (j-1) to (j+1)
    s=                   # Take the submatrix s=m[x,y]
      m[x<-x[x<=dim(m)]  # But first trim x and y from above to prevent out of bounds errors,
     ,y<-y[y<=ncol(m)]]  # trimming from below isn't necessary, as R tolerates index 0
    z=sum(1|s)           # Count the neighbors
    d=max(1,m[i,j]%/%z)  # Estimate, how much we'll distribute to each neighbor
    m[x,y]=s+d           # Add the distributed amount to each cell of the submatrix
    m[i,j]=m[i,j]-d*z    # Subtract the total amount from the exploded cell
  }
  m                      # Return the modified matrix
}

4

クリーン181の 167バイト

import StdEnv;

foldl\m(x,y)={{if(d>2)0b+e-if(d>0)0b*n\\e<-:l&v<-[0..],let{b=max m.[y,x]n/n;$a b=2+sign a-(a+1)/size b;n= $x l* $y m;d=(v-x)^2+(u-y)^2}}\\l<-:m&u<-[0..]}

オンラインでお試しください!

部分的に適用された関数リテラルの形式。

拡張(最初のバージョン):

f // functinon f on {{Int}} and [(Int,Int)]
    = foldl \m (x, y) // fold :: (a -> b -> a) a [b] -> a with first argument \ {{Int}} (Int,Int) -> {{Int}} giving \ {{Int}} [(Int,Int)] -> {{Int}}
        = {                     // an array of
            {                   // arrays of
                if(d > 2) 0 b   // the amount we give to the neighbors
                + e             // plus the current entry
                - if(d > 0) 0 b // minus the amount taken from the target entry
                * n             // times the number of neighbors, if we're on the target
            \\                  // for each
                e <-: l         // element of row l
                & v <- [0..]    // and x-index v
                , let           // local definitions:
                    b           // the amount given to the neighbors
                        = max   // we need at least 1 each, so take the largest of
                            m.[y, x] // the target entry
                            n   // or the number of neighbors
                        / n     // divide it by the number of neighbors
                    n           // the number of neighbors
                        = (     // sum of
                            1   // one
                            + s x // if x is at the left edge = 0 else 1
                            + s ( // if x is at the right edge = 0 else 1
                                size l
                                - x 
                                - 1
                            )
                        ) * (   // times the sum of
                            1   // one
                            + s y // if y is at the top edge = 0 else 1
                            + s ( // if y is at the bottom edge = 0 else 1
                                size m
                                - y
                                - 1
                            )
                        )
                    d           // distance from the target point
                        = (v - x)^2
                        + (u - y)^2
            }
        \\                      // for each
            l <-: m             // row l in matrix m
            & u <- [0..]        // and y-index u
        }

4

錆-295バイト

fn explode(p:(i8,i8),v:&mut Vec<Vec<i8>>){let x=v[p.0 as usize][p.1 as usize];let q=|x,y|x*x+y*y;loop{let mut t=0;for i in 0..v.len(){for j in 0..v[i].len(){if q(i as i8-p.0,j as i8-p.1)<3{v[i][j]+=1;v[p.0 as usize][p.1 as usize]-=1;t+=1;}}}if v[p.0 as usize][p.1 as usize]<=(x/t+x%t){break;}}}

Rustはベクトルの符号なし整数のインデックス付けを必要としますが、減算を行うには符号付き整数を必要とするため、これはかなり長くなります。ただし、これまでのアルゴリズムは「最短のアルゴリズム」だと思います。実際には、エッジ、ボトムなどの検出に対処する必要はありません。

3つのことに注意してください。1つは、すべてのセルの合計が常に一定であることです。2つ目は、これが除算/残りの状況であるため、ブレゼンハムアルゴリズムスタイルの考え方を適用できることです。3つ目は、特別な位置にある「余分な」ものを処理する前に、特別な位置のセルから一定の距離内にあるすべてのセルに常に同じ番号を追加するという質問です。

アルゴリズム:

位置Pのセルの元の値をMに保存します。

開始ループ:

マトリックス内の各セルIを反復処理します。セルIの位置が位置Pの3象限(距離の2乗)内にある場合、セルPから1を減算し、セルIに1を加算します。これは、マトリックスの1回の反復で行われる回数をカウントします。

位置Pのセルに残っている値がM /カウント+ Mモジュロカウント以下の場合、ループを中断します。それ以外の場合は、ループを再度実行してください。

結果のマトリックスは、展開バージョンになります。カウントは基本的に、エッジを処理せずに隣人をカウントする方法です。ループとは、除算/加算を1つの繰り返しの加算/減算に分割する方法です。モジュロチェックにより、位置Pに適切な剰余が残り、隣同士で均等に分割できない「爆発」に対処することが保証されます。do / whileループ構造により、P <0が適切に機能します。

Rust Playgroundの未ゴルフバージョン


1
このような長い関数名は必要ありません。必要な1バイトfです。:しかし、あなたはおそらく、匿名関数使用することにより、さらに多くのバイトを救うことができる|p:(i8,i8),v:&mut Vec<Vec<i8>>|{...}
キリルL.

3

ジャワ10、194の 193 191 190 184 182 171バイト

M->C->{for(var q:C){int n,X=q[0],Y=q[1],x,y,c=0;do{c++;x=n=0;for(var r:M){y=0;for(int $:r)r[y]+=Math.hypot(x-X,y++-Y)<2?++n/n:0;x++;}}while((M[X][Y]+=~n)>=n);M[X][Y]+=c;}}

@ArnauldのJavaScript回答の反復ポート。@Arnauldの
おかげで-17バイト。

新しい行列を返してバイトを節約する代わりに、入力行列を変更します。

オンラインでお試しください。

説明:

M->C->{                      // Method with two integer-matrix parameters and no return-type
  for(var q:C){              //  Loop over the coordinates:
    int n,                   //   Count integer
        X=q[0],Y=q[1],       //   The current X,Y coordinate
        x,y,                 //   Temp x,y coordinates
        c=0;                 //   Counter, starting at 0
    do{                      //   Do-while:
      c++;                   //    Increase the counter `c` by 1
      x=n=0;                 //    (Re)set both `x` and the count `n` to 0
      for(var r:M)           //    Loop over the rows `r`:
        y=0;                 //     (Re)set `y` to 0
        for(int $:r)         //     Loop over the cells of the current row:
          r[y]+=             //      Increase the value at x,y by:
            Math.hypot(      //       If the hypot (builtin for `sqrt(a*a, b*b)`) of:
              x-X,           //        the difference between `x` and `X`,
                  y++-Y)     //        and difference between `y` and `Y`
                             //        (and increase `y` by 1 afterwards with `y++`)
              <2?            //       Is smaller than 2:
                 ++n/n       //        Increase count `n` and the value at x,y both by 1
                :            //       Else:
                 0;          //        Leave the value at x,y the same by increasing by 0
       x++;}}                //     Increase `x` by 1
    while((M[X][Y]+=~n)      //    Decrease the value at X,Y by n+1
          >=n);              //    Continue the do-while if this new value is still larger
                             //    than or equal to count `n`
    M[X][Y]+=c;}}            //   Increase the value at X,Y with counter `c`

1
m[y]y範囲外のJS(降伏がOKでは未定義)が、m[y][x]y範囲外もクラッシュします。
アーナルド

@アーナウルド 実際、境界外は通常JSの問題ではないことを思い出しましたが、なぜundefined[x]失敗するのか理解できます。とにかく、あなたの(x-X)**2+(y-Y)**2<3小切手はかなり賢いです。周囲の3x3ブロック(および境界内)のマトリックスの値を確認したいときは覚えておく必要があります。私は実際にそのようないくつかの答えを持っていると思う、私は今、トライキャッチを使用し、ある場合にはトライファイナルを使用します。
ケビンクルーッセン

1
拡張forループを使用した171バイト
アーナウルド

@アーナウルドいいね。今、あなたは同じことを行うので、私は...>、私はあなたの答えからポートを作成したとき、私はそれについて考えていなかったと信じてすることはできませんそれを見ること>;。)
ケビンCruijssen

2

Common Lisp、498バイト

(defmacro s(l c x)`(incf(aref m,l,c),x))
(defmacro w(a &rest f)`(if(,a(or(= l 0)(= l(d 0)))(or(= c 0)(= c(d 1)))),@f))
(defmacro d(n)`(1-(array-dimension m,n)))
(defmacro p(i l m &rest f)`(loop for,i from(1-,l)to(1+,l)when(and(>=,i 0)(<=,i,m))do,@f))
(defmacro g()`(or(p i l(d 0)(p j c(d 1)(s i j 1)))(s l c(- v))))
(defun f(m l c)(let((v(w and 4(w or 6 9))))(if (<(/(s l c 0)v)1)(g)(loop for i to(1-(/(s l c 0)v))do(g)))))
(defun c(m n)(dotimes(i(length n))(f m(nth 0(nth i n))(nth 1(nth i n))))m)

オンラインでお試しください!

この関数を次のように使用します (print (c #2A((3 3 3) (3 3 3) (3 3 3)) '((0 0)(0 1)(0 2))))

より読みやすいバージョン:

(defmacro s (l c x)
  `(incf (aref m ,l ,c) ,x))

(defmacro w (a &rest f)
  `(if (,a (or (= l 0)
           (= l (d 0)))
       (or (= c 0)
           (= c (d 1))))
       ,@f))

(defmacro d (n)
  `(1- (array-dimension m ,n)))

(defmacro p (i l m &rest f)
  `(loop for ,i from (1- ,l) to (1+ ,l)
     when (and (>= ,i 0) (<= ,i ,m))
     do ,@f))

(defmacro g ()
  `(or(p i l (d 0)
     (p j c (d 1)
        (s i j 1)))
      (s l c (- v))))

(defun f (m l c)
  (let ((v (w and 4 (w or 6 9))))
    (if (< (/ (s l c 0) v) 1)
    (g)
      (loop for i to (1- (/ (s l c 0) v))
        do (g)))))

(defun c (m n)
  (dotimes (i (length n))
    (f m (nth 0 (nth i n))
       (nth 1 (nth i n))))
  m)

出力例:

(print (c #2A((3 3 3) (3 3 3) (3 3 3) (3 3 3) (3 3 3) (3 3 3)) '((5 0)(4 1)(0 2))))
;; #2A((3 4 0) (3 4 4) (3 3 3) (4 4 4) (5 -4 4) (1 5 4))

(print (c #2A((3 3 3) (3 3 3) (3 3 3)) '((0 0)(0 1)(0 2))))
; #2A((1 0 1) (5 6 5) (3 3 3))  => #2A((1 0 1) (5 6 5) (3 3 3))

(print (c #2A((9 8 7) (8 9 7) (8 7 9)) '((0 0)(1 1)(2 2))))
;; #2A((4 11 8) (11 5 10) (9 10 4))  => #2A((4 11 8) (11 5 10) (9 10 4))

(print (c #2A((0 0) (0 0)) '((0 0)(0 0)(0 0))))
;; #2A((-9 3) (3 3))  => #2A((-9 3) (3 3))

(print (c #2A((10 20 30)(30 20 10)(40 50 60)) '((0 2)(2 0)(1 1)(1 0))))
;; #2A((21 38 13) (9 12 21) (21 71 64))  => #2A((21 38 13) (9 12 21) (21 71 64))

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.