Số nổ


25

hộp cát (đã xóa)

Cho phép xác định ma trận 9 giây là:

N=[999999999]

Cho phép xác định một số phát nổ là một số tại vị trí (x,y) có thể được phân tách thành các số nguyên bằng nhau giữa tất cả các lân cận lân cận (bao gồm chính nó) và giá trị tuyệt đối của mỗi phần lớn hơn 0.

Từ ma trận trước, cho phép nổ số ở vị trí (1,1) (0 được lập chỉ mục)

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

N=[10101010110101010]

Đôi khi, phân tách kết quả thành một số hữu tỷ lớn hơn 1. Đây là điều chúng ta cần tránh khi phát nổ số. Trong trường hợp này, phần còn lại sẽ được gán cho số đã nổ.

Để chứng minh điều đó, hãy tiếp tục làm việc với ma trận trước của chúng tôi. Lần này chúng ta sẽ nổ số ở vị trí(0,0)

N=[10101010110101010]

Ở đây chúng tôi có 3 neight Harbor và số lượng chính nó. Ở đây phương trình giống như cung cấp cho chúng ta 2 cho mỗi và 2 là phần còn lại.10/4

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

N=[4121012310101010]

Đồng thời, đôi khi một số sẽ không đủ lớn để bị phân tách thành các phần bằng nhau (trong đó abs lớn hơn 0) giữa các hàng xóm của anh ta (| số hữu tỷ | <1). Trong trường hợp này, chúng ta cần "mượn" từ số đã nổ để duy trì điều kiện "lớn hơn 0" . Hãy tiếp tục với ví dụ trước của chúng tôi và nổ số ở vị trí .(1,1)

N=[4121012310101010]

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


Thách thức là, đưa ra một danh sách các vị trí và một dãy số tự nhiên không trống hữu hạn, trả về dạng đã nổ sau khi mỗi số từ danh sách vị trí đã được phát nổ.(x,y)


Các trường hợp thử nghiệm

Đầu vào: initial matrix: [[3, 3, 3], [3, 3, 3], [3, 3, 3]], numbers: [[0,0],[0,1],[0,2]]

Đầu ra: [[1, 0, 1], [5, 6, 5], [3, 3, 3]]


Đầu vào: Initial matrix: [[9, 8, 7], [8, 9, 7], [8, 7, 9]], numbers: [[0,0],[1,1],[2,2]]

Đầu ra: [[4, 11, 8],[11, 5, 10],[9, 10, 4]]


Đầu vào: Initial matrix: [[0, 0], [0, 0]], numbers: [[0,0],[0,0],[0,0]]

Đầu ra: [[-9, 3],[3, 3]]


Đầu vào: Initial Matrix: [[10, 20, 30],[30, 20, 10],[40, 50, 60]], numbers: [[0,2],[2,0],[1,1],[1,0]]

Đầu ra: [[21, 38, 13], [9, 12, 21], [21, 71, 64]]


Đầu vào: Initial Matrix: [[1]], numbers: [[0,0]]

Đầu ra: [[1]]


Đầu vào: Initial Matrix: [[1, 2, 3]], numbers: [[0,0], [0, 1]]

Đầu ra: [[1, 1, 4]]


Ghi chú

  • Áp dụng quy tắc đầu vào / đầu ra

  • Bạn có thể giả sử ma trận đầu vào sẽ không bao giờ trống

  • Bạn có thể giả sử tọa độ luôn luôn hợp lệ

  • Tọa độ đầu vào trong các trường hợp thử nghiệm được đưa ra là (hàng, cột). Nếu bạn cần nó là (x, y), bạn có thể trao đổi các giá trị. Nếu vậy, xin vui lòng cho biết trong câu trả lời của bạn


mới chơi mã golf; định dạng nào là mẫu được phép lấy các ma trận này? Bất kỳ định dạng tồn tại trong ngôn ngữ? Chuỗi hình thức chính xác như được viết?
rtpax

1
Tôi đề nghị thêm một trường hợp thử nghiệm cho các ma trận không vuông.
urur

@Ourous uh oh, tôi đã viết chương trình của mình với giả định rằng chúng được đảm bảo là hình vuông, trở lại bảng vẽ tôi đoán
rtpax

