Maksimum yolları bulma


12

Pozitif doğal karelerden oluşan bir kare göz önüne alındığında, bir programın yatay ve dikey bir yol bulmasıyla birlikte sayıların toplamı maksimum olur. Bir yatay yolu son ilk kolondan geçer ve her adımda bir kişi tarafından da sütun konumunu artırmak için vardır. Bir dikey yolu son ilk satırdan gider ve her aşamada bir kişi tarafından kendi satır konumu artırmak için vardır. Ayrıca, yatay bir yoldaki sıra konumu da aynı şekilde kalabilir veya her iki yönde de aynı şekilde, dikey yollar için değişebilir.

Açıklamak gerekirse, aşağıdakiler geçerli bir yol olabilir:

Geçerli bir yolun gösterimi

Aşağıdaki yol geçersiz olacaktır, çünkü geriye doğru adım atar (ve bazı yerlerde aynı satırda kalır):

Geçersiz bir yolun resmi

Aşağıdaki yol, satır konumunu tek bir adımda birden fazla değiştirdiğinden eşit derecede geçersiz olacaktır:

Geçersiz bir yolun başka bir resmi

Not: Çözüm kabul edilebilir bir süre içinde çalışmalıdır.

Giriş

N ile giriş hatları N boşlukla ayrılmış ve pozitif bir tamsayı, her standart giriş verilmiştir. 2 ≤ n ≤ 40. Her satır bir satır sonu ile sonlandırılır. Sayılar, maksimum toplamın 32 bit işaretli tam sayıya sığacağı kadar küçük.

Çıktı

Tek bir boşlukla ayrılmış yatay ve dikey yolların (bu sırayla) maksimum toplamları.

Örnek giriş 1

1 2
1 2

Örnek çıktı 1

3 4

Örnek giriş 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

Örnek çıktı 2

37 35

Örnek giriş 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

Örnek çıktı 3

4650 4799

Size kolaylık sağlamak için bash ( Ventero sayesinde ) ve PowerShell'de programınızı çalıştırabileceğiniz birkaç test vakası hazırladık . Çağırma: <test> <command line>yani ./test python paths.pyveya gibi bir şey ./test.ps1 paths.exe. İyi eğlenceler :-)


@Joey: Geçen yıl yarışmamızda kullandığımız görevden biraz değiştirilmiş :)
Joey

bashTest betiği için +10 ! Keşke tüm kod golf böyle geldi.
MtnViewMark

@MtnViewMark: Deniyoruz :-) Şahsen ben gönderildikten sonra çok fazla açıklama gerektiren görevlerden nefret ediyorum ve genellikle golf denemek ne zaman bir regresyon tanıtmak bilmek gerekir çünkü zaten kendi test komut dosyaları yazmak. Ayrıca bazı insanların açıkça yanlış cevaplar verme eğiliminde olduklarını gözlemledim. Test senaryoları herkesin aynı hatta girmesine yardımcı olur. Her görev için sadece bir kerelik hackjobs yerine her görev için çalışan bir tesise sahip olmak açıkça daha iyi olurdu, ama henüz tam olarak orada değiliz ;-)
Joey

Yanıtlar:


6

GolfScript - 49 Nabb gelişmiş karakteri

51 karakter
50 kesinlikle ve tamamen gerekli karakter + sadece 1 56 işini yapan
gereksiz haller

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

51 çözüm:

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

53 çözümü:

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

Yöntem bir seferde iki satır üzerinde çalışır, biri her noktada ulaşılan maksimum toplamları içerir ve diğeri sonraki satırı içerir.

a / 14: Her sonuç için iki kez tekrarlayın.
8: Girişten ilk satırı alın ve giriş dizisinin arkasına geçin, bu şimdi ilk maksimum toplam kümesidir.
b / 13: Dizide kalan her satır için yineleme.
9: Maksimum toplamların başına 0 koyun.
c / 12: Çizginin her bir elemanı üzerinde yineleme yapın.
10: İlk öğe kaldırılmış olarak maksimum toplamların bir kopyasını oluşturun.
11: Maksimum toplamların ilk 3 öğesini alın, sıralayın ve en büyüğünü satırın geçerli öğesine ekleyin.

56 çözüm:

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

1: Girişten 9 karakterde diziler dizisine, aslında sadece 1 ile yapılabilirdi, ama bu anahtarı kırdım, bu yüzden bunu yapmak zorunda kalacak.
2: 4 karakter sadece transpoze edilmiş bir kopya yapmak için.
3: 5 karakterde 99 0'lık bir dizi, muhtemelen daha akıllı bir şekilde yapılabilir, ama nasıl olduğunu anlamaya çok fazla ot içiyorum.
4: Girişin her bir elemanı üzerinde yinelenen ve sonucu üretmek için bazı bulanık mantık veya benzeri bir şey yapan aşırı karmaşık çift döngü. Nabb muhtemelen yaklaşık 3½ karakterde eşdeğer bir şey yapacak.
5: Şimdiye kadar sonuç, bir dizi içinde, bu aptal kod parçası onu çıkarmak için sadece orada (ve bir parça artıkları attı (ve sonucu yerine koy)).
6: Bu o kadar basit bir komut ki, karakter sayısı muhtemelen en uygun çözümde negatif olacaktır. 7: Bu noktada program gerçekten yapılır, ancak önceki koddaki eğim nedeniyle çıkış yanlış sıradadır ve bir boşluk yoktur, bu yüzden burada birkaç bit daha gider.


