Maximale Wege finden

12

Bei einem Quadrat aus positiven, natürlichen Zahlen findet ein Programm einen horizontalen und einen vertikalen Pfad, wobei die Summe der Zahlen maximal ist. Ein horizontaler Pfad geht von der ersten bis zur letzten Spalte und muss seine Spaltenposition in jedem Schritt um eins erhöhen. Ein vertikaler Pfad geht von der ersten bis zur letzten Zeile und muss seine Zeilenposition in jedem Schritt um eins erhöhen. Außerdem kann die Zeilenposition in einem horizontalen Pfad gleich bleiben oder sich in beiden Richtungen um eins ändern, ebenso für vertikale Pfade.

Zur Veranschaulichung kann Folgendes ein gültiger Pfad sein:

Illustration eines gültigen Pfades

Der folgende Pfad ist ungültig, da er rückwärts verläuft (und an einigen Stellen in derselben Zeile verbleibt):

Illustration eines ungültigen Pfades

Der folgende Pfad wäre ebenfalls ungültig, da er die Zeilenposition in einem einzigen Schritt um mehr als eins ändert:

Ein weiteres Beispiel für einen ungültigen Pfad

Hinweis: Die Lösung sollte in einer akzeptablen Zeit ausgeführt werden.

Eingang

Bei der Standardeingabe werden n Eingabezeilen mit jeweils n durch Leerzeichen getrennten positiven Ganzzahlen angegeben. 2 ≤ n ≤ 40. Jede Zeile wird durch einen Zeilenumbruch abgeschlossen. Die Zahlen sind klein genug, dass die maximale Summe in eine 32-Bit-Ganzzahl mit Vorzeichen passt.

Ausgabe

Die maximale Summe der horizontalen und vertikalen Pfade (in dieser Reihenfolge), die durch ein einzelnes Leerzeichen getrennt sind.

Probeneingabe 1

1 2
1 2

Beispielausgabe 1

3 4

Probeneingabe 2

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
2 1 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 4 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 4 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

Beispielausgabe 2

37 35

Probeneingabe 3

683 671 420 311 800 936
815 816 123 142 19 831
715 588 622 491 95 166
885 126 262 900 393 898
701 618 956 865 199 537
226 116 313 822 661 214

Beispielausgabe 3

4650 4799

Zu Ihrer Bequemlichkeit haben wir einige Testfälle in Bash (dank Ventero ) und PowerShell vorbereitet, über die Sie Ihr Programm ausführen können. Aufruf ist:, <test> <command line>also sowas wie ./test python paths.pyoder ./test.ps1 paths.exe. Habe Spaß :-)

Joey
quelle
@ Joey: Etwas veränderte Aufgabe von einer, die wir letztes Jahr in unserem Wettbewerb verwendet haben :)
Joey
+10 für das bashTestskript! Ich wünschte, alle Code Golf kam mit solchen.
MtnViewMark
@MtnViewMark: Wir versuchen :-) Ich persönlich hasse Aufgaben, die nach dem Posten zu viel Klärung erfordern, und ich schreibe normalerweise trotzdem meine eigenen Testskripte, da ich wissen muss, wann ein Golfversuch eine weitere Regression einführt. Ich habe auch beobachtet, dass einige Leute dazu neigen, einfach falsche Antworten zu posten. Testfälle helfen dabei, alle auf die gleiche Linie zu bringen. Eine Einrichtung zu haben, die für jede Aufgabe funktioniert, anstatt nur einmalige Hackjobs für jede Aufgabe zu machen, wäre eindeutig besser, aber wir sind noch nicht so weit ;-)
Joey,

Antworten:

6

GolfScript - 49 Nabb verbesserte Zeichen

51 Zeichen
50 absolut notwendige Zeichen + 3 Faulpelze, die nur die Aufgabe von 1 56 meist redundanten Zeichen erfüllten

n%{~]}%.zip{{0@+\{\.1>\3<$-1=@+}%\;}*$-1=\}2*' '@

