最大パスを見つける


12

正の二乗が与えられた場合、自然数はプログラムに沿って水平方向と垂直方向のパスを見つけ、それらに沿った数の合計が最大になるようにします。水平パスは、最後に、最初の列から進み、各ステップのいずれかによって、その列の位置を増加しなければなりません。縦パスは、最後に、最初の行から進み、各ステップのいずれかによって、その行の位置を増加しなければなりません。さらに、水平経路の行位置は、垂直経路の場合と同様に、同じままであるか、いずれかの方向に1つずつ変化します。

説明のために、以下が有効なパスである可能性があります。

有効なパスの図

次のパスは逆方向に進むため無効になります(一部の場所では同じ行に残ります)。

無効なパスの図

次のパスは、1つのステップで行の位置を複数変更するため、同様に無効になります。

無効なパスの別の図

注:ソリューションは許容可能な時間内に実行する必要があります。

入力

n 個のスペースで区切られた正の整数を持つ入力のn行は、標準入力で与えられます。2≤ N ≤40各行は改行で終了されます。数値は十分に小さいため、最大合計は32ビット符号付き整数に収まります。

出力

単一のスペースで区切られた水平および垂直パスの(その順序での)最大合計。

サンプル入力1

1 2
1 2

サンプル出力1

3 4

サンプル入力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

サンプル出力2

37 35

サンプル入力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

サンプル出力3

4650 4799

便宜上、プログラムを実行できるbash(Venteroに感謝)およびPowerShellでいくつかのテストケースを用意しました。呼び出しは:<test> <command line>なので、./test python paths.pyまたはのようなもの./test.ps1 paths.exeです。楽しんで :-)


@Joey:昨年のコンテストで使用したタスクからわずかに変更されたタスク:)
— Joey

bashテストスクリプトで+10 !私はすべてのコードゴルフがそのように付属したことを望みます。
— MtnViewMark

@MtnViewMark:私たちは試してみました:-)個人的には、投稿後にあまりにも明確な説明が必要なタスクが嫌いです。ゴルフの試行がさらに回帰を引き起こす場合を知る必要があるので、通常はとにかく独自のテストスクリプトを記述します。また、一部の人々は明らかに間違った回答を投稿する傾向があることを観察しました。テストケースは、全員を同じ路線に乗せるのに役立ちます。各タスクの1回限りのハックジョブではなく、すべてのタスクで機能する機能を備えている方が明らかに優れていますが、まだ十分ではありません;
— Joey

回答:


6

GolfScript-49個のNabb拡張キャラクター

51キャラクター
50厳密かつ完全に必要なキャラクター+ 1 56 の仕事だけをした3怠け者、
ほとんど冗長なキャラクター

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

51ソリューション:

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

53ソリューション:

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

このメソッドは一度に2行で機能し、1行には各ポイントで到達した最大合計が含まれ、もう1行には次の行が含まれます。

a / 14:結果ごとに1回ずつ、2回繰り返します。
8:入力から最初の行を取得し、入力配列の後ろに切り替えます。これは、現在の最大合計の最初のセットです。
b / 13:配列の残りの各行を反復処理します。
9:最大合計の先頭に0を付けます。
c / 12:行の各要素を反復処理します。
10:最初の要素を削除して、最大合計のコピーを作成します。
11:最大合計の最初の3つの要素を取得し、並べ替えて、最大値を行の現在の要素に追加します。

56ソリューション:

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

1:入力から9文字の配列の配列まで、実際には1つだけでできたはずですが、そのキーを壊したので、これが必要になります。
2:転置コピーを作成するための4文字。
3:5文字の99 0の配列。おそらくよりスマートな方法で行うことができますが、どのようにすればいいかわからないほど雑草を吸います。
4:入力の各要素を繰り返し処理し、結果を生成するファジーロジックなどを実行する、非常に複雑なダブルループ。Nabbは、おそらく約3½文字で同等のものを作成します。
5:ここまでで、結果は配列の中にあります。つまり、この愚かなコードは、それを取り出すためだけにあります(そして、残りの部分をジャンクします(そして、結果を適切な場所に切り替えます))。
6:これは非常に単純なコマンドであるため、最適なソリューションでは文字数が負になる可能性があります。7:この時点でプログラムは実際に完了しましたが、前のコードのずさんさのために、出力の順序が間違っており、スペースが不足しているため、ここからさらに少し掘り下げます。


