Gewicht des am wenigsten gewichteten RoD-Pfads

16

Sei Aeine mdurch nrechteckige Matrix positiver Ganzzahlen, wobei mund nauch positive Ganzzahlen sind.

Wir sind an RoD-Pfaden ('Rechts-oder-Runter'-Pfaden) von der oberen linken Zelle Azur unteren rechten Zelle interessiert . In einem RoD-Pfad ist jede nachfolgende Zelle des Pfads entweder eine Zelle rechts von oder eine Zelle nach unten von der vorherigen Zelle.

Bei einem solchen RoD-Pfad können wir die Summe der Zellen Ain diesem Pfad nehmen.

Betrachten Sie zum Beispiel die 4 x 3-Matrix:

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

Dann können wir den RoD-Pfad betrachten:

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

das hat eine Summe von 1+2+1+2+1+1=8. Es ist erwähnenswert, dass dieser Pfad die kleinste Summe aller möglichen RoD-Pfade von links oben nach rechts unten in dieser Matrix aufweist.

Die vorgeschlagene Herausforderung besteht also darin, die kürzeste Funktion / das kürzeste Programm in der Sprache Ihrer Wahl bereitzustellen, die bzw. das die minimale Summe ausgibt, die ein RoD-Pfad von links oben nach rechts unten in einer bestimmten Matrix haben kann A.

Es gelten die üblichen verbotenen Lücken. Ihre Eingabe kann in jedem vernünftigen Format erfolgen. Ihre Ausgabe muss eine Ganzzahl sein.

Das ist Code-Golf; Die Antworten werden nach Anzahl der Bytes bewertet.

Testfälle

[ [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
Chas Brown
quelle

Antworten:

15

J , 42 Bytes

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

Probieren Sie es online!

Wie es funktioniert

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

Illustration

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 _ _
Bubbler
quelle
3
Das ist eine wirklich schöne Lösung!
Galen Ivanov
7

JavaScript (ES6), 78 77 76 Bytes

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)

Probieren Sie es online!

Kommentiert

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
Arnauld
quelle
5

Haskell, 63.57 Bytes

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

Probieren Sie es online!

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
nimi
quelle
4

MATL , 38 36 30 29 Bytes

Vielen Dank an @ Giuseppe für den Hinweis auf einen Fehler, der jetzt korrigiert wurde.

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

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

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
Luis Mendo
quelle
3

R , 90 Bytes

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

Probieren Sie es online!

Die naive Lösung: Durchlaufen Sie das Array (in den Spalten) und ersetzen Sie jeden Eintrag durch die Summe aus sich selbst und dem Minimum der darüber und links davon liegenden Nachbarn, sofern vorhanden. Geben Sie dann den letzten Eintrag zurück.

Giuseppe
quelle
Die Berechnung aller Pfade und die Auswahl des Minimums ist möglicherweise Golfspieler.
Giuseppe
3

Perl 6 , 57 54 Bytes

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

Probieren Sie es online!

Erläuterung

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
nwellnhof
quelle
53 Bytes durch Verwenden von $!anstelle von&f
Jo King
2

Python 3 , 108 Bytes

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)

Probieren Sie es online!

Ungolfed

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)
David Foerster
quelle
2

Jelly , 21 Bytes

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

Probieren Sie es online!

Wie?

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
Jonathan Allan
quelle
2

APL (Dyalog Classic) , 37 32 Bytes

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

Probieren Sie es online!

+⍀+\ Teilsummen horizontal und vertikal - dies liefert eine anfängliche Überschätzung für die Pfade zu jedem Quadrat

9e9(... )⍣≡wende "..." bis zur Konvergenz an und übergebe bei jedem Schritt eine sehr große Zahl (9 × 10 9 ) als linkes Argument

,Add- 9e9s links von der aktuellen Schätzung

2⊣/ nimm die erste von jedem Paar aufeinanderfolgender Zellen und lasse die letzte Spalte effektiv fallen

2⊣⌿⍪Das Gleiche vertikal - 9e9oben auflegen und letzte Reihe fallen lassen

(2⊣⌿⍪) ⌊ 2⊣/, Minima

⍵+ Fügen Sie die ursprüngliche Matrix hinzu

⊢⌊ versuchen Sie damit die aktuellen Schätzungen zu verbessern

⊃⌽, Zelle rechts unten

ngn
quelle
2
Können Sie eine Erklärung für Ihre Lösung abgeben?
Galen Ivanov
1

Kohle , 46 Bytes

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

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erklärung: Dies wäre wahrscheinlich kürzer, wenn es reducein Charcoal drei Argumente gäbe .

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