Chúng ta có thể giả sử kích thước ma trận ít nhất là 2 nhân 2 không? Hoặc có thể nhập một ma trận 1 trên 1 không?
Kevin Cruijssen

@rtpax Bất kỳ định dạng nào trừ khi câu hỏi có quy định khác, có
ASCII - chỉ

Câu trả lời:


9

C (GCC) 220 216 214 212 byte

ghi có vào @ceilingcat cho 2 byte

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

Chạy nó ở đây

một phiên bản ít chơi gôn hơn

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

Mã gọi với một ví dụ

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

và đầu ra

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

11
Chào mừng bạn đến với PPCG :)
Shaggy


7

JavaScript (ES7),  126 125 123  121 byte

Đã lưu 2 byte nhờ @Shaggy

Đưa đầu vào là (matrix)(list). Đầu ra bằng cách sửa đổi ma trận.

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]++)``)

Hãy thử trực tuyến!

Làm sao?

Nếu chúng tôi tuân thủ nghiêm ngặt thuật toán được mô tả trong thử thách, chúng tôi sẽ phải thực hiện các thao tác sau cho từng cặp vị trí :(x,y)

  1. đi qua ma trận để tính số hàng xómn
  2. tính toán và suy ra số lượng cần thêm vào mỗi hàng xómm(x,y)/nq
  3. đi qua ma trận một lần nữa để cập nhật từng hàng xóm
  4. cập nhậtm(x,y)

Thay vào đó, chúng tôi sử dụng một hàm đệ quy thực hiện một luồng hoạt động đơn giản hơn, lặp đi lặp lại nhiều lần nếu cần:

  1. cho mỗi hàng xóm và cho chính ô tham chiếu: tăng ô và tăng bộ đếm (khởi tạo thành )n0
  2. trừ từ ô tham chiếun+1
  3. nếu kết quả trên lớn hơn hoặc bằng , hãy thực hiện cuộc gọi đệ quyn
  4. tăng ô tham chiếu (tất cả các bước của loại này được thực hiện liên tiếp khi cuộc gọi đệ quy cuối cùng đã hoàn thành)

Lợi ích chính là chúng ta chỉ cần một vòng lặp trên ma trận. Lợi ích thứ hai là chúng ta không phải tính toán bất kỳ thương số nào cả.

Thí dụ

M=(0000260000) and (x,y)=(1,1)

Sau bước 1 của lần lặp đầu tiên , chúng ta có:

M=(1111271111) and n=9

Và sau bước 2 của lần lặp đầu tiên :

M=(1111171111)

Điểm mấu chốt ở đây là ô tham chiếu được cập nhật bằng cách chỉ tính chi phí ( ) mà không có mức tăng ( ), để chúng tôi biết chúng tôi vẫn có thể rút được bao nhiêu từ nó.9+1

Do đó, tổng của các ô không còn bằng tại thời điểm này. Nhưng điều này sẽ được sửa chữa vào cuối quá trình, trong đó tất cả lợi nhuận trên ô tham chiếu được hạch toán cùng một lúc.26

Bước 3 của lần lặp đầu tiên : vì lớn hơn , chúng tôi thực hiện một cuộc gọi đệ quy.179

Sau bước 1 của lần lặp thứ hai , chúng ta có:

M=(2222182222) and n=9

Và sau bước 2 của lần lặp thứ hai :

M=(222282222)

Bước 3 của lần lặp thứ hai : lần này, chúng ta có , vì vậy chúng ta dừng lại ở đó.8<9

Bây giờ chúng tôi tăng ô tham chiếu hai lần ( bước 4 của cả hai lần lặp ), dẫn đến kết quả cuối cùng:

M=(2222102222)

Đã bình luận

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
Bạn có thể lưu một vài byte bằng cách thay thế cả hai lần xuất hiện (0)bằng 2 backticks.
Xù xì

6

R , 163 162 161 159 155 146 byte

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}

Hãy thử trực tuyến!

Giải trình

