แผนที่แมวอาร์โนลด์


21

ท้าทาย

ได้รับภาพแรสเตอร์สี * มีความกว้างและความสูงเดียวกันการส่งออกภาพเปลี่ยนภายใต้แผนที่แมวของ Arnold (* รายละเอียดดูด้านล่าง)

คำนิยาม

ด้วยขนาดของภาพที่Nเราคิดว่าพิกัดของพิกเซลที่จะได้รับเป็นตัวเลขระหว่างและ0N-1

แผนที่แมวของอาร์โนลด์นั้นถูกกำหนดไว้ดังนี้:

พิกเซลที่พิกัดถูกย้ายไปยัง[x,y][(2*x + y) mod N, (x + y) mod N]

นี้คืออะไร แต่เปลี่ยนเชิงเส้นในพรู: สีเหลือง, mod Nสีม่วงสีเขียวและเป็นส่วนหนึ่งได้รับการแมปกลับไปยังตารางเริ่มต้นเนื่องจากการ

การสร้างภาพ

แผนที่นี้ (เรียกมันว่าf) มีคุณสมบัติดังต่อไปนี้:

  • มันเป็นbijectiveนั่นหมายความว่าพลิกกลับ: [[2,1],[1,1]]มันเป็นการเปลี่ยนแปลงเชิงเส้นที่มีเมทริกซ์ เนื่องจากมันมีดีเทอร์มิแนนต์1และมีเฉพาะจำนวนเต็มอินเวิร์สจึงมีเพียงรายการจำนวนเต็มและกำหนดโดย[[1,-1],[-1,2]]นี่หมายความว่ามันเป็น bijective บนพิกัดจำนวนเต็มด้วย

  • มันเป็นองค์ประกอบของแรงบิดของกลุ่มแผนที่ bijective ของN x Nภาพซึ่งหมายความว่าถ้าคุณใช้มันอย่างเพียงพอหลายครั้งคุณจะได้ภาพต้นฉบับกลับมา: f(f(...f(x)...)) = xจำนวนครั้งที่แผนที่นำไปใช้กับผลลัพธ์ของตัวเองในการรับประกันตัวตนจะน้อยกว่า 3*Nหรือเท่ากับ ในรายการต่อไปนี้คุณสามารถเห็นภาพของแมวหลังจากจำนวนแอพพลิเคชั่นซ้ำของแผนที่แมวของอาร์โนลด์ที่กำหนดและภาพเคลื่อนไหวของแอปพลิเคชันซ้ำ ๆ ที่ดูเหมือน:

แอปพลิเคชั่นซ้ำหลายครั้ง

รายละเอียด

  • โปรแกรมของคุณไม่จำเป็นต้องจัดการกับภาพ แต่จำเป็นต้องใช้ 2D-arrays / matrices, string หรือ 2D-structure ที่คล้ายกันเช่นกัน

  • มันไม่สำคัญว่า(0,0)จุดของคุณจะอยู่ทางซ้ายล่างหรือบนซ้าย (หรือในมุมอื่น ๆ หากสะดวกกว่าในภาษาของคุณ) โปรดระบุแบบแผนที่คุณใช้ในการส่งของคุณ

Testcases

ในรูปแบบเมทริกซ์ ( [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
แย่ Lena ฉันหวังว่าคุณจะทำซ้ำนานพอ
หลุยส์เมนโด

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.

การตัดเมทริกซ์นี้ในทิศทางเดียวแล้วอีกอัน


อัลกอริทึมที่ยอดเยี่ยม!
Greg Martin

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
    

    บอกว่าตัวอย่างเช่นต้นฉบับ5ที่x = 2, y = 1 ไปที่x = 3, y = 2 การดำเนินการนี้เรียกว่าการทำดัชนีอ้างอิง : ใช้เมทริกซ์การทำดัชนีเพื่อบอกองค์ประกอบที่จะเลือกจากเมทริกซ์ดั้งเดิม นี่คือ functon )ซึ่งรับสองอินพุต (ในการกำหนดค่าเริ่มต้น)

  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

Mathematica ขนาด 44 ไบต์

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

พอร์ตของลินน์อัลกอริทึมที่ยอดเยี่ยม มีตัวละครที่มองไม่เห็น 3 ไบต์ U + F3C7 ในการเข้ารหัส UTF-8 ก่อนที่สุดท้ายคือ]; Mathematica แสดงว่าเป็นตัวยกTและใช้การแปลงของเมทริกซ์

