複数のファイルをデフラグする最少ディスク書き込み


18

前書き

ディスクがインデックスブロックを有する直鎖状の容器である0介しsize-1

ファイルは、そのファイルで使用されるブロックインデックスの名前付きリストです。

ファイルシステムの例は次のように表されます。

15 ALPHA=3,5 BETA=11,10,7

「ディスクには15ブロックあります。ファイルALPHAの最初のブロックは、インデックス3のディスクブロックです...」

ディスクマップは次のように描画できます。

Block Index  00  01  02  03  04  05  06  07  08  09  10  11  12  13  14
Contents    |   |   |   |A0 |   |A1 |   |B2 |   |   |B1 |B0 |   |   |   |

ディスクは、ディスク内のすべてのファイルが連続して保存されている場合、最適化されていると見なされます。

あなたの目標:

特定のディスクを最適化する、法的措置の最短シーケンスを発行します。

法的な動き

移動には、ファイルの名前、移動するファイル内のブロックのインデックス、移動先のディスクブロックのインデックスの3つの情報が含まれます

例えば

ALPHA:1>4

「ファイルALPHAのブロック1をディスクのブロック4に移動します。」

この移動後、サンプルファイルシステムは次のようになります。

15 ALPHA=3,4 BETA=11,10,7

Block Index  00  01  02  03  04  05  06  07  08  09  10  11  12  13  14
Contents    |   |   |   |A0 |A1 |   |   |B2 |   |   |B1 |B0 |   |   |   |

以前に居住していたディスクブロックは暗黙的にクリアされます。同様に、これはディスク上の2つのブロックをスワップすると見なすことができますが、スワップ内のブロックの1つは空でなければなりません

データは破壊されません。ファイルはどの段階でもブロックを共有できず、移動はディスクの範囲内でなければなりません。次の動きは違法です:ALPHA:0>10(BETAが所有)、ALPHA:3>0(ALPHAにそのようなブロックがALPHA:0>-1ない)、(そのようなディスクインデックスがない)、ALPHA:0>15(ディスクインデックスが大きすぎる)

例1

上記の例を完全に解決します。

ALPHA:0>4
BETA:0>9
BETA:2>11

ファイルはソリューション内で隣接している必要はなく、ファイル内で連続しているだけです。

例2

ここに、より制約のあるケースがあります

入力:

10 A=1,2,3 B=6,7,8 C=4,5,0

出力:

B:2>9
B:1>8
B:0>7
C:2>6

このファイルシステムの進行は次のとおりです。

Block Index  00  01  02  03  04  05  06  07  08  09
Contents    |C2 |A0 |A1 |A2 |C0 |C1 |BO |B1 |B2 |   |
            |C2 |A0 |A1 |A2 |C0 |C1 |BO |B1 |   |B2 |
            |C2 |A0 |A1 |A2 |C0 |C1 |BO |   |B1 |B2 |
            |C2 |A0 |A1 |A2 |C0 |C1 |   |B0 |B1 |B2 |
            |   |A0 |A1 |A2 |C0 |C1 |C2 |B0 |B1 |B2 |

これはへでしまうデフラグする別の方法C:2>9、その後持参A持参その後、ステップダウンC行い、その後、ステップダウンC:2>5しかし、それは代替よりも多くの動きが含まれているため、これは法的な解決策ではないでしょう

表現

基本的な文字列にかなり近い限り、入力に任意の表現を使用できます。言語によっては、最初の例への入力は次のように表記される場合があります

"15 ALPHA=3,5 BETA=11,10,7"
[15," ","ALPHA","=",3,",",5," ","BETA","=",11,",",10,",",7]
(15,(("ALPHA",(3,5)),("BETA",(11,10,7))))
etc

同様に、出力は、印刷されたままの人間の読み取り可能なログとして、言語にとって便利なものであれば何でもかまいません。各ムーブは、1)file-name、2)file-block-index 、3)new-disk-block-index

"ALPHA:1>6 BETA:2>9"
(0=>(0=>"ALPHA",1=>"1",2=>"6"), 1=>(0=>"BETA",1=>"2",2=>"9"))
["ALPHA",1,6,"BETA",2,9]
etc

必要条件

コードは、任意のサイズのディスク、および任意の数とサイズのファイルを受け入れる必要があります。

正当な初期ファイルシステムの状態を記述しない入力は、未定義の動作につながる可能性があります。

適切に定義された入力に対して、コードは最短移動ソリューションを生成する必要があります。

作成するすべての動きは合法でなければなりません。作成する各ステップを適用した後、ファイルシステムは有効な状態でなければなりません。

コードはすべての有効な入力に対して終了する必要があります。つまり、ループに陥ることはありません。各移動が適用されると、ファイルシステムは明らかに新しい状態になります。

最短のソリューションが複数存在する場合は、有効なソリューションを選択できます。

最短のコードが優先されます。少なくとも1つの新しい重要なサンプル入力とその出力をコードに投稿してください。


任意のディスクの「最短シーケンス」の長さはどのようにしてわかりますか?(回答Aが最短が6移動であると答え、回答Bが最短が5であると答えると、回答Aは失格になりますか?)
ASCIIThenANSI

幅優先検索は、必要に応じて参照ソリューションを提供できます。
spraff

2
これはおそらく、[アトミックコードゴルフ]チャレンジとしてより適切に機能します。その方法でより多くの回答が得られます。最短のコードの代わりに、ディスクへの書き込みが最も少ない答えが勝者となります。
mbomb007 16

回答:


1

Python 3、295バイト

S,F=eval(input());d=[0]*S;E=enumerate
for n,P in F:
 for j,p in E(P):d[int(p)]=n,j
Z=[(d,())]
while Z:d,p=Z.pop(0);any(e and(e[0],e[1]+1)in d and(S<j+2or(e[0],e[1]+1)!=d[j+1])for j,e in E(d))or print(p).q;{d[j]or exec("D=d[:];D[j]=e;D[k]=0;Z+=(D,p+(e,j)),")for j,_ in E(d)for k,e in E(d)if d[k]}

オンラインでお試しください!


別のテストケース

入力:
   7 ALEF = 6,4,0 BET = 5,1 GIMEL = 3

初期ディスク状態:
   A2 B1 __ G0 A1 B0 A0

解決:
   ALEF:2> 2
   ALEF:0> 0
   ベット:1> 6
   アレフ:1> 1

視覚化されたソリューション:
   A2 B1 __ G0 A1 B0 A0
   __ B1 A2 G0 A1 B0 A0
   A0 B1 A2 G0 A1 B0 __
   A0 __ A2 G0 A1 B0 B1
   A0 A1 A2 G0 __ B0 B1

ゴルフされていないバージョン

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.