Menemukan jalur maksimum

12

Diberikan kuadrat positif, bilangan asli menulis sebuah program menemukan jalur horizontal dan vertikal dengan jumlah angka di sepanjang mereka menjadi maksimal. Sebuah horisontal jalan pergi dari kolom pertama untuk yang terakhir dan harus meningkatkan posisi kolom sebesar satu dalam setiap langkah. Sebuah vertikal jalan pergi dari baris pertama sampai terakhir dan harus meningkatkan posisi barisnya oleh salah satu di setiap langkah. Lebih jauh lagi, posisi baris dalam jalur horizontal dapat tetap sama atau berubah satu arah, demikian pula untuk jalur vertikal.

Sebagai ilustrasi, berikut ini bisa menjadi jalur yang valid:

Ilustrasi jalur yang valid

Jalur berikut ini tidak valid, karena langkah mundur (dan tetap di baris yang sama di beberapa tempat):

Ilustrasi jalur yang tidak valid

Jalur berikut ini akan sama-sama tidak valid, karena itu mengubah posisi baris lebih dari satu dalam satu langkah:

Ilustrasi lain dari jalur yang tidak valid

Catatan: Solusinya harus berjalan dalam jumlah waktu yang dapat diterima.

Memasukkan

n baris input dengan n bilangan bulat positif yang dipisahkan spasi, masing-masing diberikan pada input standar. 2 ≤ n ≤ 40. Setiap baris diakhiri oleh satu baris. Jumlahnya cukup kecil sehingga jumlah maksimumnya pas dengan integer bertanda 32-bit.

Keluaran

Jumlah maksimum jalur horizontal dan vertikal (dalam urutan itu) dipisahkan oleh satu ruang.

Masukan sampel 1

1 2
1 2

Output sampel 1

3 4

Masukan sampel 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

Output sampel 2

37 35

Masukan sampel 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

Keluaran sampel 3

4650 4799

Untuk kenyamanan Anda, kami telah menyiapkan beberapa test case di bash (terima kasih kepada Ventero ) dan PowerShell yang dapat Anda jalankan melalui program Anda. Doa adalah:, <test> <command line>jadi sesuatu seperti ./test python paths.pyatau ./test.ps1 paths.exe. Selamat bersenang-senang :-)

Joey
sumber
@ Joey: Sedikit mengubah tugas dari yang kami gunakan tahun lalu dalam kontes kami :)
Joey
+10 untuk bashskrip uji! Saya berharap semua kode golf datang dengan itu.
MtnViewMark
@MtnViewMark: Kami mencoba :-) Secara pribadi saya benci tugas yang memerlukan terlalu banyak klarifikasi setelah diposting dan saya biasanya menulis skrip tes saya sendiri karena saya perlu tahu kapan upaya untuk golf lebih lanjut memperkenalkan regresi. Saya juga mengamati bahwa beberapa orang cenderung mengirim jawaban yang salah. Test case membantu membuat semua orang di jalur yang sama. Memiliki fasilitas yang berfungsi untuk setiap tugas, alih-alih hanya satu kali hackjobs untuk setiap tugas jelas akan lebih baik, tetapi kami belum cukup di sana ;-)
Joey

Jawaban:

6

GolfScript - 49 Nabb karakter yang disempurnakan

51 karakter
50 karakter yang benar-benar diperlukan + 3 slackers yang hanya mengerjakan tugas 1
56 sebagian besar karakter redundan

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

51 solusi:

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

53 solusi:

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

Metode ini bekerja pada dua baris sekaligus, satu berisi jumlah maksimum yang dicapai pada setiap titik, dan satu lagi berisi baris berikutnya.

a / 14: Ulangi dua kali, sekali untuk setiap hasil.
8: Ambil baris pertama dari input dan alihkan di belakang array input, ini sekarang set pertama jumlah maksimum.
b / 13: Ulangi setiap baris yang tersisa dalam array.
9: Masukkan 0 di awal jumlah maksimum.
c / 12: Iterasi setiap elemen dari garis.
10: Buat salinan jumlah maksimum dengan elemen pertama dihapus.
11: Ambil 3 elemen pertama dari jumlah maksimum, urutkan dan tambahkan yang terbesar ke elemen baris saat ini.

56 solusi:

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

1: Dari input ke array array dalam 9 karakter, sebenarnya itu bisa dilakukan hanya dengan 1, tapi saya memecahkan kunci itu jadi ini harus dilakukan.
2: 4 karakter hanya untuk membuat salinan yang dialihkan.
3: Array of 99 0s dalam 5 karakter, mungkin bisa dilakukan dengan cara yang lebih cerdas, tapi aku terlalu banyak merokok untuk mencari cara.
4: Loop ganda yang terlalu rumit yang mengulangi setiap elemen input dan melakukan logika fuzzy atau sesuatu seperti itu untuk menghasilkan hasilnya. Nabb mungkin akan membuat sesuatu yang setara dalam sekitar 3½ karakter.
5: Sekarang hasilnya ada di sana, di dalam array yang ada, sepotong kode konyol ini hanya ada untuk mengeluarkannya (dan membuang sepotong sisa makanan (dan alihkan hasilnya ke tempatnya)).
6: Ini adalah perintah yang sangat sederhana sehingga jumlah karakternya mungkin negatif dalam solusi optimal. 7: Pada titik ini program ini benar-benar selesai, tetapi karena kecerobohan dalam kode sebelumnya outputnya dalam urutan yang salah dan tidak memiliki ruang, jadi begini beberapa bit lagi sia-sia.