(Tương ứng với phiên bản trước của 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

Sạch sẽ , 181 167 byte

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

Hãy thử trực tuyến!

Ở dạng hàm được áp dụng một phần theo nghĩa đen.

Mở rộng (phiên bản đầu tiên):

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

Rust - 295 byte

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

Điều này khá dài do Rust yêu cầu lập chỉ mục số nguyên không dấu của các vectơ, nhưng yêu cầu các số nguyên đã ký để thực hiện phép trừ dẫn đến phủ định. Tuy nhiên tôi tin rằng thuật toán của tôi là "thuật toán ngắn nhất" cho đến nay. Thực tế không cần phải đối phó với việc phát hiện các cạnh, đáy, v.v.

Lưu ý ba điều: Một, tổng của tất cả các ô luôn không đổi. Thứ hai, đây là một tình huống phân chia / phần còn lại, vì vậy chúng ta có thể áp dụng tư duy kiểu thuật toán Bresenham. Thứ ba, câu hỏi luôn thêm cùng một số cho tất cả các ô trong một khoảng cách nhất định của ô vị trí đặc biệt, trước khi xử lý các công cụ "phụ" ở vị trí đặc biệt.

Thuật toán:

Lưu trữ giá trị ban đầu của ô tại vị trí P vào M.

Bắt đầu vòng lặp:

Lặp lại trên mỗi ô I trong ma trận. Nếu vị trí của ô I nằm trong 3 ô vuông (khoảng cách bình phương) của vị trí P, sau đó trừ 1 từ ô P và thêm 1 vào ô I. Đếm số lần này được thực hiện trong một lần lặp qua ma trận.

Nếu giá trị còn lại trong ô tại vị trí P nhỏ hơn hoặc bằng M / Count + M modulo Count, thì phá vỡ vòng lặp. Nếu không thì thực hiện lại vòng lặp.

Ma trận kết quả sẽ là phiên bản bùng nổ. Count về cơ bản là một cách để đếm hàng xóm mà không phải đối phó với các cạnh. Vòng lặp là một cách để chia các công cụ phân chia / bổ sung thành một phép cộng / trừ lặp lại của một lần lặp. Việc kiểm tra modulo đảm bảo chúng ta sẽ có phần còn lại thích hợp ở vị trí P để đối phó với 'vụ nổ' không chia hết cho các nước láng giềng. Cấu trúc vòng lặp do / while cho phép P <0 hoạt động chính xác.

Phiên bản Ungolfed trên Sân chơi Rust


1
Tên hàm dài như vậy là không cần thiết, bất kỳ 1-byter fnào cũng được. Nhưng bạn có thể có thể tiết kiệm nhiều byte hơn bằng cách sử dụng một hàm ẩn danh:|p:(i8,i8),v:&mut Vec<Vec<i8>>|{...}
Kirill L.

3

Java 10, 194 193 191 190 184 182 171 byte

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

Cổng lặp của câu trả lời JavaScript của @Arnauld .
-17 byte nhờ @Arnauld .

Sửa đổi ma trận đầu vào thay vì trả về một ma trận mới để lưu byte.

Hãy thử trực tuyến.

Giải trình:

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]ym[y][x]y

@Arnauld À ok. Tôi thực sự đã nhớ ra ngoài giới hạn thường không phải là một vấn đề trong JS, nhưng tôi có thể hiểu tại sao undefined[x]sẽ thất bại. Dù sao, (x-X)**2+(y-Y)**2<3kiểm tra của bạn là khá thông minh. Cần nhớ rằng khi tôi muốn kiểm tra các giá trị trong ma trận trong khối 3x3 (và trong giới hạn) xung quanh nó. Tôi nghĩ rằng tôi thực sự có một vài câu trả lời như vậy, bây giờ tôi sử dụng một thử bắt, và trong một trường hợp thử cuối cùng .. Sẽ xem xét những khi tôi có thời gian.
Kevin Cruijssen

1
171 byte được tăng cường cho các vòng lặp.
Arnauld

@Arnauld Ôi đẹp quá. Bây giờ tôi thấy nó tôi không thể tin rằng tôi đã không nghĩ về điều đó khi tôi tạo một cổng từ câu trả lời của bạn, vì bạn cũng làm như vậy ..>.>;)
Kevin Cruijssen

2

Lisp thông thường , 498 byte

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

Hãy thử trực tuyến!

Sử dụng chức năng này như (print (c #2A((3 3 3) (3 3 3) (3 3 3)) '((0 0)(0 1)(0 2))))

Phiên bản dễ đọc hơn:

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

Ví dụ đầu ra:

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.