Наименьшее количество записей на диск для дефрагментации нескольких файлов

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 |   |   |   |

Диск считается дефрагментированным, если все файлы в нем хранятся непрерывно.

ВАША ЦЕЛЬ:

Создайте кратчайшую последовательность законных ходов, которая дефрагментирует данный диск.

Легальные ходы

Перемещение содержит три фрагмента информации: имя файла, индекс блока в файле, который необходимо переместить, и индекс блока диска, на который он перемещается.

Например

ALPHA:1>4

"Переместить блок 1 файла ALPHA в блок 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 |   |   |   |

Ранее обитаемый дисковый блок неявно очищается. Эквивалентно, вы можете рассматривать это как замену двух блоков на диске, но один из блоков в разделе подкачки должен быть пустым .

Данные не могут быть уничтожены. Файлы не могут совместно использовать блоки на любом этапе, и движения должны быть в пределах досягаемости диска. Следующие шаги недопустимы : 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

Требования

Ваш код должен принимать любой размер диска, а также любое количество и размер файлов.

Входные данные, которые не описывают допустимые исходные состояния файловой системы, могут привести к неопределенному поведению.

Ваш код должен создавать решение для кратчайших ходов для любого четко определенного ввода.

Все ваши ходы должны быть законными; файловая система должна быть в правильном состоянии после применения каждого выполняемого вами шага.

Ваш код должен завершаться для всех допустимых входных данных, то есть он никогда не должен зацикливаться на цикле, файловая система должна находиться в совершенно новом состоянии после каждого перемещения.

Если существует более одного кратчайшего решения, любое из них может быть выбрано как действительное.

Самый короткий код выигрывает. Пожалуйста, опубликуйте хотя бы один новый нетривиальный пример ввода и его вывода с вашим кодом.

spraff
источник
Как бы мы выяснили, какой длины самая короткая последовательность для произвольного диска? (На вопрос, потому что, если ответ А говорит, что самый короткий - 6 ходов, а ответ В - самый короткий - 5, тогда ответ А становится дисквалифицированным?)
ASCIIThenANSI
Поиск в ширину может предоставить справочное решение, если это необходимо.
Spraff
2
Это, вероятно, будет работать лучше как вызов [атомного кода-гольфа]. Таким образом, вы получите больше ответов. Вместо кратчайшего кода победителем будет ответ с наименьшим количеством записей на диск.
mbomb007

Ответы:

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

Решение:
   АЛЕФ: 2> 2
   АЛЕФ: 0> 0
   BET: 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

Безголовая версия .

Джонатан Фрех
источник