Füllen Sie das Arbeitsarray mit großen Werten vor, mit Ausnahme des ersten, der Null ist.

Fθ«

Schleife über die Zeilen der Eingabe.

≔§η⁰ζ

Initialisieren Sie die aktuelle Summe mit dem ersten Element des Arbeitsarrays.

FLι«

Durchlaufen Sie die Spalten der Eingabe.

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

Nehmen Sie das Minimum der aktuellen Summe und des aktuellen Elements des Arbeitsarrays und fügen Sie das aktuelle Element der Eingabe hinzu, um die neue aktuelle Summe zu erhalten.

§≔ηκζ

Und bewahren Sie das wieder in der Arbeitsgruppe auf, damit es für die nächste Reihe bereit ist.

»»Iζ

Gibt die Gesamtsumme aus, sobald die Eingabe vollständig verarbeitet wurde.

Neil
quelle
1

Java 8, 197, 193 Bytes

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 Bytes dank @ceilingcat .

Probieren Sie es online aus.

Allgemeine Erklärung:

Ich habe eigentlich schon diese Herausforderung vor etwa einem Jahr mit Projekt Euler # 81 , mit der Ausnahme , dass auf einer quadratischen Matrix beschränkt wurde anstelle einer Nvon MMatrix. Also habe ich meinen Code von damals leicht verändert, um das zu berücksichtigen.

Ich summiere zuerst die unterste Zeile und die äußerste rechte Spalte von der allerletzten Zelle zurück. Verwenden wir also die Beispielmatrix der Herausforderung:

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

Die letzte Zelle bleibt gleich. Die zweite letzte Zelle der unteren Reihe wird die Summe: 1+1 = 2, und das gleiche für die zweite letzten Zelle der Spalte ganz rechts: 1+7 = 8. Wir machen damit weiter, also sieht die Matrix jetzt so aus:

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

Danach betrachten wir alle verbleibenden Zeilen nacheinander von unten nach oben und von rechts nach links (mit Ausnahme der letzten Spalte / Zeile) und suchen nach jeder Zelle, die sich sowohl unter als auch rechts davon befindet welches ist kleiner.

So ist die Zelle , die die Zahl enthält , 6wird 8, weil die 2darunter kleiner als die 8rechts davon. Dann schauen wir uns das 1nächste an (links) und machen dasselbe. Das 1wird 5, weil das 4darunter kleiner ist als das 8rechts davon.

Nachdem wir mit der vorletzten Zeile fertig sind, sieht die Matrix folgendermaßen aus:

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

Und das machen wir für die gesamte Matrix weiter:

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

Jetzt enthält die allererste Zelle unser Ergebnis, 8in diesem Fall.

Code Erklärung:

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
Kevin Cruijssen
quelle
1

Brachylog , 26 25 Bytes

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

Probieren Sie es online!

-1 Byte, weil der Schnitt nicht notwendig ist - Sie können den Kopf einer leeren Liste nicht nehmen

Es gibt wahrscheinlich viel Platz zum Golfen, aber ich brauche Schlaf.

Der Ansatz läuft darauf hinaus, jeden Wert für die Ausgabe (kleinster zuerst) ( ∧≜.) zu versuchen, bis ein Pfad ( b|bᵐ) zur rechten unteren Ecke ( ~g~g) gefunden wird, der diese Summe ( hhX&...↰+↙X) ergibt .

Nicht verwandte Zeichenfolge
quelle
0

Java (JDK) , 223 Byte

Übernimmt die Eingabe als 2D-Liste von Ints.

Zusätzliche 19 Bytes für import java.util.*;enthalten.

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

Probieren Sie es online!


Wie es funktioniert

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
}
Luke Stevens
quelle
0

Python 2 , 86 Bytes

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

Probieren Sie es online!

Wenn dies Bdie Transposition von ist A, dann impliziert die Problemdefinition dies f(A)==f(B).

A[1:]Fehlt dem Array Adie oberste Zeile? Fehlt zip(*A[1:])dem Array Adie Spalte ganz links und ist es transponiert? sum(sum(A,()))ist die Summe aller Elemente in A.

Wenn Anur eine einzelne Spalte oder Zeile vorhanden ist, gibt es nur einen Pfad. fDaher wird die Summe aller Elemente in zurückgegeben A. andernfalls wir die Summe der Rekursion und das Rück A[0][0]+ die kleineren von fder Afehlt die obere Reihe und fder Afehlte die Spalte ganz links.

Chas Brown
quelle