鶏はどのように道路を横断しましたか?


16

ガチャガチャ。鶏が道路を横断した理由は誰にもわかりません。反対側には見栄えの良い雄鶏がいたかもしれません。しかし、私たちはその方法を理解できます。この(または任意の)「道路」を横切る左から右へのプログラムを作成します。

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

プログラムは「交差」し、左から右に移動します。あなたが好きな一番左の列の任意の番号から始めます。そこから、右側の隣接するキャラクターに移動できます。左上隅の1で開始した場合は、3または8に移動できます。開始番号を含む、移動したすべての番号が合計に加算されます。スペースは合計に追加されません。「|」右側に移動するのではなく、強制的に上下に移動します。(このキャラクターで前進することはできません)あなたの目標は、可能な限り最小の金額で反対側に到達することです。プログラムは最後に合計を印刷する必要があり、すべての道を解決できなければなりません。道路への入力も可能ですが、必須ではありません。プログラムは、パスと合計の両方を印刷する必要があります。最少バイトのコードが勝ちます。

明確にするために、垂直バー上にいる場合を除き、診断的に移動できます。垂直バーにいるときのみ上下に移動できます。

道路をより明確に指定するために、基本的には文字列(または列や行の配列)を文字のルールに従いますが、文字は何もありません道路。任意の数字、スペース、バー( "|")、または改行を使用できます。ProgrammerDanの答えのように、道路が酔っ払った男によって舗装された場合、それはまだ有効な道路であり、プログラムはそのような道路を解決できる必要があります。反対側に到達することが不可能な場合、道路とはみなされません(たとえば、バーの直線から抜け出す方法がありません)。

プログラムは、道路が無効かどうかを判断する必要はありません。

キー:
任意の数字-合計に数字を追加し、前進します。
スペース-前進します。合計には何も追加されません。
「|」-上下に移動しても、合計には何も追加されません。

編集:提案されたソリューションの例。私は恐ろしく大きなものを作ることはできません。ATMのためにそれを解決するIDEに乗ることはできません。

この小さな道を進みます。

9191 | 8282
1919 | 2727
5555   5555

解決策は、1、1、1、1、スペース、ディバイダー、ディバイダー、スペース、スペース、2、2、2、2、合計12のパスになります。

編集#2:この質問の最初の道への解決策は、ジオビットと人々のプログラムによって決定されるように、合計13の場合、0,2,0,1、、、、1,4,1,4です。


4
少なくとも1つのテストケースに正しいソリューションを含めることができますか?また、3つ以上|の行がある可能性がありますか?
マーティンエンダー

1
@timmyは、前方に移動している限り、斜めに移動できます。いくつかの斜めの動きに触れることができます。
CaffeineToCode

3
@ mbomb007上隅から開始する場合。左の列のいずれからでも開始できるため、次の情報を取得できます0,2,0,1, , , ,1,4,1,4 -> 13
Geobits

1
はい、そうです。バーの上または下にしか移動できないため、スペースからしか出られません。
CaffeineToCode

1
出力については、単にコストで十分ですか、それともパス全体を出力する必要がありますか?
プログラマー

回答:


3

Pyth、168 143 141バイト[現在Drunken Road互換]

私のテストケースは動作しますが、私の側の誤解のために、最初の例では適切に動作しません。修正に取り組んでいます。

現在、元の例と飲酒道路で作業中

いくつかの本当に codeいコードを少し減らします:

=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

ここでテストする

10 + 9 x 40の道路でテストしました。

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

用意されているテストスイートを使用して実行すると、 "IndexError:リストインデックスが範囲外です"が表示されることに注意してください。
プログラマー

@ProgrammerDan私もそうです。
CaffeineToCode15年

1
@CaffeineToCode trueですが、「酔っぱらい道」の概念は、提出後に追加されました。何が道路を構成していたかを知ることができれば助かりました。例に基づいて、分割列を持つ2つの側面を想定しました
ブライアンタック

1
@CaffeineToCode良い質問を書くための最良の方法の1つは、解決策がなくても、より多くの例を書くことです。可変幅の道路または複数車線の道路が有効な場合、1つの「クレイジー」な例は、追加の説明テキストなしでそれを示します。
ProgrammerDan

1
@ProgrammerDanあなたはそれを求めました。鉱山はDR互換になりました(そして、もっと短く...私が追いついていると思います)
ブライアンタック

4

Java、955バイト

当然のことながら、Javaなどすべての賞を受賞するつもりはありませんが、この問題が大好きで、自分のエントリーを掲載したいと考えました。