aaaaaaaaaaaa
sumber
Ahh, saya hanya secara tidak sengaja mengasumsikan input tidak berakhir dengan baris baru. Saya terkejut bahwa itu benar-benar berfungsi sebagian, hal-hal semacam itu biasanya mengacaukan program GolfScript sepenuhnya.
aaaaaaaaaaaa
1
Terlihat baik, meskipun Anda harus menggunakan {}*bukan (\{}%.
Nabb
Ya itu masuk akal, terima kasih.
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)

Saya menolak untuk melakukan IO, menurunkan skor saya secara dramatis. Lewati semua tes dalam harness uji (meskipun hanya bekerja jika input berakhir dengan garis yang berakhir, seperti pada harness uji).

Saya menghapus penanganan untuk ujung jalur Windows, karena Chris menyarankan bahwa itu tidak perlu. Versi multi-platform akan a=:".;._2 toJ(1!:1)3menjadi baris pertama.

Penjelasan:

  • fmemberikan pasangan solusi dengan memanggil p secara normal dan dengan input dialihkan ( |:).
  • pmengambil maksimum ( >./) total baris dari penerapan cantara setiap baris ( c/)
  • cmembutuhkan dua baris (x dan y). Ini menambahkan x ke masing-masing y, y bergeser ke atas 1 sel ( 1|.!.0 y), dan y bergeser ke bawah 1 sel ( _1|.!.0 y). Kemudian dibutuhkan maksimum tiga alternatif untuk setiap baris. ( >./). Sisanya adalah peringkat [sic] - Saya tidak yakin apakah saya melakukannya dengan benar.
Jesse Millikan
sumber
4
Tepat, menurunkan skor Anda. -1
aaaaaaaaaaaa
@eBusiness: Apakah Anda yakin downvoting adalah respons yang tepat untuk solusi yang tidak lengkap?
Jesse Millikan
1
@ Joey: Tidak upvoting adalah pilihan lain. Saya terlalu lelah untuk melakukan IO pada saat itu, tetapi solusi saya sangat berbeda dari solusi J lainnya sehingga saya benar-benar ingin mempostingnya. Jika ada cara eksplisit untuk menandai jawaban sebagai "tidak berpartisipasi", atau sesuatu seperti itu, saya akan melakukannya.
Jesse Millikan
@ Joey: Alasan lain adalah down-vote tidak mungkin dibatalkan bahkan jika solusinya diperbaiki; pengguna asli harus kembali dan mengubah suara mereka. (Dihapus, menyadari bahwa hubung pendek diskusi, dan dihapus. Saya kira saya akan menembak untuk lencana "Disiplin" sebagai gantinya.)
Jesse Millikan
@Jesse Millikan: Kami melakukan itu. Tidak ada jaminan, tetapi jika Anda memperbaiki masalah dalam waktu yang wajar sebagian besar downvoters harus mencabut suara mereka.
aaaaaaaaaaaa
3

Haskell: 314 karakter yang diperlukan

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

Catatan: ini membutuhkan modul Data.Vector . Saya tidak yakin apakah itu termasuk dalam platform Haskell atau tidak.

Versi tidak disatukan:

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

Solusi ini menggunakan kemalasan, bersama dengan Data.Vector , untuk memoisasi. Untuk setiap titik, solusi untuk jalur maksimum dari itu sampai akhir dihitung, kemudian disimpan dalam sel Vector mdan digunakan kembali ketika dibutuhkan.

Joey Adams
sumber
Saya kira Anda dapat menghapus kurung kurawal setelah pernyataan where Anda, jika Anda menciutkan semua definisi menjadi satu baris.
FUZxxl
2

Ruby 1.9, 155 karakter

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

Solusi langsung yang melewati semua testcases.

Ventero
sumber
2

Haskell, 154 karakter

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

  • Sunting: (155 -> 154) sebaris fungsi dilipat
MtnViewMark
sumber
Apakah menggunakan zipWith3memperpendek kode?
haskeller bangga
Saya pikir Anda bisa mengganti dengan maksimum foldl1 max, yang menambahkan karakter tetapi memungkinkan Anda untuk faktor foldl1 dan maks, yang seharusnya menghemat karakter.
haskeller bangga
maximum.foldl1, max, Dan max--vs-- f=foldl1;m=max;, f m.f, m, dan m. - atau 20 lawan 22. Jadi, tidak, itu tidak menghemat.
MtnViewMark
Baik. Dan saya baru ingat pembatasan monomorfisme akan berhenti menulis m=max. Bagaimana dengan zipWith3?
haskeller bangga
1

J, 109 + 10 = 119 karakter

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

Jalankan dengan tr:

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

Seperti biasa dalam J, sebagian besar kode adalah untuk input / output. Kode "aktual" adalah 65 karakter:

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

Lewati semua kasus uji

Eelvex
sumber
Jadi kita perlu JB lagi dengan solusi yang mengurangi parsing menjadi 10 karakter? ;-)
Joey
@ Joey saya sedang berlibur, saya hampir tidak memiliki akses internet; tidak banyak waktu untuk bermain golf ;-)
JB
Bisakah Anda memberi tahu saya bagaimana Anda menjalankan maxpath.ijs secara langsung?
Jesse Millikan
@ Jesse: Di * nix letakkan beberapa #!/usr/bin/env jconsoledi atas file dan atur flag yang dapat dieksekusi.
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)

Jika saya hanya menghitung jalur terpendek vertikal atau horizontal,
itu bisa dilakukan di tempat, menghemat sekitar sepertiga dari byte.

hallvabo
sumber
1

Python, 204 karakter

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
sumber