Xây dựng đường ray xe lửa và lừa dối chính phủ


30

Bạn là một doanh nhân đường sắt ở Hoa Kỳ thế kỷ 19 khi tàu hỏa trở nên phổ biến vì chúng là phương tiện hiệu quả nhất để vận chuyển khối lượng lớn vật liệu bằng đường bộ. Có một nhu cầu quốc gia cho các tuyến đường sắt từ bờ biển phía đông thông qua một số vùng đất gần đây thuộc địa ở phía tây.

Để đáp ứng nhu cầu này, chính phủ Hoa Kỳ sẽ đánh thuế để trợ cấp cho đường sắt. Họ đã hứa trả tiền cho công ty đường sắt của bạn cho mỗi dặm đường được đặt. Vì đặt đường ray ở vùng đồi núi và đắt hơn so với đường ray trên vùng đất bằng phẳng, họ điều chỉnh số tiền họ đưa ra cho phù hợp. Đó là, chính phủ sẽ trả

  • $ 5.000 mỗi dặm đường được đặt trong vùng đất bằng phẳng
  • $ 12.500 mỗi dặm đường được đặt trên vùng đất đồi
  • $ 20.000 mỗi dặm theo dõi đặt trên núi.

Tất nhiên, kế hoạch này không phản ánh chính xác chi phí thực sự của việc theo dõi.

Bạn đã thuê một số người vẽ bản đồ để vẽ bản đồ cứu trợ của các khu vực nơi bạn sẽ theo dõi để phân tích độ cao. Đây là một bản đồ như vậy:

S12321
121234
348E96

Mỗi chữ số đại diện cho một dặm vuông đất. Slà điểm bắt đầu, Elà điểm kết thúc. Mỗi số đại diện cho cường độ thay đổi độ cao trong khu vực đó.

  • Đất được đánh số 1-3 tạo thành đất bằng phẳng.
  • Đất được đánh số từ 4 - 6 tạo thành đất đồi.
  • Vùng đất được đánh số 7-9 tạo thành một dãy núi.

Bạn có, qua nhiều năm kinh nghiệm xây dựng đường ray xe lửa, đã đánh giá rằng chi phí xây dựng đường ray (bằng đô la) đáp ứng công thức này:

Cost_Per_Mile = 5000 + (1500 * (Elevation_Rating - 1))

Điều đó có nghĩa là xây dựng trên độ dốc nhất định sẽ khiến bạn tốn nhiều tiền hơn so với chính phủ đưa ra, đôi khi nó sẽ mang lại lợi nhuận và đôi khi bạn sẽ chỉ hòa vốn.

Ví dụ: một dặm đường trên độ cao 3 độ tốn 8.000 đô la để xây dựng, nhưng bạn chỉ được trả 5.000 đô la cho nó, vì vậy bạn mất 3000 đô la. Ngược lại, xây dựng một dặm đường trên độ cao 7 có giá 14.000 đô la, nhưng bạn được trả 20.000 đô la cho nó: lợi nhuận 6.000 đô la!

Dưới đây là một bản đồ ví dụ, cũng như hai đường dẫn khác nhau có thể.

S29    S#9    S##
134    1#4    1##
28E    2#E    2#E

Ca khúc đầu tiên tốn 30.000 đô la để xây dựng, nhưng chính phủ trả cho bạn 30.000 đô la cho nó. Bạn không kiếm được lợi nhuận từ bài hát này.

Mặt khác, thứ hai tốn 56.500 đô la để xây dựng, nhưng bạn được trả 62.500 đô la cho nó. Bạn kiếm được 6.000 đô la từ ca khúc này.

Mục tiêu của bạn: đưa ra một bản đồ cứu trợ, tìm ra con đường có lợi nhất (hoặc có lẽ chỉ là ít tốn kém nhất) từ đầu đến cuối. Nếu nhiều đường dẫn ràng buộc, bất kỳ một trong số chúng là một giải pháp chấp nhận được.

Chi tiết chương trình

Bạn được cung cấp đầu vào văn bản được phân tách bằng bản đồ số hình chữ nhật và một điểm bắt đầu và điểm kết thúc. Mỗi số sẽ là một số nguyên nằm trong khoảng từ 1 đến 9. Ngoài ra, đầu vào có thể được cung cấp theo cách bạn muốn, theo lý do.