機能と制限:

  • 可変幅、複雑な線などを含む不規則な道路(超飲酒!)をサポートできます。
  • 実行時にパラメーターとして道路が入力されることを期待します。未ゴルフバージョンは標準入力からの読み取りもサポートしますが、入力メソッドが指定されていないため、ゴルフバージョンは最小を期待します!
  • O(n * m)時間(nは行、mは列)で効率的に解くために、6年ほど使用していない動的プログラミング手法を使用します。
    • 取るための最良の方向マーキング右から左に解決しから次のインデックスに現在のインデックスを。
    • 「行」は、列を解決し、次の列で到達可能な場合はアドレスを指定することで処理されます。最終的に到達可能なノンラインのコストで、方向を上下に保存することで解決します。
  • 追跡しますが、最適なソリューションの開始インデックスを印刷しません(ゴルフ版では)。

OK、十分なジバジャバ。ゴルフバージョン:

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);}}

私の習慣に従って、Golfhubにはolfolfされていないコードがあります

「最初の」道路のソリューション:

$ 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

2番目の例:

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

ブライアンタックのサンプル:

$ 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

「酔っぱらった」ブライアンの例:

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

視覚化されたソリューション:

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

楽しい!

編集:今私は誇示している(2つの道路がマージ!彼はそれを作ることができますか?)

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

解決:

$ 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

(ボーナス:ungolfedからのパス):

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

アルゴリズムの詳細

私が採用した動的計画法のより完全な説明が要求されたので、ここに行きます:

私は解決策のマークと事前計算の方法を使用しています。それは適切な名前を持っていますが、私はそれを長い間忘れていました。おそらく他の誰かがそれを提供できますか?

アルゴリズム:

  • 右端の列から開始して左に進み、列内の各セルについて次の計算を行います。
    • 現在のセルコスト + 次の列で到達可能な最低コストのセルとして定義される最低コストの動きの合計
    • このセルから別の単一セルへの単純な有効な移動として、この最低コストを達成するために実行する移動アクション。
  • パイプは延期されます。パイプを解決するには、列全体を計算する必要があるため、次の列までパイプを計算しません。
    • パイプの左側のセルの最低コストを決定するとき、最初にパイプに沿って移動する最適な方向を計算します-常に上または下のいずれかに解決されるため、一度計算します。
    • 次に、他のすべてのセルと同様に、最適なコスト(パイプ上を上下に移動することで到達するセルのコストとして定義)と、到達するために移動する方向を保存します。

ノート:

それでおしまい。上から下、右から左に1回スキャンします。1回以上(潜在的に)触れたセルはパイプだけですが、各パイプは1回だけ「解決」され、O(m * n)ウィンドウ内に保持されます。

「奇数」のマップサイズを処理するために、null文字をパディングすることで単純に行の長さを事前にスキャンして正規化することを選択しました。ヌル文字は、「ゼロコスト」としてパイプおよびスペースと同じように移動します。次に、ソリューションを印刷する際に、正規化された道路の端に到達するか、ヌル文字に到達すると、印刷コストを停止するか移動します。

このアルゴリズムの美しさは非常にシンプルで、すべてのセルに同じルールを適用し、O(m * n)の部分問題を解くことで完全なソリューションを生成し、速度の面ではかなり高速です。メモリとのトレードオフを行い、道路地図のメモリに2つのコピーを効果的に作成します。1つ目は「最良コスト」データを保存し、2つ目は「ベストムーブ」データをセルごとに保存します。これは、動的プログラミングの典型です。


回線へのアプローチについてもう少し説明していただけますか?また、(多少異なる)動的プログラミングアプローチを試みましたが、それらを理解するのが難しくなりました。また、メモリを使いすぎずに幅が広すぎない非常に長い道路を処理するためのインクリメンタル(行ごと)アプローチも検討しました。O(m ^ 2 * n)時間の下でそれを行う方法があるかどうか知っていますか?
dfeuer

@dfeuer確かにトレードオフについてです。私が検討した行ごとのアプローチは、いずれかの時点でO(m ^ n)時間に屈することなく、入力のすべての順列を処理できませんでした。これは、構造ごとの列ごとの問題です(主に、左から右に移動します。効率的なDPソリューションは右から左に移動します)。O(m * n)アプローチを使用して、単純な後読みと先読みの先読みで行ごとに解決できる場合もありますが、多くのメモリを節約することなく複雑さが大幅に増加しています。
ProgrammerDan

私が考えていたのは、私が間違っていなければ、これまでのベストパスを追跡し、最後に処理された行の各正方形について、左端から右端までの最もよく知られたパスを追跡し、同じ行の右側の各正方形に。それは間違っていますか?
dfeuer

1
ありがとう!cとして定義することで、コードのドロップを短縮できます-1>>>1
dfeuer

1
Haskellをターゲットにしているため、長さを競うのが難しくなりますが、それは私が最もよく知っていることです。
dfeuer
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.