51 Lösung:

n%{~]}%.zip{(\{0@+\{\.1>\3<$-1=@+}%\}%;$-1=\}2*' '@

53 Lösung:

n/{~]}%);.zip{(\{0@+\{\.1>\3<$-1=@+}%\}%;$-1=\}2*' '@
             a8_b9___c10___11______12 13      14_

Die Methode arbeitet auf zwei Zeilen gleichzeitig, wobei eine die an jedem Punkt maximal erreichten Summen und eine die nächste Zeile enthält.

a / 14: Für jedes Ergebnis zweimal wiederholen.
8: Nehmen Sie die erste Zeile vom Eingang und schalten Sie sie hinter das Eingangsarray, dies ist jetzt der erste Satz von Höchstsummen.
b / 13: Durchlaufen Sie jede verbleibende Zeile im Array.
9: Setzen Sie 0 am Anfang der Höchstsummen.
c / 12: Iteriere über jedes Element der Zeile.
10: Erstellen Sie eine Kopie der maximalen Summen, wobei das erste Element entfernt wird.
11: Nimm die ersten 3 Elemente der maximalen Summe, sortiere sie und addiere das größte zum aktuellen Element der Linie.

56 Lösung:

n/{~]}%);.zip{1,99*\{{\.1>\3<$-1=@+}%0\+\}%;$-1=\}2*' '@
1________2___ 3____ 4______________________5_____ 6_7___

1: Von der Eingabe bis zum Array von Arrays mit 9 Zeichen hätte es eigentlich mit nur 1 getan werden können, aber ich habe diesen Schlüssel gebrochen, damit dies getan werden muss.
2: 4 Zeichen, um eine transponierte Kopie zu erstellen.
3: Array von 99 0s in 5 Zeichen, es könnte wahrscheinlich intelligenter gemacht werden, aber ich rauche zu viel Gras, um herauszufinden, wie.
4: Übermäßig komplizierte Doppelschleife, die jedes einzelne Element der Eingabe durchläuft und Fuzzy-Logik oder ähnliches ausführt, um das Ergebnis zu erzielen. Nabb wird wahrscheinlich in ungefähr 3½ Zeichen etwas Äquivalentes machen.
5: Jetzt ist das Ergebnis da, in einem Array, das heißt, dieses alberne Stück Code ist nur da, um es rauszuholen (und ein Stück Reste zu verschwenden (und das Ergebnis an die richtige Stelle zu bringen)).
6: Dies ist ein Befehl, der so einfach ist, dass seine Zeichenanzahl in einer optimalen Lösung wahrscheinlich negativ wäre. 7: Zu diesem Zeitpunkt ist das Programm wirklich fertig, aber aufgrund der Schlamperei im vorhergehenden Code ist die Ausgabe in der falschen Reihenfolge und es fehlt ein Leerzeichen.

