ค้นหาเส้นทางสูงสุด


12

เมื่อกำหนดจำนวนสี่เหลี่ยมบวกจำนวนที่เป็นธรรมชาติเขียนโปรแกรมหาเส้นทางแนวนอนและแนวตั้งที่มีผลรวมของตัวเลขตามพวกเขาเป็นสูงสุด แนวเส้นทางไปจากคอลัมน์แรกที่ผ่านมาและมีการเพิ่มตำแหน่งของคอลัมน์โดยหนึ่งในแต่ละขั้นตอน แนวเส้นทางไปจากแถวแรกที่ผ่านมาและมีการเพิ่มตำแหน่งของแถวโดยหนึ่งในแต่ละขั้นตอน นอกจากนี้ตำแหน่งแถวในเส้นทางแนวนอนอาจยังคงเหมือนเดิมหรือเปลี่ยนแปลงทีละตำแหน่งในทิศทางใดทิศทางหนึ่งเช่นเดียวกันกับเส้นทางแนวตั้ง

เพื่อแสดงให้เห็นต่อไปนี้อาจเป็นเส้นทางที่ถูกต้อง:

ภาพประกอบของเส้นทางที่ถูกต้อง

เส้นทางต่อไปนี้จะไม่ถูกต้องเนื่องจากเป็นขั้นตอนย้อนหลัง (และยังคงอยู่ในแถวเดียวกันในบางแห่ง):

ภาพประกอบของเส้นทางที่ไม่ถูกต้อง

เส้นทางต่อไปนี้จะไม่ถูกต้องเท่ากันเนื่องจากจะเปลี่ยนตำแหน่งแถวมากกว่าหนึ่งในขั้นตอนเดียว:

ภาพประกอบอื่นของเส้นทางที่ไม่ถูกต้อง

หมายเหตุ: การแก้ปัญหาควรทำงานในระยะเวลาที่ยอมรับได้

อินพุต

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

+10 สำหรับbashสคริปต์ทดสอบ! ฉันหวังว่าทุกรหัสกอล์ฟมาพร้อมกับดังกล่าว
MtnViewMark

@MtnViewMark: เราพยายาม :-) โดยส่วนตัวแล้วฉันเกลียดงานที่ต้องการคำอธิบายที่มากเกินไปหลังจากโพสต์และฉันมักจะเขียนสคริปต์ทดสอบของตัวเองอยู่แล้วตั้งแต่ฉันต้องรู้เมื่อความพยายามในการเล่นกอล์ฟแนะนำการถดถอยเพิ่มเติม นอกจากนี้ฉันได้สังเกตเห็นว่าบางคนมักโพสต์คำตอบที่ผิดอย่างชัดเจน กรณีทดสอบช่วยให้ทุกคนอยู่ในบรรทัดเดียวกัน การมีสิ่งอำนวยความสะดวกที่ใช้งานได้กับทุกงานแทนที่จะเป็นแฮ็คแฮ็กเพียงครั้งเดียวสำหรับแต่ละงานจะดีกว่าอย่างชัดเจน แต่เรายังไม่ค่อยมี ;-)
Joey

คำตอบ:


6

GolfScript - 49 อักขระที่เพิ่มขึ้นของ Nabb

51 ตัวอักษร
50 ตัวอักขระที่จำเป็นอย่างเคร่งครัดและอย่างเต็มที่ + 3 slackers ที่ทำงานของ 1
56 อักขระส่วนใหญ่ซ้ำซ้อนเท่านั้น

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_

วิธีการทำงานในสองบรรทัดในแต่ละครั้งหนึ่งที่มีผลรวมสูงสุดถึงแต่ละจุดและหนึ่งที่มีบรรทัดถัดไป