Mathematica, 54 ไบต์

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

ฟังก์ชั่นที่ไม่มีชื่อใช้สองอาร์กิวเมนต์จำนวนเต็มบวก#และอาร์เรย์ 2 มิติ#2ของมิติ#x #และส่งกลับอาร์เรย์ 2 มิติที่มีรูปร่างคล้ายกัน ในกรณีทดสอบที่กำหนดจุดที่มีพิกัด {0,0} อยู่ที่มุมบนซ้ายและแกน x เป็นแนวนอน การใช้งานที่ตรงไปตรงมาโดยใช้ค่าผกผันที่[[1,-1],[-1,2]]กล่าวถึงในคำถามโดยมี-1ค่าพิกัดแรกที่อธิบายถึงความจริงที่ว่าอาร์เรย์มีการจัดทำดัชนี 1 ครั้งใน Mathematica หากเราไม่ได้รับอนุญาตให้ใช้มิติของเมทริกซ์เป็นอาร์กิวเมนต์เพิ่มเติมวิธีการแก้ปัญหานี้จะกลายเป็นอีกเก้าไบต์อีกต่อไป (แทนที่อันแรก#ไม่ใช่ - #2ด้วย - a=Length@#และทุก#วินาทีถัดมาด้วยas)


แดงเอาชนะฉันไปหามัน
JungHwan Min

3

Python 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 อิง - บรรทัดที่ 3 หมุนเป็น 2 ครั้งทางด้านขวา)
กระบวนการนี้ทำไปที่อินพุท 2 ครั้ง

+4 ไบต์ที่จะทำการแปลง N ครั้ง

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

2

Haskell, 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

Python ขนาด 69 ไบต์

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

การปรับปรุงในวิธีการ transpose และกะครั้งที่สองของร็อด ใช้การดำเนินการ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)
  • เปิดภาพ Lena
  • จากเมนูกระบวนการเลือกคณิตศาสตร์ / มาโคร ...

สิ่งนี้ไม่ทำงาน f ^ (- 1) หรือไม่ มันจะได้รับค่าพิกเซลที่พิกัดที่มันถูกระงับเพื่อย้ายไป v=getPixel((2*y-x)%w,(x-y)%h)คุณอาจหมายถึง
Robin Koch

@RobinKoch ขอบคุณ2*x+yเปลี่ยนเป็น2*y+x
rahnema1

นั่นไม่ใช่สิ่งที่ฉันเขียนหรือสิ่งที่ฉันหมายถึง คุณต้องการการแปลงผกผันสำหรับวิธีการของคุณ สำหรับการนี้การเปลี่ยนแปลงผกผันอธิบายโดยf(x,y) = (2x+y, x+y) f^(-1) = (x-y, 2y-x)(ความคิดเห็นอื่น ๆ ของฉันผิด.) ดังนั้นรหัสของคุณ shold v=getPixel((x-y)%w,(2*y-x)%h)เป็น
Robin Koch

ฉันทดสอบสูตรแล้วและผลลัพธ์เหมือนกับภาพ Lena ในคำถาม
rahnema1

@RobinKoch คุณสามารถดาวน์โหลด ImageJและทดสอบสูตรทั้งสองได้
rahnema1

1

Java, 160

แข็งแรงเล่นกอล์ฟ:

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;
  }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.