Складіть малюнок у розсувну головоломку


14

Підсумок

Мета цього завдання - створити скасоване зображення-версію 15-ти головоломки / ковзання, яку також французькою мовою називають taquin .

Деталі:

Дано вхід, що складається з:

  • зображення,
  • ціле число n,
  • інше ціле число r,

ваша програма, або функція, або що-небудь інше, що підходить, повинні виводити той самий образ ( тобто той же розмір і формат), що і вхід, але він зазнав наступного процесу:

  1. розділіть зображення на прямокутники,
  2. видаліть один із цих прямокутників, випадковим чином,
  3. перемістіть випадкову кількість суміжних прямокутників з лінії / стовпця, на який впливає точка (2.), так що створений отвір заповнений, а ще один генерується в цьому рядку / стовпці. Це число може бути, 0якщо пробіл знаходиться в куті або на краю.

Повторіть (3) rрази.

Роз'яснення:

  • Якщо ви перемістили прямокутники з рядка на кроці (3.), ви повинні перемістити прямокутники зі стовпця в наступному повторенні,
  • якщо ви перемістили прямокутники зліва направо на кроці рядка, їх слід перемістити праворуч ліворуч на наступному кроці рядка, однаково для верхів донизу та знизу вгору щодо стовпців,
  • Ви можете припустити, що nйого буде обрано, щоб воно розділило довжини сторін малюнка.

Останній пункт:

Анімація, що .gifпоказує весь процес, дуже вітається.

Я пропоную використовувати наступне зображення (яке є 1024x768), n=16і r=100як модель можна використовувати будь-яку іншу картину (якщо це актуально і відповідає правилам SE, звичайно).

Зауважте, що застосовується політика щодо прорізів у стандартах .

Це , тому коротше подання виграє!

Любителі собак, котів та качок повинні бути задоволені!

Оскільки був запропонований приклад, ось такий, зроблений "вручну", з n=4іr=1

Етапи 1 і 2

введіть тут опис зображення

Крок 3 : лінійно, 2 прямокутника зліва

введіть тут опис зображення


Приклад припускає, що прямокутники не повинні бути однакового розміру, не потрібно охоплювати все зображення, а також повинні містити лінії, намальовані над початковим зображенням. Чи можете ви пояснити це, змінивши специфікацію чи приклад?
трихоплакс

@trichoplax: приклад було намальовано вручну фарбою та швидкістю. Я перероблю його належним чином.
Фредерік

@trichoplax: Я мушу визнати, що я не повністю розумію вашу думку, але ця початкова лінія не потрібна, щоб зрозуміти виклик, тому я думаю, що марно тримати її.
Фредерік

move a random number of contiguous rectanglesце може бути 0 прямокутників? (болісно буде змусити програму змінити поведінку, коли бланк знаходиться на краю / куті)
JungHwan Min

@JungHwanMin: так, це може. Гарне зауваження, дякую!
Фредерік

Відповіді:


10

Математика, 246 байт

ImageAssemble@(n=Nest)[k=RandomInteger;q=Reverse;({t,r}=1~k~2;q[o=n[q/@#&,#,r]&@*(n[#&,#,t]&)])[o@#/.{a___,b:_~RepeatedNull~k[Position[o@#,i][[1,2]]-1],i,c___}:>{a,i,b,c}]&,MapAt[(i=#~ImageAdd~1)&,#~ImagePartition~Scaled[1/#2],{1,#2}~k~2],#3]&

Анонімна функція. Містить U + F3C7, що відповідає Transposeоператору Mathematica . Ця функція бере Imageоб'єкт і повертає Imageоб’єкт.

Зразок анімації, з n=16таr=100

Після 5000 ітерацій:

введіть тут опис зображення(натисніть на зображення для збільшення версії)

Пояснення

Ініціалізація

n=Nest

Збережіть Nestфункцію (повтор операції) в n.

k=RandomInteger;q=Reverse;

Зберігайте RandomIntegerфункцію в kі Reverseфункцію в q.

Розщеплення зображення

#~ImagePartition~Scaled[1/#2]

Розділіть вхідне зображення на (другий вхід) ^ 2 плитки.

{1,#2}~k~2

Створіть два RandomIntegers між 1 і другим входом. При цьому вибирається випадкова плитка.

MapAt[(i=#~ImageAdd~1)&, ..., {1,#2}~k~2]

Зробіть цю плитку білою. Зберігайте його в i.

Рухомі плитки

{t,r}=1~k~2

Сформувати два випадкових цілих чисел від 0 до 1, і зберігати їх в tі r, відповідно. Це випадковим чином вибирає напрямок.

o=n[q/@#&,#,r]&@*(n[#&,#,t]&)

Визначте функцію o: склад

  1. функція, що транспортує вхідні tчаси.
  2. функція, що повертається кожен rраз.
o @ #

Застосувати oдо вводу.

Position[o@#,i][[1,2]]

Знайдіть стовпчик i(біле зображення).

k[ ... -1]

Відніміть одне і знайдіть випадкове ціле число між 0 і цим числом. Це випадковим чином вибирає кількість плиток для переміщення.

o@#/.{a___,b:_~RepeatedNull~ ... ,i,c___}:>{a,i,b,c}

Коли зазначена кількість плиток виникає перед i(білим зображенням), переключіть їх місця.

(... q[o= ... ])[ ... ]

Поверніть oфункцію і застосуйте її до результату вищезгаданої операції. Це знімає зображення і повертає його назад.

Цикл та збірка зображень

(n=Nest)[ ... ,#3]

Повторіть вищевказаний процес (третій вхід) рази.

ImageAssemble@

Зберіть зображення разом.


1
Гарна відповідь! Дякуємо за деталі!
Фредерік
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.