a / 14: ทำซ้ำสองครั้งหนึ่งครั้งสำหรับแต่ละผลลัพธ์
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 ตัวอักษรเพียงเพื่อทำสำเนา transposed
3: อาเรย์ของ 99 0s ใน 5 ตัวละครมันอาจจะทำได้ในแบบที่ชาญฉลาด แต่ฉันสูบวัชพืชมากเกินไปที่จะคิดว่า
4: วงคู่ที่ซับซ้อนมากเกินไปที่วนซ้ำทุกองค์ประกอบของอินพุตและทำตรรกะคลุมเครือหรืออะไรทำนองนั้นเพื่อให้ได้ผลลัพธ์ Nabb อาจสร้างบางสิ่งที่เทียบเท่ากับตัวอักษรประมาณ3½ตัว
5: ถึงตอนนี้ผลลัพธ์อยู่ที่นั่นภายในอาเรย์นั่นคือโค้ดชิ้นนี้ที่โง่เง่าที่จะเอามันออกมา (และทิ้งเศษชิ้นส่วนที่เหลือทิ้งไว้
6: นี่เป็นคำสั่งง่าย ๆ ที่การนับจำนวนตัวอักษรอาจจะเป็นลบในทางออกที่ดี 7: ณ จุดนี้โปรแกรมทำจริงๆ แต่เนื่องจากความสะเพร่าในรหัสก่อนหน้าเอาต์พุตอยู่ในลำดับที่ไม่ถูกต้องและไม่มีช่องว่างดังนั้นที่นี่จะมีบิตเหลือน้อยลง


อ๊ะฉันเพิ่งบังเอิญสันนิษฐานว่าอินพุตจะไม่ขึ้นบรรทัดใหม่ ฉันแปลกใจที่มันใช้งานได้จริงบางส่วนสิ่งนั้นมักจะทำให้โปรแกรม GolfScript ยุ่งเหยิงไปหมด
aaaaaaaaaaaa

1
ดูดี แต่คุณควรจะใช้แทน{}* (\{}%
Nabb

ใช่ว่าเหมาะสมแล้วขอบคุณ
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 เนื่องจาก Chris แนะนำว่าไม่จำเป็น เวอร์ชั่นหลายแพลตฟอร์มน่าจะa=:".;._2 toJ(1!:1)3เป็นบรรทัดแรก

คำอธิบาย:

  • fให้คู่ของการแก้ปัญหาโดยการเรียก p ตามปกติและด้วย transposed อินพุต ( |:)
  • pใช้เวลาสูงสุด ( >./) ของผลรวมแถวจากการใช้cระหว่างแต่ละแถว ( c/)
  • cใช้สองแถว (x และ y) มันเพิ่ม x ในแต่ละ y, y เลื่อนขึ้น 1 เซลล์ ( 1|.!.0 y) และ y เลื่อนลง 1 เซลล์ ( _1|.!.0 y) จากนั้นจะใช้เวลาสูงสุดในสามตัวเลือกสำหรับแต่ละแถว ( >./) ส่วนที่เหลือเป็นอันดับ [sic] - ฉันไม่แน่ใจว่าฉันทำถูกหรือไม่

4
ตรงลดคะแนนของคุณ -1
aaaaaaaaaaaa

@eBusiness: คุณแน่ใจหรือไม่ว่าการ downvoting เป็นการตอบสนองที่ถูกต้องต่อโซลูชันที่ไม่สมบูรณ์
Jesse Millikan

1
@ โจอี้: การไม่ขึ้นทะเบียนเป็นตัวเลือกอื่น ฉันเหนื่อยเกินกว่าจะทำ IO ในเวลานั้น แต่โซลูชันของฉันแตกต่างจากโซลูชัน J อื่น ๆ ที่ฉันต้องการโพสต์ไว้จริงๆ หากมีวิธีชัดเจนในการทำเครื่องหมายคำตอบว่า "ไม่เข้าร่วม" หรืออะไรทำนองนั้นฉันก็จะมี
Jesse Millikan

@ โจอี้: อีกเหตุผลหนึ่งคือการลงคะแนนเสียงไม่น่าจะกลับรายการแม้ว่าการแก้ปัญหาจะได้รับการแก้ไข; ผู้ใช้เดิมจะต้องกลับมาและเปลี่ยนการลงคะแนน (ถูกลบแล้วตระหนักว่าการสนทนาสั้นและไม่ถูกลบฉันเดาว่าฉันจะถ่ายทำตรา "วินัย" แทน)
Jesse Millikan

@Jesse Millikan: เราทำอย่างนั้น ไม่มีการรับประกัน แต่ถ้าคุณแก้ไขปัญหาภายในเวลาอันสมควรผู้ลงคะแนนส่วนใหญ่ควรเพิกถอนการลงคะแนนของพวกเขา
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และนำกลับมาใช้ใหม่เมื่อจำเป็น


ฉันเดาว่าคุณสามารถถอดวงเล็บปีกกาหลังคำสั่ง 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

ฉันคิดว่าคุณสามารถแทนที่ค่าสูงสุดด้วยfoldl1 maxซึ่งเพิ่มอักขระ แต่อนุญาตให้คุณแยกส่วน foldl1 และสูงสุดซึ่งควรบันทึกอักขระ
ภูมิใจ haskeller

maximum.foldl1, maxและmax--vs-- f=foldl1;m=max;, f m.f, และm m- หรือ 20 กับ 22 ดังนั้นไม่มันไม่ได้บันทึก
MtnViewMark

ขวา. และฉันก็จำได้ว่าข้อ จำกัด monomorphism m=maxจะหยุดเขียน แล้ว zipWith3 เกี่ยวกับอะไร?
ภูมิใจ haskeller

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

ผ่านทุกกรณีทดสอบ


ดังนั้นเราต้องการ JB อีกครั้งด้วยวิธีแก้ปัญหาที่ลดการแจงเป็น 10 ตัวอักษร? ;-)
Joey

@ โจฉันอยู่ในช่วงวันหยุดฉันแทบจะไม่สามารถเข้าถึงอินเทอร์เน็ตได้ เวลาไม่มากสำหรับการเล่นกอล์ฟ ;-)
JB

คุณช่วยบอกเบาะแสเกี่ยวกับวิธีการเรียกใช้ maxpath.ijs โดยตรงได้หรือไม่
Jesse Millikan

@Jesse: ใน * ระวังวางไว้#!/usr/bin/env jconsoleด้านบนของไฟล์และตั้งค่าการปฏิบัติธง
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)

หากฉันต้องคำนวณเส้นทางที่สั้นที่สุดในแนวตั้งหรือแนวนอน
ก็สามารถทำได้ในสถานที่แทนการบันทึกประมาณหนึ่งในสามของไบต์


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.