Гільберти зображення


28

Мені подобається крива Гільберта .


Ваше завдання для цього завдання полягає в тому, щоб зробити зображення (строго квадратне зображення, де всі сторони мають два пікселі завширшки) і розплутати його по черзі за зигзагоподібним способом і згорнути його назад в псевдо-Гільбертовій кривій .

Розгадування

Щоб розгадати, ви почнете з пікселя у верхньому лівому куті та рухаєтесь праворуч, поки не досягнете краю зображення. Після того, як ви потрапили на край зображення, ви перейдете вниз до наступного ряду і почнете подорожувати вліво, поки ви знову не натиснете на край. Ви будете продовжувати розплутувати рядок, перемикаючи напрямок кожного разу, щоб отримати одну суцільну криву. Це повинно виглядати як добре відіграна гра в змію

Результатом розгадування має бути порядок пікселів, що включає кожен піксель рівно один раз

Перекроювання

Коли ви отримаєте замовлення на пікселі, ви переставите їх на нове полотно однакового розміру, слідуючи за кривою псевдо-Гільберта. Для 2**nрозмірного квадратного зображення слід використовувати n-ту ітерацію псевдогілбертової кривої. Кожен піксель буде розміщений рівно в одному місці на новому полотні. Вам слід переробити зображення так, щоб точка, спочатку вгорі ліворуч (початок кривої змії), залишилася там, а точка в нижньому правому куті (кінець кривої змії) буде розміщена вгорі праворуч.

I / O

Ваша програма або функція повинна приймати зображення певних обмежень за допомогою стандартних методів і виводити інше зображення за допомогою стандартних методів.

Оцінка балів

Це програма з найменшою кількістю байтових виграшів.

Приклади

Вхідні дані

Мондріан

Вихідні дані

Вихід 1


Вхідні дані

Ротько

Вихідні дані

Вихід 2


Вхідні дані

Заплутався

Вихідні дані

Лев


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

Не соромтеся включати власні результати у відповіді!


Чи добре брати масив значень RGB замість зображення як вхід? А як щодо виходу?
JungHwan Min

@JHM Ні, ти не можеш. Ви можете вибрати будь-який формат зображення, який хочете, тому, якщо у вашій мові немає вбудованої підтримки зображень, ви можете використовувати нестиснений .ppm файл, який дуже схожий на масив значень RGB.
Пшеничний майстер

Відповіді:


8

Mathematica, 286 273 байт

