Tavuk yoldan nasıl geçti?


16

Cluck cluck. Kimse tavukların neden yolu geçtiğini bilmiyor, belki diğer tarafta iyi görünümlü bir horoz vardı. Ama nasıl olduğunu bulabiliriz. Soldan sağa bu (veya herhangi bir) yoldan geçen bir program yazın.

1356 | 1738
3822 | 1424
3527   3718
9809 | 5926
0261 | 1947
7188   4717
6624 | 9836
4055 | 9164
2636   4927
5926 | 1964
3144 | 8254

Programınız "geçiyor", soldan sağa hareket ediyor. İstediğiniz en soldaki sütunda herhangi bir sayı ile başlarsınız. Oradan, sağdaki herhangi bir bitişik karaktere geçebilirsiniz. Sol üst köşeden başlarsanız, 1, 3 veya 8'e gidebilirsiniz. Başlangıç ​​numarası da dahil olmak üzere, gittiğiniz her sayı bir tutara eklenir. Alanlar toplamınıza eklenmez. "|" sizi sağda bir yer yerine yukarı veya aşağı hareket etmeye zorlar. (Bu karakter üzerinde ilerleyemezsiniz) Amacınız diğer tarafa mümkün olan en küçük toplamla ulaşmaktır. Programınız toplamı en sonunda yazdırmalı ve herhangi bir yolu çözebilmelidir. Tercihen, bir yol için girdi de olabilir, ancak gerekli değildir. Programınız hem yolu hem de toplamı yazdırmalıdır. En az bayt kod kazanır.

Açıklığa kavuşturmak için, dikey bir çubukta olmadığınız sürece diyagnostik olarak hareket edebilirsiniz. Yalnızca dikey bir çubuk üzerindeyken yukarı ve aşağı hareket edebilirsiniz.

Yolların daha net bir şekilde belirtilmesi için, temelde karakterlerin kurallarını izleyen bir metin dizesidir (veya bu şekilde düşünmeyi tercih ederseniz bir dizi sütun veya satırdır) ve bu karakterlerde AMA bir şey olamaz yol. Herhangi bir sayı, boşluk, çubuk ("|") veya satırsonu olabilir. Bir yol sarhoş bir adam tarafından döşenmişse, ProgrammerDan'ın cevabında olduğu gibi, hala geçerli bir yoldur ve programınız böyle bir yolu çözebilmelidir. Diğer tarafa ulaşmak imkansızsa bir yol olarak kabul edilmez (Örneğin, düz bir çubuk çizgisinden çıkmanın yolu yoktur).

Programınızın bir yolun geçersiz olup olmadığını belirlemesi gerekmez.

Tuş:
Herhangi bir sayı - sayıyı toplamınıza ekler, ilerle.
Boşluk - İlerleyin, toplamınıza hiçbir şey eklenmez.
"|" - Yukarı veya aşağı hareket edin, toplamınıza hiçbir şey eklenmez.

EDIT: Önerildiği gibi örnek bir çözüm. Çok büyük bir tane yapamam, benim için ATM'yi çözmek için bir IDE alamıyorum.

Bu küçük yolu kullanın:

9191 | 8282
1919 | 2727
5555   5555

Çözüm, toplam 12 için 1, 1, 1, 1, boşluk, bölücü, bölücü, boşluk, boşluk, 2, 2, 2, 2 yolu olacaktır.

DÜZENLEME # 2: Geobits ve halk programları tarafından belirlenen bu sorudaki ilk yola çözüm, toplam 13 için 0,2,0,1,,, 1,4,1,4'tür.


4
Doğru çözüm içeren en az bir test durumu ekleyebilir misiniz? Ayrıca, |arka arkaya üçten fazla olabilir mi?
Martin Ender

1
@timmy, ilerledikçe çapraz olarak hareket edebilirsiniz. Birkaç çapraz hareketle dokunabilir.
CaffeineToCode

3
@ mbomb007 Üst köşeden başlıyorsanız. Sol sütundaki herhangi birinden başlayabildiğiniz için, alabilirsiniz0,2,0,1, , , ,1,4,1,4 -> 13
Geobits

1
Evet öyle. Çubuklarda yalnızca yukarı veya aşağı hareket edebilirsiniz, böylece onlardan sadece bir boşluktan çıkabilirsiniz.
CaffeineToCode

1
Çıktı için, sadece maliyet yeterlidir veya tüm yolun çıktısı alması gerekir mi?
ProgrammerDan

