Побудувати залізничні колії та обдурити уряд


30

Ви підприємець із залізниць у Сполучених Штатах 19 століття, коли потяги стають популярними, оскільки вони є найефективнішим засобом перевезення великих обсягів матеріалів по суші. Існує національна потреба у залізничних коліях від східного узбережжя через деякі недавно колонізовані землі на заході.

Для задоволення цієї потреби уряд США збирається стягувати податок на субсидування залізниць. Вони пообіцяли заплатити гроші вашій залізничній компанії за кожну милю прокладеної колії. Оскільки прокладення доріжок у горбистих та гірських районах дорожче, ніж прокладка доріжок у рівнинній землі, вони відповідно коригують суму, яку вони дають. Тобто уряд заплатить

  • 5000 доларів за милю траси, прокладеної на рівнині
  • $ 12 500 за милю траси, прокладеної в горбистій землі
  • $ 20 000 за милю траси, прокладеної в горах.

Звичайно, цей план не відображає точно, скільки насправді коштує прокладати доріжки.

Ви найняли деяких картографів, щоб вони склали рельєфні карти регіонів, де ви будете прокладати доріжки для аналізу висоти. Ось одна така карта:

S12321
121234
348E96

Кожна цифра представляє одну квадратну милю землі. Sє початковою точкою, Eє кінцевою точкою. Кожне число відображає інтенсивність змін висоти в цьому регіоні.

  • Земля під номером 1-3 становить рівнину.
  • Земля з номером 4-6 становить горбисту землю.
  • Земля з номером 7-9 становить гірський хребет.

За багаторічний досвід будівництва залізничних колій ви оцінили, що вартість будівництва колій (у доларах) відповідає цій формулі:

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

Це означає, що побудова на певних градієнтах висоти буде коштувати вам більше грошей, ніж дає уряд, іноді це буде вигідно, а іноді ви просто зламаєте.

Наприклад, миля траси на градієнті висоти 3 коштує 8000 доларів, а ви лише платите 5000 доларів, тому ви втрачаєте 3000 доларів. Навпаки, будівництво милі траси на градієнті висоти 7 коштує 14 000 доларів, але за це вам платять 20 000 доларів: прибуток 6 000 доларів!

Ось прикладна карта, а також два різні можливі шляхи.

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

Перший трек коштує 30 000 доларів на його побудову, але уряд платить вам за це 30 000 доларів. Ви не отримуєте прибутку від цієї доріжки.

З іншого боку, на будівництво другий коштує 56 500 доларів, але за це вам платять 62 500 доларів. Ви заробляєте 6000 доларів від цього треку.

Ваша мета: надавши карту рельєфу, знайдіть найвигідніший (чи, можливо, найменш дорогий) шлях від початку до кінця. Якщо кілька шляхів пов'язані, будь-який з них є прийнятним рішенням.

Деталі програми

Вам надається введення тексту, розділене прямокутною картою чисел та однією початковою та кінцевою точкою. Кожне число буде цілим числом, включно між 1 і 9. Крім цього, вхід може бути наданий у межах причини.

Вихід повинен бути у тому ж форматі, що і вхідний, при цьому цифри, де побудована доріжка, замінені хеш ( #). Через довільні норми, накладені деякими примхливими політиками, сліди можуть йти лише горизонтальними або вертикальними стежками. Іншими словами, ви не можете відхилитись або пройти по діагоналі.

Програма повинна мати можливість вирішувати за розумну кількість часу (тобто <10 хвилин) для карт до 6 рядків і 6 стовпців.

Це виклик для гольфу з кодом , тому виграє найкоротша програма.

У мене є приклад реалізації (без гольфу) .

Зразок вводу / виводу

S12321
121234
348E96

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



S73891
121234
348453
231654
97856E

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

Що таке, якщо вихід неоднозначний?
FUZxxl

2
Вихід може бути неоднозначним, але неоднозначним таким чином, коли прибуток однаковий, незалежно від того, як ви його відстежуєте.
Пітер Олсон

Я думаю, що є невелика помилка. Чи має 4у 134прикладі карта бути 6?
JiminP

@JiminP Так, це помилка при зміні номерів в одному місці, але не в іншому. Це слід виправити зараз.
Пітер Олсон

3
Через три роки уряд оглядається і починає цікавитись, чому всі * пагорби та гори вкриті залізничними коліями. Але ей, місцеві користувачі транзиту отримали приємне катання на гірських дорогах / екскурсії --- безкоштовно --- фінансувались урядом, роблячи людей щасливішими, так чому ж дбати? (* крім деяких пагорбів класу 6)
Джон Дворак

Відповіді:


5

Пітон, 307 символів

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,

Pпроходить частковий шлях pі повертає всі шляхи його розширення для досягнення E. Кожен повернутий шлях поєднується з його оцінкою, тому maxможна знайти найкращий.

Займає приблизно 80 секунд на карті 6x6.


1
Ви можете замінити відступи другого рівня на вкладки, щоб зберегти 3 символи
gnibbler

4

Пітон: 529 482 460 байт

Моє рішення не виграє жодних призів. Однак, оскільки розміщено лише два рішення, і я вважав проблему цікавою, я все-таки вирішив опублікувати свою відповідь.

Редагувати: Дякую Говарду за його рекомендації. Мені вдалося поголити багато своєї оцінки!

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]

Ось так і починається. :)
Джонатан Ван Матре

1
Деякі поліпшення незначні: Pі Mвикористовуються тільки один раз , так що це ідея хороша вбудовувати потім (для одного виклику він працює практично у всіх випадках для двох іноді). m[c]!='S'може бути скорочено до m[c]<'S', навіть abs(z)==1до abs(z)<2або навіть -2<z<2.
Говард

Ваші "незначні поліпшення" заощаджують мені 47 байт. Я редагую свою відповідь.
садакацу

3

Рубі, 233 символи

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]

Підхід Ruby з грубою силою, який добре працює у часові обмеження на дошці 6x6. Вхід повинен бути вказаний на STDIN.

Приклади:

S12321
121234
348E96

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

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

@PeterOlson Я намагався принаймні трохи приділити увагу твоєму виклику ;-)
Говард
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.