Image[Array[1,{l=Length@#,l}]~ReplacePart~Thread[#&@@@Split[#&@@@FoldList[Switch[#2,"-",#{1,I},"+",#/{1,I},"F",#+{ReIm@Last@#,0},_,#]&,{{1,1},I},Characters@Nest[StringReplace@{"L"->"+RF-LFL-FR+","R"->"-LF+RFR+FL-"},"L",Log2@l]]]->Join@@MapAt[Reverse,#,2;;;;2]]]&@*ImageData

Фу! Виклик, але весело!

Пояснення

ImageData

Перетворити Imageна масив значень RGB.

Array[1,{l=Length@#,l}]

Генерує з lдопомогою lмасиву з головою 1, де lє довжина вхідного сигналу (тобто ширини зображення).

Це дає {{1[1, 1], 1[1, 2], ..., 1[1, L]}, {1[2, 1], ..., 1[2, L]}, ..., {1[L, 1], ..., 1[L, L]}}( lнаписано великими літерами для зменшення плутанини)

StringReplace@{"L"->"+RF-LFL-FR+","R"->"-LF+RFR+FL-"}

StringReplaceФункція , яка замінює кожен "L"з "+RF-LFL-FR+"і "R"з"-LF+RFR+FL-"

Nest[ ... ,"L",Log2@l]

Застосуйте StringReplaceфункцію до String "L", Log2[l]раз.

Characters

Перетворіть отримане Stringв Listсимволи.

Switch[#2,"-",#{1,I},"+",#/{1,I},"F",#+{ReIm@Last@#,0},_,#]&

Безіменна функція, яка:

  • Якщо другий вхід є "-", помножте другий елемент першого вводу на I.
  • Якщо другий вхід є "+", розділіть другий елемент першого вводу на I.
  • Якщо другий вхід є "F", збільште перший вхід на ReIm(розділяє реальну та уявну частину входу) другого входу.
FoldList [..., {{1,1}, I}, ...]

Починаючи з {{1,1},I}, кумулятивно застосуйте вищевказану неназвану функцію, використовуючи кожен елемент Listсимволів як другий вхід. Цей код дає результати всіх ітерацій.

#&@@@Split[#&@@@ ... ]

Позбавтеся від других елементів кожного Listі видаліть дублікати. (Крок до цієї точки породжує Listкоординати кривої Гільберта)

Join@@MapAt[Reverse,#,2;;;;2]

Розплутайте вхідний RGB-масив (перевертає всі інші рядки і вирівнюється).

Thread[ ... -> ... ]

Створіть Ruleоб'єкти, такі, що перший елемент на першому вході (координати кривої Гільберта) поєднується з першим елементом другого входу (нерозгаданим зображенням), другим елементом із другим входом тощо.

... ~ReplacePart~ ...

Застосовуйте ці заміни Rules до Arrayдругого кроку.

Image

Перетворити масив значень RGB в Image.

Зразок введення / виводу

Вхід:

Тестовий випадок 1

Вихід:

вихід


Вхід:

Едвард і Альфонс Елрік з алхіміка Fullmetal

Вихід:

ват

Зворотна функція ( 266 253 байт)

Image[MapAt[Reverse,Extract[#,#&@@@Split[#&@@@FoldList[Switch[#2,"-",#{1,I},"+",#/{1,I},"F",#+{ReIm@Last@b,0},_,#]&,{{1,1},I},Characters@Nest[StringReplace@{"L"->"+RF-LFL-FR+","R"->"-LF+RFR+FL-"},"L",Log2[l=Length@#]]]]]~Partition~l,2;;;;2]]&@*ImageData

5

Октава 234 байт

I=imread(input(''));w=rows(I);X=[0,3;1,2];for k=2:log2(w);n=numel(X);X=[X',rot90(X',2)+3*n;X+n,X+2*n];end;for k = 1:3;I(2:2:end,:,k)=fliplr(I(2:2:end,:,k));end[~,S]=sort(X(:));I(S+(0:w^2:2*w^2))=permute(I,[2 1 3]);imwrite(I,input(''))

Імена файлів вхідних та вихідних зображень повинні бути надані із стандартного вводу. розмір коду без вводу / виводу - 194 байти .
Пояснення:

Базова схема показників:

X =
  0 3
  1 2

У кожній ітерації 4 копії за результатами попередньої зробленої ітерації та деяка трансформація, застосована до кожної копії, тоді всі блоки об'єднані, щоб утворити поточний результат.

X =[0,3;1,2];
for k = 2:log2(s)
    n=numel(X);
    X = [X',rot90(X',2)+3*n;X+n,X+2*n];
end

тому у нас є:

block(1,1): X' 
block(1,2): rot90(X',2)+3*n 
block(2,1): X+n
block(2,2): X+2*n

0    1  | 14   15
3    2  | 13   12
--------|--------
4    7  |  8   11
5    6  |  9   10

Індекси Гільберта відсортовано та повернуто індекси відсортованих елементів:

[~,S]=sort(X(:));

Розгортання застосованого гортання всіх рівних рядків:

for k = 1:3
    I(2:2:end,:,k) = fliplr(I(2:2:end,:,k));
end

Застосовується перемотування:
-S повторюється для кожного каналу -
застосовується перестановка, оскільки в даних Octave розташований стовпчик

I(S+(0:w^2:2*w^2))=permute(I,[2 1 3]);

Приклади зображень:

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

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

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

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


Ви можете вибрати, щоб ваша програма працювала як функція, якщо ви хочете уникати використання вводу-виводу.
Пшеничний майстер

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