失われたポーンの問題


14

失われたポーンの問題

チェスゲームが終了した後、生き残ったポーンは敵のラインの後ろに残されました。彼が家に戻る最短の道を見つけるのを手伝いましょう。

元の問題は、nXn「チェス」ボードとf: {1,..,n-1}X{1,..,n}X{-1,0,1} => R+重みの関数について説明しています。目標は、下の行のある正方形から上の行のある他の正方形への最適なパスを見つけることです。ここで、可能な動きは次のとおりです。左から上、右から上。

この問題は、動的プログラミングを使用してO(n ^ 2)で比較的簡単に解決できますが、これはcodegolfであり、実行時間の複雑さのような無駄なものは気にしません...

問題

入力:正確にサイズが通常のチェスボードに対応する3次元配列(または選択した他のコレクション、stdinを介して、または関数の引数として):7X8X3(#linePasses X #rowSize X #movesPerPass)非負の整数。移動コストから、いくつかの位置行インデックスであり、であり、列インデックスです。(i,j)ij

  • a[i][j][0]広場まで、左旅行へのコストのために(i+1,j-1)、またはグラフィカル:\
  • a[i][j][1]広場まで移動するためのコストについて(i+1,j):、またはグラフィカルに|
  • a[i][j][2]広場まで、右走行へのコストのために(i+1,j+1)、またはグラフィカル:/

合計がを超えるパスは含まれないと想定できますMAX_INT

出力:最適な(最短、つまり重みの最小合計)パスを示す8X8 ascii出力(最適な結果が複数ある場合は、任意のパスを表示できます)。パスは下から上に描画されます。各行では、パス内のポーンの位置に対応する文字が、作成しようとしている文字です。例えば、ポーンが列3から(列2に)左上に移動しようとしている場合、描画する必要があります。

#?######
##\#####

どこ?が次の動きに置き換えられるべきか。最終位置はとして描画する必要がありますX

入力:

[
  [[1,1,1],[1,1,1],[0,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,0],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,0],[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[1,0,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
  [[1,1,1],[1,1,1],[1,1,1],[0,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]]
]

出力:

##X#####
###\####
###|####
###|####
##/#####
#/######
#|######
##\#####

入力:

[
  [[41,27,38],[12,83,32],[50,53,35],[46,32,26],[55,89,82],[75,30,87],[2,11,64],[8,55,22]],
  [[56,21,0],[83,25,38],[43,75,63],[56,60,77],[68,55,89],[99,48,67],[94,30,9],[62,62,58]],
  [[23,18,40],[24,47,61],[96,45,72],[71,6,48],[75,63,98],[93,56,51],[23,31,30],[49,34,99]],
  [[20,47,42],[62,79,72],[32,28,44],[68,61,55],[62,39,57],[4,17,49],[97,85,6],[91,18,12]],
  [[51,50,11],[32,39,56],[12,82,23],[33,88,87],[60,55,22],[29,78,14],[70,11,42],[63,94,67]],
  [[75,64,60],[27,79,86],[70,72,56],[55,45,32],[95,67,12],[87,93,98],[81,36,53],[38,22,93]],
  [[31,80,50],[77,71,22],[59,46,86],[64,71,53],[41,19,95],[62,71,22],[92,80,41],[26,74,29]]
]

出力:

######X#
#####/##
####/###
#####\##
#####|##
######\#
######|#
#######\

これはなので、最短のコードが優先されます。

プレイフェア。抜け穴はありません...

編集:

Iv'eは、あなたが見ることができるscalaでゴルフをしていないまっすぐな解決策を書きました。オンラインでscalaコードでプレイできるサイトもあります:scalakata(要点をscalakataにコピーして貼り付け、再生ボタンを押すだけです)

回答:


5

Q:199バイト

f:{m::x;n::{@/[+/-1 0 1_\:/:(x;m[y;;|!3]);0 2;(0W,),{x,0W}]};i:*<*|r:{&/n[x;y]}\[8#0;!7];  s:{-1+{*<x}'+n[y;z]}\[();(,8#0),-1_r;!7];j:i,{x+y x}\[i;|s];-1(@[8#"#";;:;]'[j;"X","/|\\"1+s'[|!7;-1_j]]);}

ノート

  • Qインタープリター(kx.com)を非商用使用(Windows、Linux、Macのバージョン)に無料で提供
  • このソリューションではQの内部コア(内部的にはk4という名前)を使用するため、拡張子がkのスクリプトファイル、またはkモードの対話型インタープリター(最初のプロンプトで\コマンド)が必要です。対照的に、 'verbose'(判読可能な)バージョンの言語はq拡張子のスクリプトを必要とし、対話型インタープリターのデフォルトモードです。

テスト

f ((1 1 1; 1 1 1; 0 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 0; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 0; 1 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 1 0 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1)
   (1 1 1; 1 1 1; 1 1 1; 0 1 1; 1 1 1; 1 1 1; 1 1 1; 1 1 1))

##X#####
###\####
###|####
###|####
##/#####
#/######
#|######
##\#####

f ((41 27 38; 12 83 32; 50 53 35; 46 32 26; 55 89 82; 75 30 87;  2 11 64;  8 55 22)
   (56 21  0; 83 25 38; 43 75 63; 56 60 77; 68 55 89; 99 48 67; 94 30  9; 62 62 58)
   (23 18 40; 24 47 61; 96 45 72; 71  6 48; 75 63 98; 93 56 51; 23 31 30; 49 34 99)
   (20 47 42; 62 79 72; 32 28 44; 68 61 55; 62 39 57;  4 17 49; 97 85  6; 91 18 12)
   (51 50 11; 32 39 56; 12 82 23; 33 88 87; 60 55 22; 29 78 14; 70 11 42; 63 94 67)
   (75 64 60; 27 79 86; 70 72 56; 55 45 32; 95 67 12; 87 93 98; 81 36 53; 38 22 93)
   (31 80 50; 77 71 22; 59 46 86; 64 71 53; 41 19 95; 62 71 22; 92 80 41; 26 74 29))

######X#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\

説明

説明のために、2番目のテスト(行列((41 27 38; 12 83 32; ....)

元のマトリックス(コードレベルでm)を変換します。各座標のトリプレットを持つ元のマトリックスの代わりに、左、上、右の変位のマトリックスを定義します。左のマトリックスには7x7の値(最初の列をドロップ)、アップのマトリックス7x8、および右のマトリックス7x7(最後の列をドロップ)が含まれます。

left                           up                         right
12 50 46 55 75 2  8       27 83 53 32 89 30 11 55     38 32 35 26 82 87 64
83 43 56 68 99 94 62      21 25 75 60 55 48 30 62     0  38 63 77 89 67 9 
24 96 71 75 93 23 49      18 47 45 6  63 56 31 34     40 61 72 48 98 51 30
62 32 68 62 4  97 91      47 79 28 61 39 17 85 18     42 72 44 55 57 49 6 
32 12 33 60 29 70 63      50 39 82 88 55 78 11 94     11 56 23 87 22 14 42
27 70 55 95 87 81 38      64 79 72 45 67 93 36 22     60 86 56 32 12 98 53
77 59 64 41 62 92 26      80 71 46 71 19 71 80 74     50 22 86 53 95 22 41

最終的な位置を計算するには、最小コストのパスを評価する必要があります。初期コスト0 0 0 0 0 0 0 0(最初の行の各列に到達するためのコスト)を想定し、次の各行で繰り返します。各列iで、3つの値を計算します。

  • 以前のi + 1値とleft [i + 1]のコスト。コストの最初のコンポーネントを削除し(追加する列をシフトおよび整列化)、コンポーネントをコンポーネントに合計します

  • 前のi値にup [i]を加えたコスト。コンポーネントごとにコンポーネントを合計します

  • 前のi-1値とright [i-1]のコスト。コストの最後のコンポーネントを削除し(追加する列をシフトおよび整列化)、コンポーネントからコンポーネントに合計します

最小値を計算するために、左コストを無限に追加し、右コストを無限に追加します。8つのコンポーネントの3つのベクトルを使用して、コンポーネント間の最小コンポーネントを計算します。結果の値は、新しい反復の基本コストです

最初の反復では、値を取得します(Qで0Wは無限です)

0W 12 50 46 55 75 2  8
27 83 53 32 89 30 11 55
38 32 35 26 82 87 64 0W

各列の最小値を計算します

27 12 35 26 55 30 2 8

すべての反復の後、各正方形に到達するための最小コストがあります(上部に行0、下部に7と仮定)。最後の列にのみ興味がありますが、説明のためにすべての中間結果を描画します

0   0   0   0   0   0   0   0
27  12  35  26  55  30  2   8
27  37  78  82  110 78  11  70
45  61  123 88  173 129 34  104
87  123 151 143 212 133 40  122
98  155 163 176 234 147 51  185
158 182 219 208 246 234 87  207
208 204 265 261 265 256 128 233

これで、最後の行(128、列6)に最小値が見つかりました。これがパスの終わりです(出力のX文字)。

コスト計算を繰り返しますが、各最小値を取得する方向に注釈を付けます(最小値の計算に使用される3つの値のうち、選択した値です)。

\|/|\///
\\\\\/|/
\\\|//|/
\\|\//|/
\\|//|\/
\\//|\|/
\|/|/|\/

行を反転し、位置6に 'X'を置き、列6で終わるパスのみを保持します(他は#で置き換えられます)

######X#
#####/##
####/###
#####\##
######\#
######|#
######|#
#######\

Iv'eはQについて聞いたことがありませんが、このような詳細な応答に感謝します:)
gilad hoch
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.