Trọng lượng của con đường RoD có trọng số nhỏ nhất


16

Để cho Alà một mbằng nma trận chữ nhật của dương số nguyên, nơi mncũng là tích cực số nguyên.

Chúng tôi quan tâm đến các đường dẫn RoD ('Phải hoặc xuống') từ ô trên bên trái đến ô Adưới bên phải; trong một đường dẫn RoD, mỗi ô liên tiếp của đường dẫn là một ô ở bên phải hoặc một ô nằm xuống từ ô trước đó.

Với bất kỳ đường dẫn RoD nào như vậy, chúng ta có thể lấy tổng của các ô trong Ađường dẫn đó.

Ví dụ, hãy xem xét ma trận 4 by 3:

[ [1, 2, 3, 4],
  [5, 1, 6, 7],
  [8, 2, 1, 1] ]

Sau đó, chúng ta có thể xem xét đường dẫn RoD:

1 > 2   3   4
    v
5   1   6   7
    v
8   2 > 1 > 1

trong đó có một tổng số 1+2+1+2+1+1=8. Điều đáng chú ý là đường dẫn này có tổng nhỏ nhất trong tất cả các đường dẫn RoD có thể từ trên trái sang dưới phải trong ma trận đó.

Vì vậy, thách thức được đề xuất là cung cấp chức năng / chương trình ngắn nhất trong ngôn ngữ bạn chọn, đưa ra tổng tối thiểu một đường RoD từ phía trên bên trái sang phía dưới bên phải có thể có trong một ma trận nhất định A.

Các lỗ hổng bị cấm thông thường có hiệu lực. Đầu vào của bạn có thể ở bất kỳ định dạng hợp lý; đầu ra của bạn phải là một số nguyên.

Đây là môn đánh gôn; câu trả lời được tính theo số byte.

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

[ [5] ] -> 5

[ [5, 2] ] -> 7

[ [5], 
  [2] ] -> 7

[ [ 9 , 1 , 12, 3 ],
  [ 12, 11, 6 , 11],
  [ 12, 9 , 2 , 11] ] -> 40

[ [ 6 , 8 , 11, 2 ],
  [ 3 , 6 , 7 , 6 ],
  [ 6 , 2 , 8 , 12] ] -> 37

[ [ 4 , 5 , 8 , 4 ],
  [ 6 , 5 , 9 , 4 ],
  [ 2 , 5 , 6 , 8 ] ] -> 31

[ [ 4 , 5 , 15, 18, 30],
  [ 26, 26, 3 , 4 , 5 ],
  [ 7 , 9 , 29, 25, 14],
  [ 16, 1 , 27, 13, 27],
  [ 23, 11, 25, 24, 12],
  [ 17, 23, 7 , 14, 5 ] ] -> 94

[ [ 10, 15, 7 , 2 , 9 ],
  [ 24, 5 , 2 , 1 , 25],
  [ 2 , 12, 14, 30, 18],
  [ 28, 4 , 12, 22, 14],
  [ 15, 21, 21, 11, 4 ],
  [ 21, 15, 21, 29, 9 ] ] -> 103

Câu trả lời:


15

J , 42 byte

