Arnold'un Kedi Haritası


21

Meydan okuma

Aynı genişlik ve yüksekliğe sahip renkli bir raster görüntü * verildiğinde, Arnold'un kedi haritası altında dönüştürülen görüntüyü çıktılar . (* detaylar aşağıya bakınız)

Tanım

Görüntünün boyutu göz önüne alındığında Nbir pikselin koordinatları arasındaki sayılar olarak verilmiştir varsayalım 0ve N-1.

Arnold'un kedi haritası daha sonra şöyle tanımlanır:

Koordinatlardaki bir piksel [x,y]taşındı [(2*x + y) mod N, (x + y) mod N].

Bu, torus üzerindeki doğrusal bir dönüşümden başka bir şey değildir: Sarı, menekşe ve yeşil kısım nedeniyle ilk kareye eşlenir mod N.

görüntüleme

Bu harita (hadi arayalım f) aşağıdaki özelliklere sahiptir:

  • Bu bibekti , bu tersinir anlamına gelir: Matris ile doğrusal bir dönüşümdür [[2,1],[1,1]]. Belirleyici olduğu 1ve ve sadece tamsayı girişleri olduğu için, tersi de sadece tamsayı girişleri vardır ve [[1,-1],[-1,2]]bu, tamsayı koordinatlarında bibektif olduğu anlamına gelir.

  • Bu, görüntülerin bijective haritalar grubunun bir torsiyon elemanıdır N x N, yani, onu birçok kez yeterince uygularsanız, orijinal görüntüyü geri alırsınız: f(f(...f(x)...)) = xHaritanın kimliğe verdiği sonuçların daha az olması garanti edilir veya eşittir 3*N. Aşağıda, Arnold'un kedi haritasının belirli bir yinelenen uygulamasından sonra bir kedinin görüntüsünü ve tekrarlanan bir uygulamanın neye benzediğini gösteren bir animasyon görebilirsiniz:

çoklu tekrarlanan uygulamalar

ayrıntılar

  • Programınız mutlaka görüntülerle uğraşmak zorunda değildir, ancak 2D dizileri / matrisleri, dizeleri veya benzer 2D yapıları da kabul edilebilir.

  • (0,0)Amacınızın sol alt mı yoksa sol üst mi olduğu önemli değil . (Veya bu herhangi bir köşede, eğer sizin dilinizde daha uygunsa.) Lütfen gönderiminizde hangi kuralları kullandığınızı belirtin.

testcases

Matris formunda ( [1,2,3,4], üst sırada 1indeksine sahiptir (0,0), 2indeksine sahiptir (1,0), 5indisine sahiptir (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

Resim olarak (sol altta (0,0)):


1
Zavallı Lena. Umarım yeterince uzun süre yinelemeye devam ettin
Luis Mendo

2
Görüntü boyutunu girdi olarak alabilir miyiz? Her zaman kare mi?
xnor

1
Evet görüntü karelik hep olduğunu ve boyutu hakkında emin değilim, orada bir şey karşı olduğunu izin?
kusur

Yanıtlar:


10

Jöle , 9 bayt

Zṙ"JC$µ2¡

Çevrimiçi deneyin! Koordinatlar cevaptaki gibidir.

açıklama

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

Bu, matrisi bir yöne, sonra diğer yöne kaydırır.


Fantastik algoritma!
Greg Martin

7

MATL , 23 bayt

tt&n:qt&+&y\tb+&y\b*+Q(

(0,0)Nokta üst zorluk metinde örneklerde olduğu gibi, bırakılır.

Çevrimiçi deneyin!

açıklama

MATL'deki bir matris iki yerine tek bir indeksle indekslenebilir. Buna doğrusal dizinleme adı verilir ve sütun ana düzeni kullanılır. Bu, her girişteki değerin doğrusal endeksiyle çakıştığı aşağıdaki 4 x 4 matrisiyle gösterilmiştir:

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

Eşleştirmeyi uygulamada uygulamak için benzer iki yaklaşım vardır:

  1. Arnold'un lineer endekslerde ters eşlemesini temsil eden bir indeksleme matrisi oluşturun ve orijinal matristeki değerleri seçmek için kullanın . 4 × 4 durum için indeksleme matrisi

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

    örneğin, orijinal olduğunu söylemek 5de x = 2, y 1 gider = x = 3, y = 2. Bu işleme referans indeksleme adı verilir : orijinal matristen hangi elemanı seçeceğini söylemek için indeksleme matrisini kullanın. Bu, )iki giriş alan functon'dur (varsayılan yapılandırmasında).

  2. Arnold'un doğrusal endekslerde doğrudan eşlemesini temsil eden bir indeksleme matrisi oluşturun ve değerleri orijinal matrise yazmak için kullanın . 4 × 4 durum için indeksleme matrisi

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

    girdisi anlatan x = 2 olduğunda, y , yeni matris = 1 lineer dizin ile giriş üzerine yazılır olacak 10olan, x = 3 olduğunda, y = 2. Buna atama indeksleme adı verilir : indeksleme matrisini, bir veri matrisini ve orijinal matrisi kullanın ve verileri belirtilen indekslerde orijinal matrise yazın. Bu, (üç giriş alan fonksiyondur (varsayılan konfigürasyonunda).

Yöntem 1 daha basittir, ancak yöntem 2'nin daha kısa olduğu ortaya çıktı.

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

5

Mathematica, 44 bayt

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

Lynn'in harika algoritmasının limanı . UTF-8 kodlamasında görünmez bir 3 baytlık karakter, U + F3C7 var ]; Mathematica, onu bir üst simge olarak işler Tve bir matrisin transpozisyonunu alır.

Mathematica, 54 bayt

Table[#2[[Mod[2x-y-1,#]+1,Mod[y-x,#]+1]],{x,#},{y,#}]&

Adsız fonksiyonu iki bağımsız bir pozitif tamsayıyı alarak #ve 2B dizi #2boyutlarının #X #ve benzer şekilde bir 2 boyutlu dizi geri döndürülmesi. Verilen test durumundaki gibi, {0,0} koordinatlarına sahip nokta sol üstte ve x ekseni yataydır. [[1,-1],[-1,2]]Sorunun içinde belirtilen tersi kullanan basit uygulama -1, dizilerin doğal olarak Mathematica'da 1 indeksli olduğu gerçeğini hesaba katan ilk koordinatta. Ek bir argüman olarak matrisin boyutu almaya izin verilmez, o zaman bu çözüm (ilk yerine dokuz bayt uzarsa #daha etme #2-with a=Length@#ve sonraki tüm #ile s as).


Dang, beni dövdü
JungHwan Min

3

Python 2, 89 82 77 73 bayt

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

Giriş, listelerin bir listesidir
Çalıştır içindeki dize, listelerin listesini dönüştürür ve her listeyi satır dizinine göre döngüsel olarak döndürür (0 temelli - 3. satır, 2 kez sağa döndürülür).
Bu işlem girişe 2 kez yapılır.

N kez dönüşüm yapacak +4 bayt

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

2

Haskell, 55 bayt

m#n|r<-[0..n-1]=[[m!!mod(2*y-x)n!!mod(x-y)n|x<-r]|y<-r]

Kullanım örneği: [[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,0Sol üst köşede. Bu ters dönüşümü kullanır.


1

Python, 69 bayt

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

Rod'un devrik-kaydır-iki kez yönteminde bir gelişme . Dizeyi M -> [r[-i:]+r[:-i]for i,r in enumerate(zip(*M))]oluşturarak ve değerlendirerek işlemi iki kez uygular.

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

Bu, görüntünün kare olduğunu ve uzunluğunun girdi olarak alınabileceğini varsayarsak, doğrudan bir dönüşümü (70 bayt) atar.

lambda M,n:[[M[(2*j-i)%n][(i-j)%n]for i in range(n)]for j in range(n)]

1

ImageJ makrosu, 29 bayt

v=getPixel((x+y)%w,(2*y+x)%h)
  • Lena görüntüsünü aç
  • İşlem menüsünden Matematik / Makro ...

Bu f ^ (- 1) yapmıyor mu? Piksel değerini, verildiği koordinatlarda alır. taşımak için. Muhtemelen demek istiyorsun v=getPixel((2*y-x)%w,(x-y)%h).
Robin Koch,

@RobinKoch Teşekkürler, 2*x+y değiştirildi2*y+x
rahnema1

Ne yazdığım ne de demek istediğim bu değildi. Yaklaşımınız için ters dönüşüme ihtiyacınız var. İçinf(x,y) = (2x+y, x+y) ters dönüşüm ile açıklanmaktadır f^(-1) = (x-y, 2y-x). (Diğer yorumum yanlıştı.) Kodunuz çok zayıf v=getPixel((x-y)%w,(2*y-x)%h).
Robin Koch,


@RobinKoch ImageJ programını indirebilir ve her iki formülü test edebilirsiniz
rahnema1

1

Java, 160

golfed:

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

Ungolfed:

  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;
  }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.