Ahh, girdinin bir satırsonu ile bitmeyeceğini sanmıştım. Aslında kısmen çalıştığına şaşırdım, bu tür şeyler genellikle bir GolfScript programını tamamen bozuyor.
aaaaaaaaaaaa

1
{}*Bunun yerine kullanmanız gerekir, ancak iyi görünüyor (\{}%.
Nabb

Evet bu mantıklı, teşekkürler.
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 yapmayı reddediyorum, puanımı önemli ölçüde düşürüyorum. (O olsa test koşum tüm testlerini geçmiştir sadece bir çizgi ile giriş uçları biten eğer test koşum olduğu gibi çalışır).

Chris gerekli olmadığını önerdiğinden, Windows satır sonları için işlemeyi kaldırdım. Çok platformlu sürüm a=:".;._2 toJ(1!:1)3ilk satır olacaktır.

Açıklama:

  • fp'yi normal olarak ve transpozisyonu ( |:) çağırarak çözüm çiftini verir .
  • pher satır ( ) arasına >./uygulanacak satır toplamlarının maksimumunu ( ) alırcc/
  • ciki satır alır (x ve y). Y'nin her birine x ekler, y 1 hücreyi ( 1|.!.0 y) kaydırır ve y 1 hücreyi ( _1|.!.0 y) kaydırır . Daha sonra her bir satır için en fazla üç alternatifi alır. ( >./). Gerisi rütbe [sic] - Doğru yapıp yapmadığımdan emin değilim.

4
Kesinlikle, puanınızı düşürmek. -1
aaaaaaaaaaaa

@ eBusiness: Eksik oylamanın eksik bir çözüme doğru yanıt olduğundan emin misiniz?
Jesse Millikan

1
@Joey: Başka bir seçenek de oy değil. O zaman IO yapmak için çok yorgundum, ancak çözümüm diğer J çözümünden o kadar farklı ki, bunu gerçekten göndermek istedim. Cevabı "katılmayan" olarak işaretlemenin açık bir yolu olsaydı, ya da buna benzer bir şey olurdu.
Jesse Millikan

@Joey: Başka bir neden, çözüm sabit olsa bile aşağı oyların geri döndürülmesinin mümkün olmamasıdır; orijinal kullanıcı geri gelmeli ve oylarını değiştirmelidir. (Silindi, tartışmayı kısa devre yaptığını fark etti ve sildi. Sanırım bunun yerine "Disiplinli" rozeti için ateş edeceğim.)
Jesse Millikan

@Jesse Millikan: Biz yapıyoruz. Hiçbir garanti yok, ancak sorunu makul bir süre içinde çözerseniz, çoğu downvoter oylarını iptal etmelidir.
aaaaaaaaaaaa

3

Haskell: 314 gerekli karakter

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

Not: Bu, Data.Vector modülünü gerektirir . Haskell platformuna dahil edilip edilmediğinden emin değilim.

Ungolfed sürümü:

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

Bu çözüm, bellek için Data.Vector ile birlikte tembellik kullanır . Her nokta için, ondan sona kadar maksimum yol için çözüm hesaplanır, daha sonra Vector hücresinde saklanır mve gerektiğinde yeniden kullanılır.


Eğer tüm tanımları tek bir satıra daraltırsanız sanırım where ifadenizden sonra kıvırcık parantezleri çıkarabilirsiniz.
FUZxxl

2

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

Tüm test kılıflarından geçen basit çözüm.


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

  • Düzenleme: (155 -> 154) üzerinde katlanmış fonksiyon

Kullanmak zipWith3kodu kısaltır mı?
gururlu haskeller

Sanırım foldl1 maxkarakterleri ekleyen ancak karakterleri kaydetmesi gereken foldl1 ve max'ı dışarıda bırakmanıza izin veren maksimum ile değiştirebilirsiniz .
gururlu haskeller

maximum.foldl1, maxVe max--vs-- f=foldl1;m=max;, f m.f, m, ve m. - ya da 20'ye karşı 22. Yani, hayır, tasarruf etmiyor.
MtnViewMark

Sağ. Ve sadece monomorfizm kısıtlamasının yazmayı bırakacağını hatırladım m=max. ZipWith3 ne olacak?
gururlu haskeller

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

Şununla çalıştır tr:

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

J'de her zamanki gibi, kodun çoğu giriş / çıkış içindir. "Gerçek" kod 65 karakterdir:

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

Tüm test senaryolarını geçer


Ayrıştırma işlemini 10 karaktere indiren bir çözümle JB'ye tekrar ihtiyacımız var mı? ;-)
Joey

@Joey Tatildeyim, internet erişimim yok; golf için fazla zaman yok ;-)
JB

Doğrudan maxpath.ijs'i nasıl çalıştırdığınızı öğrenebilir misiniz?
Jesse Millikan

@Jesse: * nix'de #!/usr/bin/env jconsoledosyanın üzerine bazılarını koyun ve yürütülebilir bayrağı ayarlayın.
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)

Yalnızca dikey veya yatay en kısa yolu hesaplayacak olsaydım,
bunun yerine yerinde yapılabilir, baytların yaklaşık üçte birini kaydedebilirdi.


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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.