ああ、間違って入力が改行で終わらないと思っただけです。それが実際に部分的に機能したことに驚いています。そのようなものは通常、GolfScriptプログラムを完全に台無しにします。
— aaaaaaaaaaaa

1
の{}*代わりに使用する必要がありますが、うまく見えます(\{}%。
— ナブ

はい、それは理にかなっています、ありがとう。
— aaaaaaaaaaaa

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)

IOの実行を拒否し、スコアを劇的に下げました。テストハーネス内のすべてのテストに合格します(ただし、テストハーネスのように入力が行末で終わる場合にのみ機能します)。

クリスが必要ではないと示唆したので、Windowsの行末の処理を削除しました。マルチプラットフォームバージョンがa=:".;._2 toJ(1!:1)3最初の行になります。

説明:

  • fpを通常に呼び出し、入力を転置(|:)することにより、ソリューションペアを提供します。
  • p各行の間に>./適用さcれる行合計の最大値()を取得します(c/)
  • c2行(xとy)を取ります。各yにxを追加し、yを1セル上にシフト(1|.!.0 y)、yを1セル下にシフト(_1|.!.0 y)します。次に、各行に対して3つの選択肢の最大値を取ります。(>./)。残りはランク[原文のまま]-正しく実行しているかどうかわかりません。

4
正確に、あなたのスコアを下げます。-1
— aaaaaaaaaaaa

@eBusiness:不完全なソリューションに対する正しい回答は、ダウンボーティングであると確信していますか?
— ジェシーミリカン

1
@Joey:他の選択肢は、賛成しないことです。当時はあまりにも疲れていたためIOを実行できませんでしたが、私のソリューションは他のJソリューションとは非常に異なるため、とにかく投稿したかったのです。答えを「非参加」またはそのような何かとしてマークする明示的な方法があれば、私はそうするでしょう。
— ジェシーミリカン

@Joey:別の理由は、解決策が修正されたとしても、下票が取り消される可能性が低いことです。元のユーザーが戻って投票を変更する必要があります。(削除され、議論が短絡されたことに気付き、削除されていない。代わりに「規律」バッジを撃つと思う。)
— ジェシーミリカン

@ジェシーミリカン:私たちはそれを行います。保証はありませんが、妥当な時間内に問題を修正した場合、ほとんどのダウンボッターは投票を取り消す必要があります。
— aaaaaaaaaaaa

3

Haskell:314の必要な文字

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

注:これには、モジュールData.Vectorが必要です。Haskellプラットフォームに含まれているかどうかはわかりません。

ゴルフされていないバージョン:

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

このソリューションでは、メモ化のためにData.Vectorと連携して遅延を使用します。すべてのポイントについて、そこから最後までの最大パスの解が計算され、Vectorのセルに保存され、m必要に応じて再利用されます。


すべての定義を1行にまとめる場合、whereステートメントの後に中括弧を削除できると思います。
— FUZxxl

2

Ruby 1.9、155文字

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]]*" ""

すべてのテストケースに合格する簡単なソリューション。


2

Haskell、154文字

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

  • 編集:(155-> 154)折り畳まれた関数をインライン化

を使用zipWith3するとコードが短くなりますか?
— 誇りに思ってhaskeller 14

maximumをfoldl1 maxに置き換えて、文字を追加できますが、foldl1とmaxを因数分解して、文字を節約できると思います。
— 誇りに思ってhaskeller 14

maximum.foldl1、max、およびmax--vs-- f=foldl1;m=max;、f m.f、m、とm。-または20対22。だから、いや、それは保存しません。
— MtnViewMark

正しい。そして、単相性の制限が書き込みを停止することを思い出しましたm=max。zipWith3はどうですか?
— 誇りに思ってhaskeller 14

1

J、109 + 10 = 119文字

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

で実行tr:

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

Jでの通常のように、コードのほとんどは入出力用です。「実際の」コードは65文字です。

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

すべてのテストケースに合格


そこで、解析を10文字に減らすソリューションを備えたJBが再び必要になりますか?;-)
— ジョーイ

@Joey私は休暇中です。ほとんどインターネットにアクセスできません。ゴルフの時間があまりない;-)
— JB

maxpath.ijsを直接実行している方法を教えてください。
— ジェシーミリカン

@Jesse:* nixでは#!/usr/bin/env jconsole、ファイルの上にいくつかを置き、実行可能フラグを設定します。
— エルベックス

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)

垂直または水平の最短経路のみを計算する場合、
代わりにインプレースで実行でき、バイトの約3分の1を節約できます。


1

Python、204文字

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