Đầu ra phải có cùng định dạng với đầu vào, với các số mà bản nhạc đã được xây dựng thay thế bằng hàm băm ( #). Do các quy định tùy tiện được áp đặt bởi một số chính trị gia thất thường, các bản nhạc chỉ có thể đi theo đường ngang hoặc dọc. Nói cách khác, bạn không thể quay lại hoặc đi theo đường chéo.

Chương trình sẽ có thể giải quyết trong một khoảng thời gian hợp lý (tức là <10 phút) cho bản đồ tối đa 6 hàng và 6 cột.

Đây là một mã golf thử thách , vì vậy chương trình ngắn nhất sẽ thắng.

Tôi có một ví dụ (không chơi gôn) .

Mẫu I / O

S12321
121234
348E96

S12321
######
3##E##



S73891
121234
348453
231654
97856E

S#3###
1###3#
3#####
######
#####E

Là gì, nếu đầu ra là mơ hồ?
FUZxxl

2
Đầu ra có thể mơ hồ, nhưng mơ hồ theo cách mà lợi nhuận là như nhau bất kể bạn theo dõi nó như thế nào.
Peter Olson

Tôi nghĩ có một lỗi nhỏ. Nên 4134trong bản đồ ví dụ được 6?
JiminP

@JiminP Vâng, đó là một sai lầm từ việc thay đổi số ở một nơi nhưng không phải là một nơi khác. Nó nên được chữa ngay bây giờ.
Peter Olson

3
Ba năm sau, chính phủ nhìn xung quanh và bắt đầu tự hỏi tại sao tất cả * những ngọn đồi và ngọn núi được bao phủ trong đường ray xe lửa. Nhưng này, người dùng quá cảnh địa phương đã có một chuyến tàu lượn / tour du lịch tuyệt vời --- miễn phí --- được tài trợ bởi chính phủ, làm cho mọi người hạnh phúc hơn, vậy tại sao phải quan tâm? (* ngoại trừ một số đồi cấp 6)
John Dvorak

Câu trả lời:


5

Python, 307 ký tự

import os
I=os.read(0,99)
n=I.find('\n')+1
I='\0'*n+I+'\0'*n
def P(p):
 S=[]
 for d in(-n,-1,1,n):
  y=p[-1]+d
  if'E'==I[y]:S+=[(sum((int(I[v])-1)/3*75-15*int(I[v])+15for v in p[1:]),p)]
  if'0'<I[y]<':'and y not in p:S+=P(p+[y])
 return S
for i in max(P([I.find('S')]))[1][1:]:I=I[:i]+'#'+I[i+1:]
print I,

Pcó một đường dẫn một phần pvà trả về tất cả các cách mở rộng nó để đạt tới E. Mỗi đường dẫn được trả lại được ghép với điểm của nó để maxcó thể tìm ra đường tốt nhất.

Mất khoảng 80 giây trên bản đồ 6x6.


1
Bạn có thể thay thế cấp độ thụt lề thứ hai bằng các tab để lưu 3 ký tự
gnibbler

4

Python: 529 482 460 byte

Giải pháp của tôi sẽ không giành được bất kỳ giải thưởng. Tuy nhiên, vì chỉ có hai giải pháp được đăng và tôi thấy vấn đề này rất thú vị, tôi quyết định đăng câu trả lời của mình bằng mọi cách.

Chỉnh sửa: Cảm ơn Howard cho các khuyến nghị của mình. Tôi đã quản lý để cạo rất nhiều điểm số của tôi!

import sys
N=len
def S(m,c,p=0):
 if m[c]=='E':return m,p
 if m[c]<'S':
    b=list(m);b[c]='#';m=''.join(b)
 b=[],-float('inf')
 for z in(1,-1,w,-w):
    n=c+z
    if 0<=n<N(m)and m[n]not in('S','#')and(-2<z<2)^(n/w!=c/w):
     r=S(m,n,p+(0if m[n]=='E'else(int(m[n])-1)/3*5-int(m[n])+1))
     if b[1]<r[1]:b=r
 return b
m=''
while 1:
 l=sys.stdin.readline().strip()
 if l=='':break
 w=N(l);m+=l
b,_=S(m,m.index('S'))
for i in range(0,N(b),w):print b[i:i+w]

Đó là cách nó bắt đầu. :)
Jonathan Van Matre 17/03/2016

1
Một số cải tiến nhỏ: PMchỉ được sử dụng một lần mỗi lần vì vậy đó là một ý tưởng tốt để nội tuyến sau đó (đối với một lệnh gọi duy nhất, nó hoạt động trong hầu hết các trường hợp cho hai lần). m[c]!='S'có thể được rút ngắn xuống còn m[c]<'S', cũng abs(z)==1đến abs(z)<2hoặc thậm chí -2<z<2.
Howard

"Những cải tiến nhỏ" của bạn giúp tôi tiết kiệm được 47 byte. Tôi đang chỉnh sửa câu trả lời của mình.
sadakatsu

3

Ruby, 233 ký tự

R=->s{o=s=~/S/m
s=~/E/m?(q=[-1,1,-N,N].map{|t|s[f=o+t]>'0'?(n=s*1
n[o]='#'
n[f]='S'
a=R[n]
a&&[a[0]-(e=s[f].to_i-1)/3*5+e,a[1]]):nil}-[nil]
q.sort!&&q[0]):[0,(n=s*1;n[o]='E'
n[$_=~/S/m]='S'
n)]}
N=1+(gets(nil)=~/$/)
$><<R[$_+$/*N][1]

Một cách tiếp cận vũ phu của Ruby chạy tốt trong giới hạn thời gian trên bảng 6x6. Đầu vào phải được đưa ra trên STDIN.

Ví dụ:

S12321
121234
348E96

S#2321
1#####
3##E##    
--    
S73891
121234
348453
231654
97856E

S#####
1212##
#####3
#3####
#####E

@PeterOlson Tôi đã cố gắng dành ít nhất một chút chú ý đến thử thách của bạn ;-)
Howard
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.