Codegolf - Карта Кошек Арнольда

  • Автор темы Yasminkt
  • Обновлено
  • 20, Oct 2024
  • #1

Испытание

Учитывая цветное растровое изображение* одинаковой ширины и высоты, выведите изображение, преобразованное под Карта кошек Арнольда. (*подробности см. ниже)

Определение

Учитывая размер изображения

 (0,0) 
we assume that the coordinates of a pixel are given as numbers between 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 maps to: 1 14 11 8 12 5 2 15 3 16 9 6 10 7 4 13 -------------------- 1 2 3 4 5 6 7 8 9 map to: 1 8 6 9 4 2 5 3 7 и (0,1) .

Карта кошек Арнольда тогда определяется следующим образом:

Пиксель по координатам 5 is moved to (1,0) .

Это не что иное, как линейное преобразование тора: желтая, фиолетовая и зеленая части отображаются обратно на исходный квадрат из-за 2 .

codegolf - Карта кошек Арнольда

Эта карта (назовем ее (0,0) ) has following properties:

  • Это биективный, это означает обратимое: это линейное преобразование с матрицей 1 . Since it has determinant [1,2,3,4] и он имеет только целочисленные записи, обратный вариант также имеет только целочисленные записи и определяется выражением (0,0) , this means it is also bijective on integer coordinates.

  • Это кручение элемент группы биективных отображений 3*N images, that means if you apply it sufficiently many times, you will get the original image back: f(f(...f(x)...)) = x Количество раз, когда карта, примененная к самой себе, приводит к идентичности, гарантированно будет меньше или равно N x N . In the following you can see the image of a cat after a given number of iterated applications of Карта кошек Арнольдаи анимацию того, как выглядит повторяющееся приложение:

codegolf - Карта кошек Арнольда codegolf - Карта кошек Арнольда

Подробности

  • Ваша программа не обязательно должна иметь дело с изображениями, но 2D-массивы/матрицы, строки или подобные 2D-структуры также приемлемы.

  • Не имеет значения, является ли ваш [[1,-1],[-1,2]] point is on the bottom left or on the top left. (Or in any other corner, if this is more convenient in your language.) Пожалуйста, укажите, какое соглашение вы используете в своем сообщении.

Тестовые случаи

В матричной форме ( 1 is the top row, [[2,1],[1,1]] имеет индекс f , mod N имеет индекс [(2*x + y) mod N, (x + y) mod N] , [x,y] имеет индекс N-1 )

0

Как изображение (слева внизу N ):

codegolf - Карта кошек Арнольдаcodegolf - Карта кошек Арнольда

#код-гольф #графический вывод #обработка изображений #линейная алгебра #повторное преобразование

Yasminkt


Рег
23 Jul, 2014

Тем
72

Постов
175

Баллов
555
  • 26, Oct 2024
  • #2

Желе, 9 байт

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
   int[][] f(int[][] m) {

int x = 0, y, l = m.length, r[][] = new int[l][];

for (; x < l; ++x) {

r[x] = new int[l];

}

for (x = 0; x < l; ++x) {

for (y = 0; y < l; ++y) {

r[(x + y) % l][(2 * x + y) % l] = m[y][x];

}

}

return r;

}
 

Попробуйте онлайн! Координаты как в ответе.

Объяснение

int[][]f(int[][]m){int x=0,y,l=m.length,r[][]=new int[l][];for(;x<l;++x)r[x]=new int[l];for(x=0;x<l;++x)for(y=0;y<l;++y)r[(x+y)%l][(2*x+y)%l]=m[y][x];return r;}

При этом обертывание сдвигает матрицу в одном направлении, затем в другом.

 

Payne


Рег
28 May, 2006

Тем
69

Постов
186

Баллов
561
  • 26, Oct 2024
  • #3

МАТЛ, 23 байта

v=getPixel((x+y)%w,(2*y+x)%h)

lambda M,n:[[M[(2*j-i)%n][(i-j)%n]for i in range(n)]for j in range(n)] point is upper left, as in the examples in the challenge text.

Попробуйте онлайн!

Объяснение

Матрицу в MATL можно индексировать одним индексом вместо двух. Это называется линейная индексацияи использует колонна-мажор заказ. Это иллюстрируется следующей матрицей 4×4, в которой значение каждой записи совпадает с ее линейным индексом:

[r[-i:]+r[:-i]for i,r in enumerate(zip(*[r[-i:]+r[:-i]for i,r in enumerate(zip(*M))]))]