v(+}.<.}:)&.>/@{.[:</.(2#v=._1+1#.$){.!._]

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

Làm thế nào nó hoạt động

v(+}.<.}:)&.>/@{.[:</.(2#v=._1+1#.$){.!._]
                         v=._1+1#.$         Sum of two dimensions - 1; assign to v
                                            (v is a verb)
                      (2#          ){.!._]  Extend the given array in both dimensions
                 [:</.  Extract the antidiagonals as boxed arrays
v             @{.  Take the first `v` antidiagonals
 (       )&.>/     Reduce over unboxed items:
   }.<.}:            Given the right item R, take the minimum of R[1:] and R[:-1]
  +                  Add to the left item

Hình minh họa

1 2 3 4  Input array, dimensions = 3,4
5 1 6 7
8 2 1 1

1 2 3 4 _ _  Extended to 6,6 with filler _ (infinity)
5 1 6 7 _ _
8 2 1 1 _ _
_ _ _ _ _ _
_ _ _ _ _ _
_ _ _ _ _ _

1            Diagonalize and take first 6 rows
5 2
8 1 3
_ 2 6 4
_ _ 1 7 _
_ _ _ 1 _ _

Reduction: left+min(right[1:], right[:-1])
1                                          1  => 8
5 2                               5  2  => 10 7
8 1 3                   8 1 3  => 12 5 11
_ 2 6 4      _ 2 6 4 => _ 4 8 12
_ _ 1 7 _ => _ _ 2 8 _
_ _ _ 1 _ _

3
Đây là một giải pháp thực sự tốt đẹp!
Galen Ivanov

7

JavaScript (ES6), 78 77 76 byte

m=>(M=g=s=>(v=(m[y]||0)[x])?g(s+=v,y++)|g(s,x++,y--)*x--|M<s?M:M=s:0)(x=y=0)

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

Đã bình luận

m => (                      // m[] = input matrix
  M =                       // initialize the minimum M to a non-numeric value
  g = s =>                  // g = recursive function taking the current sum s
    (v = (m[y] || 0)[x]) ?  //   if the current cell v is defined:
      g(s += v, y++) |      //     do a recursive call at (x, y + 1)
      g(s, x++, y--) * x--  //     do a recursive call at (x + 1, y)
      |                     //     if at least one call did not return 0 (which means
                            //     that we haven't reached the bottom-right corner)
      M < s ?               //     or M is less than s (false if M is still non-numeric):
        M                   //       return M unchanged
      :                     //     else:
        M = s               //       update M to s, and return this new value
    :                       //   else (we're outside the bounds of the matrix):
      0                     //     return 0
)(x = y = 0)                // initial call to g with s = x = y = 0

5

Haskell, 63 57 byte

f x@((a:_:_):c:d)=a+min(f$c:d)(f$tail<$>x)
f x=sum$id=<<x

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

f x@((a:_:_):c:d)=           -- if it's at least a 2x2 matrix
   a+min                     -- add the top left element to the minimum of the
                             -- path costs of
        f$c:d                --   the matrix with the first row dropped and
        f$tail<$>x           --   the matrix with the first column dropped
f x=                         -- else, i.e. a 1xm or nx1 matrix, i.e. a vector
    sum$id=<<x               -- return the sum of this vector

4

MATL , 38 36 30 29 byte

Cảm ơn @Giuseppe đã chỉ ra một lỗi, giờ đã sửa.

lyZyqsG&nghZ^Yc!tsGz=Z)Ys)sX<

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

l        % Push 1
y        % Input, implicit. Duplicate from below. Pushes the input below
         % the current 1, and a copy of the input on top
Zy       % Size of input. Gives [m, n]
qs       % Subtract 1 element-wise, sum. Gives m+n-2
G        % Push input again
&n       % Push size as two separate numbers. Gives m, n
gh       % Transform n into 1 and concatenate horizontally. Gives [m, 1]
Z^       % Cartesian power of [m, 1] raised to m+n-2. This produces the
         % Cartesian tuples as row of a matrix. A typical tuple may be
         % [1, m, 1, m, m]. This will define a path along the matrix in
         % linear, column-wise indexing (down, then across). So 1 means
         % move 1 step down, and m means move m steps "down", which is
         % actually 1 step to the right
Yc       % Concatenate strcat-like. This prepends the 1 that is at the
         % bottom of the stack to each row
!        % Transpose. Each tuple (extended with initial 1) is now a column
!ts      % Duplicate, sum of each column
Gz       % Number of nonzeros of input. Gives m*n-1
=Z)      % Keep only columns that sum m*n. That means that, starting from
Ys       % Cumulative sum of each column. This defines the path
)        % Index: pick entries specified by the path
s        % Sum of each column
X<       % Minimum
         % Display, implicit

3

R , 90 byte

function(m){l=sum(m|1)
if(l>1)for(i in 2:l)m[i]=m[i]+min(m[i-1],m[max(0,i-nrow(m))])
m[l]}

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

Giải pháp ngây thơ: lặp qua mảng (xuống các cột), thay thế từng mục bằng tổng của chính nó và mức tối thiểu của các hàng xóm bên trên và bên trái của nó, nếu chúng tồn tại, sau đó trả về mục cuối cùng.


Có thể tính toán tất cả các con đường và chọn tối thiểu là golfier.
Giuseppe

3

Perl 6 , 57 54 byte

my&f={|.flat&&.[0;0]+min (f(.[1..*]),f $_>>[1..*])||0}

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

Giải trình

my&f={                                               }  # Function f
      |.flat&&  # Return empty slip if matrix is empty
              .[0;0]+  # Value at (0,0) plus
                     min  # Minimum of
                          f(.[1..*])   # Rows 1..*
                                     f $_>>[1..*]  # Columns 1..*
                         (          ,            )||0  # Or 0 if empty

53 byte thông qua việc sử dụng $!thay vì&f
Jo King


2

Python 3 , 108 byte

def f(A,m,n,i=0,j=0):r=i+1<m and f(A,m,n,i+1,j);d=j+1<n and f(A,m,n,i,j+1);return A[i][j]+min(r or d,d or r)

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

Bị đánh cắp

def f(A, m, n, i=0, j=0):
    right = i + 1 < m and f(A, m, n, i + 1, j)
    down  = j + 1 < n and f(A, m, n, i, j + 1)
    return A[i][j] + min(right or down, down or right)

2

Thạch , 21 byte

ZI_.ỊȦ
ŒJŒPÇƇLÐṀœị⁸§Ṃ

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

Làm sao?

ZI_.ỊȦ - Link 1: isDownRight?: List of 2d indices (limited to having no repetitions)
Z      - transpose
 I     - deltas (vectorises)
  _.   - subtract 1/2 (vectorises)
    Ị  - insignificant? (effectively _.Ị here is like "v in {0,1}? 1 : 0")
     Ȧ - any & all (0 if a 0 is present when flattened, else 1)

ŒJŒPÇƇLÐṀœị⁸§Ṃ - Main Link: list of lists of integers, A
ŒJ             - multi-dimensional indices of A
  ŒP           - power-set
     Ƈ         - filter keep only those truthy by:
    Ç          -   last link as a monad
       ÐṀ      - filter keep only those maximal by:
      L        -   length
           ⁸   - chain's left argument, A
         œị    - multi-dimensional index into (vectorises)
            §  - sum each
             Ṃ - minimum

2

APL (Dyalog Classic) , 37 32 byte

{⊃⌽,9e9(⊢⌊⍵+(2⊣⌿⍪)⌊2⊣/,)⍣≡+⍀+\⍵}

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

+⍀+\ tổng một phần theo chiều ngang và chiều dọc - điều này cung cấp sự đánh giá quá cao ban đầu cho các đường dẫn đến mỗi hình vuông

9e9(... )⍣≡áp dụng "..." cho đến khi hội tụ, ở mỗi bước vượt qua một số lượng rất lớn (9 × 10 9 ) làm đối số bên trái

,thêm 9e9-s vào bên trái của ước tính hiện tại

2⊣/ lấy cái đầu tiên từ mỗi cặp ô liên tiếp, thả cột cuối cùng một cách hiệu quả

2⊣⌿⍪điều tương tự theo chiều dọc - đặt 9e9lên trên và thả hàng cuối cùng

(2⊣⌿⍪) ⌊ 2⊣/, cực tiểu

⍵+ thêm ma trận gốc

⊢⌊ cố gắng cải thiện các ước tính hiện tại với điều đó

⊃⌽, ô dưới cùng bên phải


2
Bạn có thể cung cấp một lời giải thích về giải pháp của bạn?
Galen Ivanov

1

Than , 46 byte

≔E§θ⁰∧κΣ§θ⁰ηFθ«≔§η⁰ζFLι«≔⁺⌊⟦§ηκζ⟧§ικζ§≔ηκζ»»Iζ

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải thích: Điều này có lẽ sẽ ngắn hơn nếu có một đối số ba reducetrong Char than.

≔E§θ⁰∧κΣ§θ⁰η

Điền trước mảng làm việc với các giá trị lớn ngoại trừ mảng đầu tiên bằng không.

Fθ«

Vòng qua các hàng của đầu vào.

≔§η⁰ζ

Khởi tạo tổng hiện tại với phần tử đầu tiên của mảng làm việc.

FLι«

Vòng qua các cột của đầu vào.

≔⁺⌊⟦§ηκζ⟧§ικζ

Lấy mức tối thiểu của tổng hiện tại và phần tử hiện tại của mảng làm việc và thêm phần tử hiện tại của đầu vào để đưa ra tổng hiện tại mới.

§≔ηκζ

Và lưu trữ trở lại trong mảng làm việc đã sẵn sàng cho hàng tiếp theo.

»»Iζ

In tổng số một khi đầu vào đã được xử lý hoàn toàn.



1

Java 8, 197 193 byte

m->{int r=m.length-1,c=m[0].length-1,i=r,a;for(;i-->0;m[i][c]+=m[i+1][c]);for(i=c;i-->0;m[r][i]+=m[r][i+1]);for(i=r*c;i-->0;r=m[i/c][i%c+1],m[i/c][i%c]+=a<r?a:r)a=m[i/c+1][i%c];return m[0][0];}

-4 byte nhờ @ceilingcat .

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

Giải thích chung:

Tôi thực sự đã làm thử thách này khoảng một năm trước với Dự án Euler # 81 , ngoại trừ việc được giới hạn trong một ma trận vuông thay vì một Nbởi Mma trận. Vì vậy, tôi đã sửa đổi một chút mã của mình từ trước đó để giải thích cho điều đó.

Trước tiên tôi tổng hợp hàng dưới cùng và cột ngoài cùng bên phải từ ô cuối cùng trở về sau. Vì vậy, hãy sử dụng ma trận ví dụ của thử thách:

1, 2, 3, 4
5, 1, 6, 7
8, 2, 1, 1

Tế bào cuối cùng vẫn giữ nguyên. Ô cuối cùng thứ hai của hàng dưới cùng trở thành tổng: 1+1 = 2và tương tự cho ô cuối cùng thứ hai của cột ngoài cùng bên phải : 1+7 = 8. Chúng tôi tiếp tục làm điều này, vì vậy bây giờ ma trận trông như thế này:

 1,  2,  3, 12
 5,  1,  6,  8
12,  4,  2,  1

Sau khi làm điều đó, chúng tôi xem xét tất cả các hàng còn lại lần lượt từ dưới lên trên và từ phải sang trái (ngoại trừ cột / hàng cuối cùng) và chúng tôi tìm từng ô ở cả ô bên dưới và bên phải của ô để xem cái nào nhỏ hơn

Vì vậy, ô chứa số 6trở thành 8, bởi vì 2bên dưới nó nhỏ hơn 8bên phải của nó. Sau đó, chúng tôi nhìn vào phần 1tiếp theo của nó (bên trái) và làm tương tự. Điều đó 1trở thành 5, bởi vì 4bên dưới nó nhỏ hơn 8bên phải của nó.

Vì vậy, sau khi chúng ta hoàn thành hàng thứ hai đến hàng cuối cùng, ma trận trông như thế này:

 1,  2,  3, 12
10,  5,  8,  8
12,  4,  2,  1

Và chúng tôi tiếp tục làm điều này cho toàn bộ ma trận:

 8,  7, 11, 12
10,  5,  8,  8
12,  4,  2,  1

Bây giờ, ô đầu tiên sẽ chứa kết quả của chúng ta, 8trong trường hợp này.

Mã giải thích:

m->{                    // Method with integer-matrix input and integer return-type
  int r=m.length-1,     //  Amount of rows minus 1
      c=m[0].length-1,  //  Amount of columns minus 1
      i=r,              //  Index integer
      a;                //  Temp integer
  for(;i-->0;m[i][c]+=m[i+1][c]);
                        //  Calculate the suffix-sums for the rightmost column
  for(i=c;i-->0;m[r][i]+=m[r][i+1]);
                        //  Calculate the suffix-sums for the bottom row
  for(i=r*c;i-->0       //  Loop over the rows and columns backwards
      ;                 //     After every iteration:
       r=m[i/c][i%c+1], //      Set `r` to the value left of the current cell
       m[i/c][i%c]+=a<r?//      If `a` is smaller than `r`:
                 a      //       Add `a` to the current cell
                :       //      Else:
                 r)     //       Add `r` to the current cell
      a=m[i/c+1][i%c];  //    Set `a` to the value below the current cell
  return m[0][0];}      //  Return the value in the cell at index {0,0} as result

1

Brachylog , 26 25 byte

∧≜.&{~g~g|hhX&{b|bᵐ}↰+↙X}

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

-1 byte vì việc cắt giảm là không cần thiết - bạn không thể lấy phần đầu của danh sách trống

Có lẽ có rất nhiều phòng để chơi gôn này nhưng tôi cần ngủ.

Cách tiếp cận tập trung vào việc thử mọi giá trị cho đầu ra, nhỏ nhất trước, ( ∧≜.) cho đến khi có thể tìm thấy một đường dẫn ( b|bᵐ) đến góc dưới bên phải ( ~g~g) tạo ra tổng đó ( hhX&...↰+↙X).


0

Java (JDK) , 223 byte

Đưa đầu vào dưới dạng Danh sách 2D của số nguyên.

Thêm 19 byte cho import java.util.*;bao gồm.

import java.util.*;m->{var l=m.get(0);int s=m.size(),c=l.size(),x=-1>>>1,a=l.get(0);return s*c<2?a:Math.min(s>1?n.n(new Vector(m.subList(1,s))):x,c>1?n.n(new Vector<>(m){{replaceAll(l->new Vector(l.subList(1,c)));}}):x)+a;}

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


Làm thế nào nó hoạt động

import java.util.*;                                     // Import needed for Vector class
m->{                                                    // Lambda that takes a 2D list of integers
    var r=m.get(0);                                     // Store first row in variable
    int h=m.size(),                                     // Store number of rows
        w=r.size(),                                     // Store number of columns
        x=-1>>>1,                                       // Store int max
        a=r.get(0);                                     // Store the current cell value
    return h*w<2?a:                                     // If matrix is single cell return value
        Math.min(                                       // Otherwise return the minimum of...

            h>1?                                        // If height is more than 1
                n.n(                                    // Recursively call this function with 
                    new Vector(m.subList(1,h))):        // a new matrix, without the top row
                x,                                      // Otherwise use int max as there is no row below this

            w>1?                                        // If width is more than 1
                n.n(new Vector<>(m){{                   // Recursively call this function with a new matrix             
                    replaceAll(                         // where all columns have been replaced with 
                        l->new Vector(l.subList(1,w))   // cloned lists without the leftmost column
                    );
                }}):                                    // Otherwise use int max as there is
                x                                       // no column to the right of this
        )+a;                                            // Add the current cell value to the result before returning
}

0

Con trăn 2 , 86 byte

f=lambda A:len(A)>1<len(A[0])and A[0][0]+min(f(zip(*A)[1:]),f(A[1:]))or sum(sum(A,()))

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

Nếu B là hoán vị của A, thì định nghĩa vấn đề ngụ ý rằng f(A)==f(B).

A[1:]là mảng Athiếu hàng trên cùng của nó. zip(*A[1:])là mảng Athiếu cột ngoài cùng bên trái và được hoán vị.sum(sum(A,()))là tổng của tất cả các yếu tố trong A.

Nếu Achỉ có một cột hoặc một hàng đơn, chỉ có một đường dẫn, do đó ftrả về tổng của tất cả các phần tử trong A; nếu không chúng tôi recurse và trả lại khoản A[0][0]+ nhỏ hơn của fcác Athiếu hàng đầu và fcác Athiếu cột tận cùng bên trái.

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.