Yanıtlar:


3

Pyth, 168 143 141 bayt [şimdi Sarhoş Yolu uyumlu]

Test durumum işe yarıyor, ancak benim tarafımdaki bir yanlış anlama nedeniyle, ilk örnekle düzgün çalışmaz. Düzeltmeye çalışıyorum.

Şimdi orijinal örnek ve sarhoş yollar için çalışıyor

Bazı GERÇEKTEN biraz daha az çirkin kod:

=Z.dC,++\ `MUT\|++0UT=^T5Ltu+G]?&qeeG\|<heGhH+eGeHHtb,0hbKhohNum++hed@ZhhdtedC,H_y_y.b+N]YmhohNd.:++TGT3HCm.[d\ lh.MlZ.z.z*hl.z]]0j\,t.sK\ hK

Burada Test Edin

10 + 9 x 40 yol üzerinde test ettim.

6417443208|153287613
8540978161|726772300
7294922506 263609552
0341937695 498453099
9417989188 370992778
2952186385|750207767
7049868670 756968872
1961508589|379453595
0670474005 070712970
4817414691|670379248
0297779413|980515509
6637598208 090265179
6872950638 767270459
7375626432 439957105
1387683792|544956696
6974831376 545603884
0949220671|632555651
3952970630|379291361
0456363431|275612955
2973230054|830527885
5328382365|989887310
4034587060 614168216
4487052014|969272974
5015479667 744253705
5756698090|621187161
9444814561|169429694
7697999461|477558331
3822442188 206942845
2787118311|141642208
2669534759 308252645
6121516963|554616321
5509428225|681372307
6619817314|310054531
1759758306 453053985
9356970729|868811209
4208830142 806643228
0898841529|102183632
9692682718|103744380
5839709581|790845206
7264919369|982096148

Sadece bir not, sağlanan test paketini kullanarak çalıştırırken "IndexError: liste dizini aralık dışı" elde.
ProgrammerDan

@ProgrammerDan so do I.
CaffeineToCode

1
@CaffeineToCode true, ancak gönderdikten sonra "sarhoş yol" kavramı eklendi. Neyin yol oluşturduğunu bilmek faydalı olurdu. Örneklere dayanarak, bir bölme sütunu ile 2 taraf olduğunu varsaydım
Brian Tuck

1
@CaffeineToCode İyi bir soru yazmanın en iyi yollarından biri, çözüm olmadan bile daha fazla örnek yazmaktır. Değişken genişlik veya çok şeritli yollar geçerli olsaydı, bir "çılgın" örnek herhangi bir ek açıklayıcı metin olmadan onu resmederdi.
ProgrammerDan

1
@ProgrammerDan Siz istediniz. Benimki artık DR uyumlu (ve daha kısa ... sanırım yakaladım)
Brian Tuck

4

Java, 955 bayt

Açıkçası herhangi bir ödül kazanmayacak, Java ve hepsi olacak, ama bu sorunu seviyorum ve kendi girişime atmak istedim.

Özellikler ve limitler:

  • Değişken genişlikler, karmaşık çizgiler vb.Dahil olmak üzere düzensiz yolları (süper sarhoş!) Destekleyebilir.
  • Yolun yürütme sırasında parametreler olarak girilmesini bekler; ungolfed sürümü de stdin okumayı destekler, ancak giriş yöntemi belirtilmediğinden golfed sürümü en küçük bekliyor!
  • N (satırlar ve m sütunlar) O (n * m) zamanında verimli bir şekilde çözmek için kullanmadığım bazı dinamik programlama tekniğini kullanır, oh, 6 yıl kadar.
    • Almak için en iyi yönü işaretleme sola sağdan çözer, gelen bir sonraki endeksine akım indeksi.
    • "satırlar" sütunları çözülerek, daha sonra bir sonraki sütuna erişilebiliyorsa adreslenir. Nihayet ulaşılabilir hat dışı maliyetle yönü yukarı veya aşağı kaydederek çözülürler.
  • En iyi çözümün başlangıç ​​dizinini izler, ancak yazdırmaz (golf'd sürümünde) .

Tamam, yeterli jibba jabba. Golf versiyonu:

class C{public static void main(String[]a){int n=a.length,m=0,i=0,j=0,h=0,p=0,q=0,s=0,t=0,b=-1,c=2147483647,x=0,y=0;char[][]r=new char[n][];char u;for(String k:a){j=k.length();m=(j>m)?j:m;}for(String k:a)r[i++]=java.util.Arrays.copyOf(k.toCharArray(),m);int[][][]d=new int[n][m][2];for(j=m-1;j>=0;j--){for(i=0;i<n;i++){u=r[i][j];p=(u=='\0'||u==' '||u=='|'?0:u-'0');if(j==m-1)d[i][j][1]=p;else{if(u=='|')d[i][j][0]=-1;else{for(h=-1;h<2;h++){x=i+h;y=j+1;if(x>=0&&x<n){if(d[x][y][0]==-1){s=x-1;while(s>=0&&r[s][y]=='|')s--;t=x+1;while(t<n&&r[t][y]=='|')t++;if((s>=0&&t<n&&d[s][y][1]<d[t][y][1])||(s>=0&&t>=n)){t=d[s][y][1];s=4;}else{s=6;t=d[t][y][1];}d[x][y][0]=s;d[x][y][1]=t;}q=d[x][y][1]+p;if(d[i][j][0]==0||q<d[i][j][1]){d[i][j][0]=h+2;d[i][j][1]=q;}}}}}if(j==0&&(b<0||d[i][j][1]<c)){b=i;c=d[i][j][1];}}}String o="";i=b;j=0;while(j<m){u=r[i][j];if(u=='\0')j=m;else{o+=u+",";h=d[i][j][0]-2;if(h>1)i+=h-3;else{i+=h;j++;}}}System.out.println(o+"\b:"+c);}}

Alışkanlığım gereği, çözülmemiş kodla github .

"İlk" yol için çözüm:

$ java C "1356 | 1738" "3822 | 1424" "3527   3718" "9809 | 5926" "0261 | 1947" "7188   4717" "6624 | 9836" "4055 | 9164" "2636   4927" "5926 | 1964" "3144 | 8254"
0,2,0,1, , , ,1,4,1,4:13

İkinci örnek:

$ java C "9191 | 8282" "1919 | 2727" "5555   5555"
1,1,1,1, ,|,|, , ,2,2,2,2:12

Brian Tuck'ın örneği:

$ java C "6417443208|153287613" "8540978161|726772300" "7294922506 263609552" "0341937695 498453099" "9417989188 370992778" "2952186385|750207767" "7049868670 756968872" "1961508589|379453595" "0670474005 070712970" "4817414691|670379248" "0297779413|980515509" "6637598208 090265179" "6872950638 767270459" "7375626432 439957105" "1387683792|544956696" "6974831376 545603884" "0949220671|632555651" "3952970630|379291361" "0456363431|275612955" "2973230054|830527885" "5328382365|989887310" "4034587060 614168216" "4487052014|969272974" "5015479667 744253705" "5756698090|621187161" "9444814561|169429694" "7697999461|477558331" "3822442188 206942845" "2787118311|141642208" "2669534759 308252645" "6121516963|554616321" "5509428225|681372307" "6619817314|310054531" "1759758306 453053985" "9356970729|868811209" "4208830142 806643228" "0898841529|102183632" "9692682718|103744380" "5839709581|790845206" "7264919369|982096148"
2,1,0,1,5,1,2,1,1,1, ,1,0,1,2,1,2,3,0,1:26

"Sarhoş" Brian'ın örneği:

6417443208 | 153287613
8540978161 | 726772300
7294922506 263609552
0341937695 498453099
9417989188 370992778
2952186385 | 750207767
7049868670 756968872
1961508589 | 379453595
0670474005 070712970
4817414691 | 670379248
0297779413 | 980515509
6637598208 090265179
6872950638 767270459
7375626432 439957105
1387683792 | 544956
697483176 5456034
09492201 | 6325551
395297030 | 3792913
 456363431 | 275612
  73230054 | 830527885
    8382365 | 989887310
    4587060 614168216
  87052014 | 96927297
 50479667 7442537
57566980 | 621187161
944481456 | 169429694
7697999461 | 477558331
3822442188 206942845
2787118311 | 141642208
2669534759 308252645
6121516963 | 554616321
5509428225 | 681372307
6619817314 | 310054531
1759758306 453053985
9356970729 | 868811209
4208830142 806643228
0898841529 | 102183632
9692682718 | 103744380
5839709581 | 790845206
7264919369 | 982096148
$ java C "6417443208|153287613" "8540978161|726772300" "7294922506 263609552" "0341937695 498453099" "9417989188 370992778" "2952186385|750207767" "7049868670 756968872" "1961508589|379453595" "0670474005 070712970" "4817414691|670379248" "0297779413|980515509" "6637598208 090265179" "6872950638 767270459" "7375626432 439957105" "1387683792|544956" "697483176 5456034" "09492201|6325551" "395297030|3792913" " 456363431|275612" "  73230054|830527885" "    8382365|989887310" "    4587060 614168216" "  87052014|96927297" " 50479667 7442537" "57566980 | 621187161" "944481456 | 169429694" "7697999461|477558331" "3822442188 206942845" "2787118311|141642208" "2669534759 308252645" "6121516963|554616321" "5509428225|681372307" "6619817314|310054531" "1759758306 453053985" "9356970729|868811209" "4208830142 806643228" "0898841529|102183632" "9692682718|103744380" "5839709581|790845206" "7264919369|982096148"
 , , , ,0,5,2,0,1, , , ,1,1,1,3,2:16

Çözüm görselleştirildi:

09492201 | 6325551
395297030 | 3792913
\ 456363431 | 275612
 \ 73230054 | 830527885
  \ 8382365 | 989887310
   \ 4 \ 87060 614168216
  87/5 - \ 4 | 96927 \ 97
 50479667 \ 74425/7
57566980 | \ 62- / 87161
944481456 | \ / 69429694
7697999461 | 477558331

Zevk almak!

Düzenleme: Şimdi sadece gösteriş yapıyorum (iki yol birleşiyor!

948384 | 4288324 324324 | 121323
120390 | 1232133 598732 | 123844
 293009 | 2394023 432099 | 230943
 234882 | 2340909 843893 | 849728
  238984 | 328498984328 | 230949
  509093 | 904389823787 | 439898
   438989 | 3489889344 | 438984
   989789 | 7568945968 | 989455
    568956 | 56985869 | 568956
    988596 | 98569887 | 769865
     769879 | 769078 | 678977
     679856 | 568967 | 658957
      988798 | 8776 | 987979
      987878 | 9899 | 989899
       999889 | | 989899
       989999 | | 989999
        989898 | | 998999
        989999 | | 999999
         989998 || 899999
         989998 || 998999

Çözüm:

$ java C "948384 | 4288324   324324 | 121323" "120390 | 1232133   598732 | 123844" " 293009 | 2394023 432099 | 230943" " 234882 | 2340909 843893 | 849728" "  238984 | 328498984328 | 230949" "  509093 | 904389823787 | 439898" "   438989 | 3489889344 | 438984" "   989789 | 7568945968 | 989455" "    568956 | 56985869 | 568956" "    988596 | 98569887 | 769865" "     769879 | 769078 | 678977" "     679856 | 568967 | 658957" "      988798 | 8776 | 987979" "      987878 | 9899 | 989899" "       999889 |    | 989899" "       989999 |    | 989999" "        989898 |  | 998999" "        989999 |  | 999999" "         989998 || 899999" "         989998 || 998999"
 ,2,0,3,0,0, ,|,|, ,|,|, ,|,|, ,|,|, ,|,|, ,|,|, ,|,|, , , , , , , ,|, ,|, ,|, ,|, ,|, ,|, ,|,|, , ,1,0,7,2:15

(bonus: ungolfed'in yolu):

$ java Chicken < test5.txt
best start: 3 cost: 15
  -> 2 -> 0 -> 3 -> 0 -> 0 ->   -> | -> | ->   -> | -> | ->   -> | -> | ->   -> | -> | ->   -> | -> | ->   -> | -> | ->
  -> | -> | ->   ->   ->   ->   ->   ->   ->   -> | ->   -> | ->   -> | ->   -> | ->   -> | ->   -> | ->   -> | -> | ->
  ->   -> 1 -> 0 -> 7 -> 2 -> 15
/ -> - -> - -> \ -> / -> / -> - -> , -> , -> - -> , -> , -> - -> , -> , -> - -> , -> , -> - -> , -> , -> - -> , -> , ->
- -> , -> , -> / -> \ -> - -> - -> - -> / -> / -> ^ -> / -> ^ -> / -> ^ -> / -> ^ -> / -> ^ -> / -> ^ -> / -> , -> , ->
/ -> - -> \ -> \ -> - -> \ -> across

Algoritma ile İlgili Ayrıntılar

Çalıştığım Dinamik Programlama tekniğinin daha eksiksiz bir açıklaması istendi, işte burada:

Bir mark-and-compcompute çözüm yöntemi kullanıyorum. Uygun bir adı var, ama uzun zamandan beri unuttum; belki başka biri bunu teklif edebilir?

Algoritma:

  • En sağdaki sütundan başlayıp sola ilerleyerek, sütundaki her hücre hakkında aşağıdakileri hesaplayın:
    • Geçerli hücre maliyeti + bir sonraki sütunda ulaşılabilecek en düşük maliyetli hücre olarak tanımlanan en düşük maliyet hareketinin toplamı
    • Bu hücreden başka bir tek hücreye geçerli bir hamle olarak, bu en düşük maliyeti elde etmek için yapılacak hareket.
  • Borular ertelenir. Bir boruyu çözümlemek için, tam sütunun hesaplanmış olması gerekir, bu nedenle sonraki sütuna kadar boruları hesaplamayız.
    • Bir borunun solundaki bir hücrenin en düşük maliyetini belirlerken, önce boru boyunca seyahat etmek için en iyi yönü hesaplarız - her zaman yukarı veya aşağı doğru çözülür, böylece bir kez hesaplarız.
    • Daha sonra, diğer tüm hücrelerde olduğu gibi, en iyi maliyeti (boruda yukarı veya aşağı seyahat ederek ulaştığımız hücrenin maliyeti olarak tanımlanır) ve ona ulaşmak için seyahat yönünü depolarız.

Notlar:

Bu kadar. Yukarıdan aşağıya, sağdan sola, bir kez tararız; bir kereden fazla dokunan (potansiyel olarak) tek hücreler borulardır, ancak her boru yalnızca bir kez "çözülür" ve bizi O (m * n) penceremizin içinde tutar.

"Tek" harita boyutlarını işlemek için, boş karakterlerle dolgu yaparak satır uzunluklarını önceden taramayı ve normalleştirmeyi seçtim. Boş karakterler "sıfır maliyet" olarak sayılır, borular ve boşluklarla aynı hareket eder. Ardından, çözümü yazdırırken, normalleştirilmiş yolun kenarına ulaşıldığında veya boş bir karaktere ulaşıldığında baskı maliyetlerini veya hareketleri durdururum.

Bu algoritmanın güzelliği çok basittir, aynı kuralları her hücreye uygular, O (m * n) alt problemlerini çözerek tam bir çözüm üretir ve hız açısından oldukça hızlıdır. İlk önce "en iyi maliyet" verilerini depolamak için ikinci, hücre başına "en iyi hareket" verilerini depolamak için ikinci yolun etkin bir şekilde iki yol kopyasını oluşturarak bellekte işlem yapar; bu dinamik programlama için tipiktir.


Çizgilere yaklaşımınızı biraz daha açıklayabilir misiniz? Ayrıca (biraz farklı) bir dinamik programlama yaklaşımı denedim, ama bunları anlamakta zorlandım. Ben de çok fazla bellek kullanmadan çok geniş olmayan son derece uzun yollar ile başa çıkmak için artımlı (satır satır) bir yaklaşım düşündüm; O (m ^ 2 * n) zamanında bunu yapmanın bir yolu olup olmadığını biliyor musunuz?
dfeuer

@dfeuer Her şeyden emin olmak için ödünleşmeyle ilgili. Düşündüğüm satır satır yaklaşımların hiçbiri, bir noktada O (m ^ n) zamanına yenik düşmeden tüm girdi permütasyonlarını kaldıramadı; Bu, yapıya göre sütun sütun problemidir (hareket, büyük ölçüde soldan sağa gider - verimli DP çözümü sağdan sola gider). Basit arkası ve ertelenmiş bakış açısı ile satır satır çözme O (m * n) yaklaşımı yapabilirsiniz, ancak çok fazla bellek tasarrufu yapmadan karmaşıklığı büyük ölçüde artırıyorsunuz.
ProgrammerDan

Düşündüğüm şey, eğer yanılmıyorsam, şimdiye kadarki en iyi yolu izlemeniz ve en son işlenen satırdaki her kare için sol kenardan sağ kenara kadar bilinen en iyi yollar ve sağdaki her kareye aynı satırda. Yanlış mı?
dfeuer

1
Teşekkürler! Sen tanımlayarak bir damla kodunuzu kısaltabilirsiniz colarak -1>>>1.
dfeuer

1
Uzun süredir rekabet etmeyi zorlaştıracak Haskell'i hedefliyorum, ama şimdiye kadar en iyi bildiğim şey bu.
dfeuer
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.