Существует два похожих подхода к реализации картографии в задаче:

  1. Постройте матрицу индексации, представляющую матрицу Арнольда. обратное отображение по линейным индексам и использовать его для выбирать значения из исходной матрицы. Для случая 4×4 матрица индексации будет иметь вид

    M -> [r[-i:]+r[:-i]for i,r in enumerate(zip(*M))]

    рассказываю, что например оригинал lambda M:eval("[r[-i:]+r[:-i]for i,r in enumerate(zip(*"*2+"M))]))]") at х=2, й=1 переходит в х=3, й=2. Эта операция называется индексация ссылок: используйте матрицу индексации, чтобы указать, какой элемент выбрать из исходной матрицы. Это функция 0,0 , which takes two inputs (in its default configuration).

  2. Постройте матрицу индексации, представляющую матрицу Арнольда. прямое картографирование по линейным индексам и использовать его для писать значения в исходную матрицу. Для случая 4×4 матрица индексации будет иметь вид

    [[1,14,11,8],[12,5,2,15],[3,16,9,6],[10,7,4,13]]

    сообщая, что запись х=2, й=1 новой матрицы будет перезаписано на запись с линейным индексом [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]] # 4 , that is, х=3, й=2. Это называется индексирование присвоений: использовать матрицу индексации, матрицу данных и исходную матрицу и записывать данные в исходную матрицу по указанным индексам. Это функция m#n|r<-[0..n-1]=[[m!!mod(2*y-x)n!!mod(x-y)n|x<-r]|y<-r] , which takes three inputs (in its default configuration).

Способ 1 проще, но способ 2 оказался короче.

def f(a,n):exec'a=[l[-i:]+l[:-i]for i,l in enumerate(zip(*a))];'*2*n;return a ||answer||

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

def f(a):exec'a=[l[-i:]+l[:-i]for i,l in enumerate(zip(*a))];'*2;return a

Порт Фантастический алгоритм Линн. Перед последним находится невидимый 3-байтовый символ U+F3C7 в кодировке UTF-8. a ; Mathematica renders it as a superscript # , и он принимает транспонирование матрицы.

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

a=Length@#

Безымянная функция, принимающая два аргумента, положительное целое число. #2 and a 2D array # размеров -1 x [[1,-1],[-1,2]] и возвращает двумерный массив аналогичной формы. Как и в данном тестовом примере, точка с координатами {0,0} находится в левом верхнем углу, а ось X горизонтальна. Прямая реализация с использованием обратного # mentioned in the question, with a # в первой координате, чтобы учесть тот факт, что массивы по своей сути имеют 1-индексный индекс в системе Mathematica. Если нам не разрешено брать размерность матрицы в качестве дополнительного аргумента, то это решение станет на девять байт длиннее (замените первый #2 —not the #Table[#2[[Mod[2x-y-1,#]+1,Mod[y-x,#]+1]],{x,#},{y,#}]& and all the subsequent T с ] s).

 

GNELARTAK


Рег
10 Nov, 2019

Тем
59

Постов
181

Баллов
496
  • 26, Oct 2024
  • #4

Python 2, 89 82 77 73 байта

(n=MapIndexed[RotateLeft[#,1-#2]&,#]&)@*n

Входные данные — это список списков.
Строка внутри exec транспонирует список списков и циклически поворачивает каждый список по индексу строки (отсчет от 0 — 3-я строка поворачивается 2 раза вправо).
Этот процесс повторяется 2 раза для входа.

+4 байта, которые будут выполнять преобразование N раз.

tt % Take the input implicitly and push two more copies &n % Get its size as two (equal) numbers: N, N :qt % Push range [0 1 ... N-1] twice. This represents the original x values &+ % Matrix of all pairwise additions. This represents x+y &y % Push a copy of N onto the top of the stack \ % Modulo. This is the new y coordinate: y_new t % Push another copy b+ % Bubble up the remaining copy of [0 1 ... N-1] and add. This is 2*x+y &y % Push a copy of N onto the top of the stack \ % Modulo. This is the new x coordinate: x_new b*+ % Bubble up the remaining copy of N, multiply, add. This computes % x_new*N+y_new, which is the linear index for those x_new, y_new Q % Add 1, because MATL uses 1-based indexing ( % Assigmnent indexing: write the values of the original matrix into % (another copy of) the original matrix at the entries given by the % indexing matrix. Implicitly display the result ||answer||

Хаскель, 55 байт

(

Пример использования: 10 -> 1 10 3 12 6 15 8 13 11 4 9 2 16 5 14 7 .

) is the upper left corner. This uses the inverse transformation.

 

AGerasimchuk


Рег
10 May, 2009

Тем
61

Постов
185

Баллов
500
  • 26, Oct 2024
  • #5

Питон, 69 байт

5

Улучшение Метод Рода «транспонирование и двойной сдвиг». Применяет операцию 1 8 11 14 15 2 5 12 9 16 3 6 7 10 13 4 twice by creating and evaluating the string

1 5 9 13 2 6 10 14 3 7 11 15 4 8 12 16

Это едва ли превосходит прямое преобразование (70 байт), если предположить, что изображение квадратное и его длину можно принять в качестве входных данных:

(0,0) ||answer||

Макрос ImageJ, 29 байт

tt&n:qt&+&y\tb+&y\b*+Q(
  • Открыть изображение Лены
  • В меню «Процесс» выберите «Математика / Макрос...».
 

Yukkanen


Рег
14 Jun, 2006

Тем
62

Постов
210

Баллов
520
  • 26, Oct 2024
  • #6

Ява, 160

Гольф:

µ2¡ Twice: Z Transpose, then ṙ" Rotate rows left by JC$ 0, -1, -2, -3, …, 1-n units.

Негольфед:

Zṙ"JC$µ2¡
 

Kertman


Рег
05 May, 2020

Тем
69

Постов
186

Баллов
571
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно