अर्नोल्ड के बिल्ली का नक्शा


21

चुनौती

एक रंग रेखापुंज छवि को देखते हुए * समान चौड़ाई और ऊंचाई के साथ, आउटपुट छवि को अर्नोल्ड के बिल्ली के नक्शे के तहत बदल दिया गया । (* विवरण नीचे देखें)

परिभाषा

छवि के आकार को देखते हुए Nहम मानते हैं कि एक पिक्सेल के निर्देशांक को बीच 0और के बीच संख्या के रूप में दिया जाता है N-1

अर्नोल्ड का बिल्ली का नक्शा तब निम्नानुसार परिभाषित किया गया है:

निर्देशांक पर एक पिक्सेल [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। निम्नलिखित में आप अर्नोल्ड के कैट मैप के पुनरावृत्त अनुप्रयोगों की संख्या के बाद बिल्ली की छवि देख सकते हैं , और एक दोहराए गए आवेदन की तरह दिखने वाला एक एनीमेशन:

कई बार दोहराया गया आवेदन

विवरण

  • आपके कार्यक्रम के लिए जरूरी नहीं है कि छवियों से निपटें, लेकिन 2D-सरणियाँ / मैट्रिसेस, स्ट्रिंग्स या इसी तरह के 2D-संरचनाएं भी स्वीकार्य हैं।

  • इससे कोई फर्क नहीं पड़ता कि आपकी (0,0)बात नीचे बाईं तरफ है या ऊपर बाईं तरफ। (या किसी अन्य कोने में, यदि यह आपकी भाषा में अधिक सुविधाजनक है।) कृपया निर्दिष्ट करें कि आप अपने प्रस्तुतिकरण में किस सम्मेलन का उपयोग करते हैं।

परीक्षण के मामलों

मैट्रिक्स रूप में ( [1,2,3,4]शीर्ष पंक्ति है, 1सूचकांक है (0,0), 2सूचकांक है (1,0), 5सूचकांक है (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)):


1
बेचारी लीना। मुझे आशा है कि आप लंबे समय तक इसे बनाए रखेंगे
लुइस मेंडो

2
क्या हम छवि आकार को इनपुट के रूप में ले सकते हैं? क्या यह हमेशा चौकोर होता है?
xnor

1
हां छवि हमेशा चौकोर है, और मुझे आकार के बारे में निश्चित नहीं है, क्या इसकी अनुमति देने के खिलाफ कुछ है?
दोषपूर्ण

जवाबों:


10

जेली , 9 बाइट्स

Zṙ"JC$µ2¡

इसे ऑनलाइन आज़माएं! निर्देशांक उत्तर में हैं।

व्याख्या

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

यह आवरण एक दिशा में मैट्रिक्स को लपेटता है, फिर दूसरा।


शानदार एल्गोरिथ्म!
ग्रेग मार्टिन

7

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

चुनौती में मानचित्रण को लागू करने के लिए दो समान दृष्टिकोण हैं:

  1. एक अनुक्रमण मैट्रिक्स का निर्माण करें जो रैखिक सूचकांकों पर अर्नोल्ड के व्युत्क्रम मानचित्रण का प्रतिनिधित्व करता है , और मूल मैट्रिक्स से मूल्यों का चयन करने के लिए इसका उपयोग करता है । 4 × 4 मामले के लिए, अनुक्रमण मैट्रिक्स होगा

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

    यह बताना कि उदाहरण के लिए x = 2, y = 1 5पर मूल x = 3, y = 2 पर जाता है। इस ऑपरेशन को संदर्भ अनुक्रमण कहा जाता है : मूल मैट्रिक्स से कौन सा तत्व चुनना है, यह बताने के लिए अनुक्रमण मैट्रिक्स का उपयोग करें। यह फंक्शनलन है , जो दो इनपुट लेता है (अपने डिफ़ॉल्ट कॉन्फ़िगरेशन में)।)

  2. एक अनुक्रमण मैट्रिक्स का निर्माण करें जो रैखिक सूचकांकों पर अर्नोल्ड के प्रत्यक्ष मानचित्रण का प्रतिनिधित्व करता है , और मूल मैट्रिक्स में मान लिखने के लिए इसका उपयोग करता है । 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। इसे असाइनमेंट इंडेक्सिंग कहा जाता है : इंडेक्सिंग मैट्रिक्स, एक डेटा मैट्रिक्स और मूल मैट्रिक्स का उपयोग करें, और निर्दिष्ट सूचकांकों पर डेटा को मूल मैट्रिक्स पर लिखें। यह फ़ंक्शन है (, जो तीन इनपुट लेता है (इसके डिफ़ॉल्ट कॉन्फ़िगरेशन में)।

विधि 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

5

गणितज्ञ, 44 बाइट्स

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

लिन के शानदार एल्गोरिथ्म का एक बंदरगाह । अंतिम से पहले UTF-8 एन्कोडिंग में एक अदृश्य 3-बाइट वर्ण, U + F3C7 है ]; Mathematica इसे सुपरस्क्रिप्ट के रूप में प्रस्तुत करता है T, और यह एक मैट्रिक्स का स्थानान्तरण लेता है।

मैथेमेटिका, 54 बाइट्स

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

अनाम समारोह दो तर्क, एक सकारात्मक पूर्णांक लेने #और एक 2 डी सरणी #2आयामों की #एक्स #, और इसी तरह आकार का एक 2 डी सरणी लौटने। दिए गए परीक्षण के मामले में, निर्देशांक के साथ बिंदु {0,0} ऊपरी बाएँ में है और x- अक्ष क्षैतिज है। [[1,-1],[-1,2]]प्रश्न में उल्लिखित व्युत्क्रम का उपयोग करते हुए सीधा कार्यान्वयन , -1इस तथ्य के लिए पहली बार समन्वय करने के लिए कि सरणियों को गणितीय रूप से 1-अनुक्रमित किया गया है। यदि हमें मैट्रिक्स के आयाम को एक अतिरिक्त तर्क के रूप में लेने की अनुमति नहीं है, तो यह समाधान नौ बाइट्स लंबा हो जाता है (पहले बदलें #नहीं)#2 साथ a=Length@#- साथ और बाद के सभी को #एस के साथ बदल दें a)।


डांग, मुझे इसे हराया
जुंगह्वान मिन

3

पायथन 2, 89 82 77 73 बाइट्स

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

इनपुट सूचियों
की एक सूची है निष्पादन के अंदर स्ट्रिंग सूचियों की सूची को स्थानांतरित करती है और प्रत्येक सूची को रेखा सूचकांक (0 आधारित - 3 पंक्ति को दाईं ओर 2 बार घुमाया जाता है) से घुमाती है।
यह प्रक्रिया 2 बार इनपुट के लिए की जाती है।

+4 बाइट्स जो एन बार रूपांतरण करेगा

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

2

हास्केल, 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ऊपरी बाएँ कोने में है। यह उलटा परिवर्तन का उपयोग करता है।


1

पायथन, 69 बाइट्स

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

रॉड के पारगमन और शिफ्ट-दो बार विधि में सुधार । 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)]

1

ImageJ मैक्रो, 29 बाइट्स

v=getPixel((x+y)%w,(2*y+x)%h)
  • लीना की खुली छवि
  • प्रक्रिया मेनू से गणित / मैक्रो का चयन करें ...

क्या यह f ^ (- 1) प्रदर्शन नहीं करता है? यह निर्देशांक पर पिक्सेल मान प्राप्त करता है जिसे इसे स्थानांतरित करने के लिए दबाया जाता है। आप शायद मतलब है v=getPixel((2*y-x)%w,(x-y)%h)
रॉबिन कोच

@RobinKoch धन्यवाद, 2*x+yबदल गया2*y+x
rahnema1

यह न तो मैंने लिखा है और न ही मेरा मतलब है। आपको अपने दृष्टिकोण के लिए व्युत्क्रम परिवर्तन की आवश्यकता है। इसके लिए f(x,y) = (2x+y, x+y)उलटा परिवर्तन द्वारा वर्णित किया गया है f^(-1) = (x-y, 2y-x)। (मेरी अन्य टिप्पणी गलत थी।) तो आपका कोड शोल हो v=getPixel((x-y)%w,(2*y-x)%h)
रॉबिन कोच

मैंने अपने सूत्र का परीक्षण किया और परिणाम प्रश्न में लीना की छवि के समान है
rahnema1

@RobinKoch आप ImageJ को डाउनलोड कर सकते हैं और दोनों फॉर्मूला का परीक्षण कर सकते हैं
rahnema1

1

जावा, 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;
  }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.