aaaaaaaaaaa
quelle
Ahh, ich habe nur aus Versehen angenommen, dass die Eingabe nicht mit einem Zeilenumbruch endet. Ich bin überrascht, dass es teilweise tatsächlich funktioniert hat. Solche Dinge bringen ein GolfScript-Programm normalerweise völlig durcheinander.
aaaaaaaaaaa 21.03.11
1
Sieht gut aus, obwohl Sie {}*anstelle von verwenden sollten (\{}%.
Nabb
Ja das macht Sinn, danke.
aaaaaaaaaaa
3

J 91, 95

a=:".;._2(1!:1)3
c=:4 :'>./x+"1|:y,.(1|.!.0 y),._1|.!.0 y'
p=:[:>./c/
(":(p|:a),p a)1!:2(4)

Ich lehne es ab, IO zu machen, was meine Punktzahl dramatisch verringert. Besteht alle Tests im Testkabelbaum ( funktioniert jedoch nur, wenn die Eingabe wie im Testkabelbaum mit einem Zeilenende endet).

Ich habe die Behandlung für Windows-Zeilenenden entfernt, da Chris vorgeschlagen hat, dass dies nicht notwendig ist. Die Multi-Plattform-Version hätte a=:".;._2 toJ(1!:1)3als erste Zeile.

Erläuterung:

  • fgibt das Lösungspaar durch normalen Aufruf von p und transponierte Eingabe ( |:) an.
  • pNimmt das Maximum ( >./) der Zeilensummen aus der Anwendung czwischen den einzelnen Zeilen ( c/)
  • cdauert zwei Zeilen (x und y). Es addiert x zu y, wobei y um 1 Zelle nach oben ( 1|.!.0 y) und y um 1 Zelle nach unten ( _1|.!.0 y) verschoben wird . Dann werden die Maximalwerte der drei Alternativen für jede Zeile verwendet. ( >./). Der Rest ist Rang - ich bin nicht sicher, ob ich es richtig mache.
Jesse Millikan
quelle
4
Genau, um deine Punktzahl zu senken. -1
aaaaaaaaaaaa
@eBusiness: Sind Sie sicher, dass Downvoting die richtige Antwort auf eine unvollständige Lösung ist?
Jesse Millikan
1
@ Joey: Nicht upvoting ist die andere Option. Ich war zu müde, um IO zu machen, aber meine Lösung unterscheidet sich so sehr von der anderen J-Lösung, dass ich sie unbedingt posten wollte. Wenn es einen expliziten Weg gäbe, die Antwort als "nicht teilnehmend" oder so ähnlich zu markieren, hätte ich das getan.
Jesse Millikan
@Joey: Ein weiterer Grund ist, dass Abwärtsstimmen wahrscheinlich nicht rückgängig gemacht werden, selbst wenn die Lösung feststeht. Der ursprüngliche Benutzer muss zurückkehren und seine Stimme ändern. (Gelöscht, erkannt, dass die Diskussion kurzgeschlossen und nicht gelöscht wurde. Ich schätze, ich werde stattdessen für das Abzeichen "Diszipliniert" schießen.)
Jesse Millikan
@ Jesse Millikan: Das machen wir. Keine Garantie, aber wenn Sie das Problem innerhalb einer angemessenen Zeit beheben, sollten die meisten Downvoter ihre Stimmen widerrufen.
aaaaaaaaaaa
3

Haskell: 314 notwendige Zeichen

import Data.Vector(fromList,generate,(!))
import List
l=fromList
x=maximum
g=generate
p a=show$x[m!i!0|i<-[0..h-1]]where{
w=length$head a;h=length$a;n=l$map l a;
m=g h$ \i->g w$ \j->n!i!j+x[k#(j+1)|k<-[i-1..i+1]];
i#j|i<0||i>=h||j>=w=0|1>0=m!i!j;}
q a=p a++' ':(p.transpose)a
main=interact$q.map(map read.words).lines

Hinweis: Dies erfordert das Modul Data.Vector . Ich bin nicht sicher, ob es in der Haskell-Plattform enthalten ist oder nicht.

Ungolfed-Version:

import Data.Vector(fromList,generate,(!))
import Data.List

-- horizontal; we use transpose for the vertical case
max_path :: [[Integer]] -> Integer
max_path numbers = maximum [m ! i ! 0 | i <- [0..h-1]] where
    w = length (head numbers)
    h = length numbers
    n = fromList $ map fromList numbers
    m = generate h $ \i -> generate w $ \j ->
        n ! i ! j + maximum [f i' (j+1) | i' <- [i-1..i+1]]
    f i j | i < 0 || i >= h || j >= w = 0
    f i j = m ! i ! j

max_paths :: [[Integer]] -> String
max_paths numbers = (show . max_path) numbers ++ " " ++
                    (show . max_path . transpose) numbers

main = interact $ max_paths . map (map read . words) . lines

Bei dieser Lösung wird Faulheit in Verbindung mit Data.Vector zum Speichern verwendet. Für jeden Punkt wird die Lösung für den maximalen Pfad von diesem bis zum Ende berechnet, dann in der Zelle von Vector gespeichert mund bei Bedarf wiederverwendet.

Joey Adams
quelle
Ich vermute, Sie können die geschweiften Klammern nach Ihrer where-Anweisung entfernen, wenn Sie alle Definitionen in einer einzigen Zeile zusammenfassen.
FUZxxl
2

Ruby 1.9, 155 Zeichen

f=->t{(1...l=t.size).map{|a|l.times{|b|t[a][b]+=t[a-1][(b>0?b-1:0)..b+1].max}};t[-1].max};q=[*$<].map{|a|a.split.map &:to_i};puts [f[q.transpose],f[q]]*" ""

Einfache Lösung, die alle Testfälle besteht.

Ventero
quelle
2

Haskell, 154 Zeichen

import List
z=zipWith
f=show.maximum.foldl1(\a->z(+)$z max(tail a++[0])$z max(0:a)a)
q a=f(transpose a)++' ':f a
main=interact$q.map(map read.words).lines

  • Bearbeiten: (155 -> 154) hat die Funktion umgeklappt
MtnViewMark
quelle
Wird die Verwendung zipWith3den Code verkürzen?
stolzer Haskeller
Ich denke, Sie könnten Maximum durch ersetzen foldl1 max, wodurch Zeichen hinzugefügt werden, aber Sie können foldl1 und max ausklammern, wodurch Zeichen gespart werden sollten.
stolzer Haskeller
maximum.foldl1, maxUnd max--vs-- f=foldl1;m=max;, f m.f, m, und m. - oder 20 gegen 22. Also, nein, es spart nicht.
MtnViewMark
Richtig. Und ich erinnerte mich nur daran, dass die Monomorphismus-Beschränkung aufhören würde zu schreiben m=max. Was ist mit zipWith3?
stolzer Haskeller
1

J, 109 + 10 = 119 Zeichen

y=:0".(1!:1)3
N=:%:#y
y=:y$~N,N
r=:(((1&{)(+(3>./\0,0,~]))(0&{)),2&}.)^:(<:N)
(":([:>./"1([:r|:),r)y)(1!:2)4

Laufen mit tr:

cat << EOF | tr \\n ' ' | ./maxpath.ijs

Wie in J üblich, ist der größte Teil des Codes für die Ein- / Ausgabe bestimmt. Der "tatsächliche" Code ist 65 Zeichen:

r=:(((1&{)(+(3>./\0,0,~]))(0&{)),2&}.)^:(<:#y)
([:>./"1([:r|:),r)y

Besteht alle Testfälle

Eelvex
quelle
Also brauchen wir JB wieder mit einer Lösung, die das Parsen auf 10 Zeichen reduziert? ;-)
Joey
@ Joey ich bin im Urlaub, ich habe kaum Internetzugang; nicht viel Zeit zum Golfen ;-)
JB
Können Sie mir sagen, wie Sie maxpath.ijs direkt ausführen?
Jesse Millikan
@Jesse: In * nix setze einiges #!/usr/bin/env jconsoleauf die Datei und setze das Executable Flag.
Eelvex
1

Python, 149

import sys
def f(g,t=[]):
 for r in g:t=[int(e)+max(t[i-1:i+2]+[0])for i,e in enumerate(r)]
 print max(t),
g=map(str.split,sys.stdin)
f(zip(*g)),f(g)

Wenn ich nur einen vertikalen oder horizontalen kürzesten Pfad berechnen würde,
könnte dies stattdessen an Ort und Stelle erfolgen und etwa ein Drittel der Bytes einsparen.

hallvabo
quelle
1

Python, 204 Zeichen

import sys
I=sys.stdin.read()
n=I.count('\n')
A=map(int,I.split())
R=range(n)
X=lambda h,a:[a[i]+max(([0]+h)[i:i+3])for i in R]
h=v=[0]*n
for i in R:h=X(h,A[i*n:i*n+n]);v=X(v,A[i::n])
print max(v),max(h)
Keith Randall
quelle