도전
너비와 높이가 동일한 색상 래스터 이미지 *가 제공되면 Arnold의 cat map에서 변환 된 이미지를 출력합니다 . (* 자세한 내용은 아래 참조)
정의
이미지의 크기가 주어지면 N
픽셀의 좌표가 0
와 사이의 숫자로 주어진다고 가정합니다 N-1
.
Arnold의 고양이 맵 은 다음과 같이 정의됩니다.
좌표의 픽셀 [x,y]
이로 이동합니다 [(2*x + y) mod N, (x + y) mod N]
.
이것은 원환 체의 선형 변환에 지나지 않습니다. 노란색, 보라색 및 녹색 부분은로 인해 초기 사각형에 다시 매핑됩니다 mod N
.
이 맵 (이것을 호출하자 f
)에는 다음과 같은 속성이 있습니다
-
그것은 인 전단 사 수단 가역 것을 : 그것은 행렬로 선형 변환이다
[[2,1],[1,1]]
. 결정자가1
있고 정수 항목 만 있기 때문에 역수에는 정수 항목 만 있고로 주어집니다[[1,-1],[-1,2]]
. 이는 정수 좌표에서도 이항적임을 의미합니다. -
그것은이다 비틀림 의 전단 사지도 그룹의 요소
N x N
: 수단 당신이 그것을 충분히 많은 시간, 당신은 원본 이미지 다시 얻을 것이다 적용 할 경우 것으로, 이미지f(f(...f(x)...)) = x
신원의지도 자체에 적용되는 시간의 양의 결과를 이하로 보장된다 또는 같습니다3*N
. 다음에서는 Arnold의 cat map 을 반복해서 사용한 고양이 이미지 와 반복되는 애플리케이션의 모습을 애니메이션으로 볼 수 있습니다.
세부
-
프로그램이 반드시 이미지를 다룰 필요는 없지만 2D 배열 / 행렬, 문자열 또는 이와 유사한 2D 구조도 허용됩니다.
-
(0,0)
포인트가 왼쪽 하단에 있는지 또는 왼쪽 상단에 있는지는 중요하지 않습니다 . (또는 귀하의 언어로보다 편리한 경우 다른 구석에 있습니다.) 제출시 사용할 규칙을 지정하십시오.
테스트 케이스
행렬 형식으로 ( [1,2,3,4]
맨 위 행, 1
index (0,0)
, 2
index (1,0)
, 5
index가 있음 (0,1)
)
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,0)
) :
답변
젤리 , 9 바이트
Zṙ"JC$µ2¡
온라인으로 사용해보십시오! 좌표는 답에서와 같습니다.
설명
µ2¡ Twice:
Z Transpose, then
ṙ" Rotate rows left by
JC$ 0, -1, -2, -3, …, 1-n units.
이것은 한 방향으로 매트릭스를 감싼 다음 다른 방향으로 깎습니다.
답변
MATL , 23 바이트
tt&n:qt&+&y\tb+&y\b*+Q(
그만큼 (0,0)
점은 위 도전 텍스트의 예와 같이 남아 있습니다.
설명
MATL의 행렬은 두 개의 인덱스 대신 단일 인덱스로 인덱스 할 수 있습니다. 이것을 선형 인덱싱 이라고 하며 열 주요 순서를 사용합니다. 이것은 다음 4 × 4 행렬로 설명되며, 각 항목의 값이 선형 지수와 일치합니다.
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
챌린지에서 매핑을 구현하는 두 가지 유사한 방법이 있습니다.
-
선형 인덱스에서 Arnold의 역 매핑 을 나타내는 인덱싱 행렬을 작성하고 이를 사용 하여 원래 행렬에서 값 을 선택 합니다. 4 × 4의 경우, 인덱싱 행렬은
1 8 11 14 15 2 5 12 9 16 3 6 7 10 13 4
예를 들어 x = 2
5
에서 원본 을 말하면 y = 1은 x = 3, y = 2가됩니다. 이 작업을 참조 인덱싱 이라고 합니다 . 인덱싱 매트릭스를 사용하여 원래 매트릭스에서 선택할 요소를 알려줍니다. 이것은 functon)
이며, 기본 구성에서 두 개의 입력을받습니다. -
선형 인덱스에 대한 Arnold의 직접 매핑 을 나타내는 인덱싱 매트릭스 를 작성 하고 이를 사용 하여 값을 원래 매트릭스 에 씁니다 . 4 × 4의 경우, 인덱싱 행렬은
1 10 3 12 6 15 8 13 11 4 9 2 16 5 14 7
엔트리 것을 말하고 , X = 2, Y 새로운 매트릭스 = 1은 선형 인덱스 항목에 덮어 것
10
인, X = 3, Y = 2. 이를 할당 색인 이라고 합니다 . 색인 행렬, 데이터 행렬 및 원본 행렬을 사용하고 지정된 인덱스에서 원본 행렬에 데이터를 씁니다. 이것은(
기본 설정에서 세 개의 입력을받는 function 입니다.
방법 1은 더 간단하지만 방법 2는 더 짧았습니다.
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
답변
매스 매 티카, 44 바이트
(n=MapIndexed[RotateLeft[#,1-#2]&,#]&)@*n
Lynn의 환상적인 알고리즘의 포트 . UTF-8 인코딩에는 보이지 않는 3 바이트 문자 U + F3C7이 마지막 문자 앞에 있습니다 ]
. Mathematica는 그것을 첨자로 렌더링 T
하고 행렬의 전치를받습니다.
수학, 54 바이트
Table[#2[[Mod[2x-y-1,#]+1,Mod[y-x,#]+1]],{x,#},{y,#}]&
명명되지 않은 함수는 양의 정수 #
와 #2
차원 #
x 의 2D 배열 인 두 개의 인수를 취하고 #
비슷한 모양의 2D 배열을 반환합니다. 주어진 테스트 사례에서와 같이 좌표가 {0,0} 인 점은 왼쪽 상단에 있고 x 축은 수평입니다. 배열이 Mathematica에서 본질적으로 1- 인덱싱된다는 사실을 설명하기 위해 첫 번째 좌표에서 [[1,-1],[-1,2]]
질문에 언급 된 역을 사용하여 간단한 구현 -1
. 우리는 추가 인수로 행렬의 차원을 허용하지 않는 경우,이 솔루션은 (첫 번째 교체 구 바이트 이상이된다 #
-not에게 #2
가진 – a=Length@#
모든 후속 #
와의 a
들).
답변
파이썬 2, 89 82 77 73 바이트
def f(a):exec'a=[l[-i:]+l[:-i]for i,l in enumerate(zip(*a))];'*2;return a
입력은 목록의 목록입니다
. exec 내부의 문자열은 목록의 목록을 바꾸고 각 목록을 줄 색인으로 주기적으로 회전시킵니다 (0 기반-세 번째 줄은 오른쪽으로 2 회 회전).
이 프로세스는 입력에 2 번 수행됩니다.
변환을 N 번 수행하는 +4 바이트
def f(a,n):exec'a=[l[-i:]+l[:-i]for i,l in enumerate(zip(*a))];'*2*n;return a
답변
하스켈, 55 바이트
m#n|r<-[0..n-1]=[[m!!mod(2*y-x)n!!mod(x-y)n|x<-r]|y<-r]
사용 예 : [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]] # 4
-> [[1,14,11,8],[12,5,2,15],[3,16,9,6],[10,7,4,13]]
.
0,0
왼쪽 상단입니다. 이것은 역변환을 사용합니다.
답변
파이썬, 69 바이트
lambda M:eval("[r[-i:]+r[:-i]for i,r in enumerate(zip(*"*2+"M))]))]")
Rod의 조옮김 및 전환 방법 이 개선되었습니다 . M -> [r[-i:]+r[:-i]for i,r in enumerate(zip(*M))]
문자열을 만들고 평가 하여 작업을 두 번 적용 합니다.
[r[-i:]+r[:-i]for i,r in enumerate(zip(*[r[-i:]+r[:-i]for i,r in enumerate(zip(*M))]))]
이미지가 정사각형이고 길이를 입력으로 사용할 수 있다고 가정하면 직접 변환 (70 바이트)을 좁 힙니다.
lambda M,n:[[M[(2*j-i)%n][(i-j)%n]for i in range(n)]for j in range(n)]
답변
ImageJ 매크로, 29 바이트
v=getPixel((x+y)%w,(2*y+x)%h)
- 레나의 열린 이미지
- 프로세스 메뉴에서 수학 / 매크로 …를 선택하십시오.