Hilbertify รูปภาพ


28

ผมชอบฮิลแบร์ต Curve


งานของคุณสำหรับความท้าทายนี้คือการถ่ายภาพ (เป็นรูปสี่เหลี่ยมจัตุรัสโดยที่ทุกด้านมีกำลังสองพิกเซลกว้าง) และคลี่คลายมันทีละบรรทัดในรูปแบบซิกแซกและนำกลับไปเป็นเส้นโค้งหลอก - ฮิลแบร์ต .

คลี่คลาย

หากต้องการคลี่คลายคุณจะต้องเริ่มต้นด้วยพิกเซลที่มุมซ้ายบนและเดินทางไปทางขวาจนกว่าคุณจะถึงขอบของรูปภาพ เมื่อคุณกดที่ขอบของรูปภาพคุณจะเลื่อนลงไปที่แถวถัดไปและเริ่มเดินทางไปทางซ้ายจนกว่าคุณจะตีที่ขอบอีกครั้ง คุณจะยังคงคลี่คลายแถวต่อแถวสลับทิศทางในแต่ละครั้งเพื่อให้คุณได้รับหนึ่งโค้งอย่างต่อเนื่อง นี่ควรเป็นเกมงูที่เล่นกันดี

ผลลัพธ์ของการคลายควรเป็นลำดับของพิกเซลที่รวมทุกพิกเซลในครั้งเดียว

Reraveling

เมื่อคุณมีการสั่งซื้อพิกเซลคุณจะจัดเรียงใหม่บนผืนผ้าใบที่มีขนาดเท่ากันใหม่ตามเส้นทางของเส้นโค้งหลอก - ฮิลแบร์ต สำหรับ2**nภาพสี่เหลี่ยมจัตุรัสคุณควรใช้การวนซ้ำของเส้นโค้งหลอก - ฮิลแบร์ต แต่ละพิกเซลจะถูกวางในจุดเดียวบนผืนผ้าใบใหม่ คุณควรจัดภาพใหม่เพื่อให้จุดเริ่มต้นที่มุมบนซ้าย (จุดเริ่มต้นของเส้นโค้งงูของเรา) อยู่ที่นั่นและจุดที่มุมล่างขวา (จุดสิ้นสุดของเส้นโค้งงูของเรา) จะถูกวางไว้ที่มุมขวาบน

I / O

โปรแกรมหรือฟังก์ชั่นของคุณควรใช้ภาพของข้อ จำกัด ที่ระบุผ่านวิธีการมาตรฐานและส่งออกภาพอื่นผ่านวิธีการมาตรฐาน

เกณฑ์การให้คะแนน

นี่เป็นโปรแกรมมีจำนวนไบต์น้อยที่สุดเป็นผู้ชนะ

ตัวอย่าง

อินพุต

Mondrian

เอาท์พุต

เอาท์พุท 1


อินพุต

Rothko

เอาท์พุต

เอาท์พุท 2


อินพุต

กวน

เอาท์พุต

สิงโต


ฉันขอแนะนำให้ทดสอบภาพสีขาวหรือสีทึบเพื่อให้แน่ใจว่าคุณจะไม่พลาดพิกเซล

อย่าลังเลที่จะรวมผลลัพธ์ของคุณเองในคำตอบของคุณ!


มันโอเคที่จะใช้อาร์เรย์ของค่า RGB แทนภาพเป็นอินพุทหรือไม่? เอาท์พุทเกี่ยวกับอะไร
JungHwan Min

@JHM ไม่คุณไม่สามารถ คุณสามารถเลือกรูปแบบภาพที่ต้องการได้ดังนั้นหากภาษาของคุณไม่มีการรองรับภาพในตัวคุณสามารถใช้ไฟล์. ppp ที่ไม่บีบอัดซึ่งคล้ายกับอาร์เรย์ของค่า RGB
ข้าวสาลีตัวช่วยสร้าง

คำตอบ:


8

Mathematica, 286 273 ไบต์

Image[Array[1,{l=Length@#,l}]~ReplacePart~Thread[#&@@@Split[#&@@@FoldList[Switch[#2,"-",#{1,I},"+",#/{1,I},"F",#+{ReIm@Last@#,0},_,#]&,{{1,1},I},Characters@Nest[StringReplace@{"L"->"+RF-LFL-FR+","R"->"-LF+RFR+FL-"},"L",Log2@l]]]->Join@@MapAt[Reverse,#,2;;;;2]]]&@*ImageData

วุ้ย ท้าทาย แต่สนุก!

คำอธิบาย

ImageData

แปลงเป็นImageอาร์เรย์ของค่า RGB

Array[1,{l=Length@#,l}]

สร้างอาร์เรย์lโดยlใช้หัว1โดยที่lความยาวของอินพุต (เช่นความกว้างของภาพ)

อัตราผลตอบแทนนี้{{1[1, 1], 1[1, 2], ..., 1[1, L]}, {1[2, 1], ..., 1[2, L]}, ..., {1[L, 1], ..., 1[L, L]}}( lเขียนเป็นตัวพิมพ์ใหญ่เพื่อลดความสับสน)

StringReplace@{"L"->"+RF-LFL-FR+","R"->"-LF+RFR+FL-"}

StringReplaceฟังก์ชั่นที่มาแทนที่ทุก"L"ที่มี"+RF-LFL-FR+"และ"R"มี"-LF+RFR+FL-"

Nest[ ... ,"L",Log2@l]

ใช้StringReplaceฟังก์ชั่นไปString "L", Log2[l]ครั้ง

Characters

แปลงผลลัพธ์Stringเป็นListอักขระ

Switch[#2,"-",#{1,I},"+",#/{1,I},"F",#+{ReIm@Last@#,0},_,#]&

ฟังก์ชั่นที่ไม่มีชื่อที่:

  • ถ้าใส่สองคือคูณองค์ประกอบที่สองของการป้อนข้อมูลเป็นครั้งแรกโดย"-"I
  • ถ้าใส่สองคือแบ่งองค์ประกอบที่สองของการป้อนข้อมูลเป็นครั้งแรกโดย"+"I
  • หากอินพุตที่สองคือ"F"เพิ่มอินพุตแรกโดยReIm(แยกส่วนจริงและจินตภาพของอินพุต) ของอินพุตที่สอง
FoldList [... , {{1,1}, I}, ... ]

เริ่มต้นด้วยการ{{1,1},I}ใช้ฟังก์ชันที่ไม่มีชื่อข้างต้นรวมกันโดยใช้องค์ประกอบListของอักขระแต่ละตัวเป็นอินพุตที่สอง รหัสนี้ให้ผลลัพธ์ของการวนซ้ำทั้งหมด

#&@@@Split[#&@@@ ... ]

กำจัดองค์ประกอบที่สองของแต่ละรายการListและลบรายการที่ซ้ำกัน (ขั้นตอนจนถึงจุดนี้สร้างListพิกัดของเส้นโค้ง Hilbert)

Join@@MapAt[Reverse,#,2;;;;2]

คลี่คลายอาร์เรย์อินพุต RGB (ย้อนกลับทุกแถวและแบนราบ)

Thread[ ... -> ... ]

สร้างRuleวัตถุเช่นองค์ประกอบแรกในอินพุตแรก (พิกัดของเส้นโค้งของฮิลแบร์ต) ถูกจับคู่กับองค์ประกอบแรกของอินพุตที่สอง (รูปภาพที่ไม่มีการย่อ) องค์ประกอบที่สองที่มีอินพุตที่สองและอื่น ๆ

... ~ReplacePart~ ...

ใช้การแทนที่เหล่านั้นRuleกับArrayขั้นตอนที่สอง

Image

แปลงไปยังอาร์เรย์ของค่า RGB Imageเข้าไปในนั้น

ตัวอย่างเข้า / ออก

การป้อนข้อมูล:

กรณีทดสอบ 1

เอาท์พุท:

เอาท์พุต


การป้อนข้อมูล:

Edward และ Alphonse Elric จากนักเล่นแร่แปรธาตุ Fullmetal

เอาท์พุท:

วัด

ฟังก์ชันผกผัน ( 266 253 ไบต์)

Image[MapAt[Reverse,Extract[#,#&@@@Split[#&@@@FoldList[Switch[#2,"-",#{1,I},"+",#/{1,I},"F",#+{ReIm@Last@b,0},_,#]&,{{1,1},I},Characters@Nest[StringReplace@{"L"->"+RF-LFL-FR+","R"->"-LF+RFR+FL-"},"L",Log2[l=Length@#]]]]]~Partition~l,2;;;;2]]&@*ImageData

5

อ็อกเทฟ 234 ไบต์

I=imread(input(''));w=rows(I);X=[0,3;1,2];for k=2:log2(w);n=numel(X);X=[X',rot90(X',2)+3*n;X+n,X+2*n];end;for k = 1:3;I(2:2:end,:,k)=fliplr(I(2:2:end,:,k));end[~,S]=sort(X(:));I(S+(0:w^2:2*w^2))=permute(I,[2 1 3]);imwrite(I,input(''))

ชื่อไฟล์ของภาพที่นำเข้าและส่งออกควรจะให้รูปแบบอินพุตมาตรฐาน ขนาดของรหัสโดยไม่ต้องเข้า / ส่งออกเป็น194 ไบต์
คำอธิบาย:

รูปแบบพื้นฐานของดัชนีคือ:

X =
  0 3
  1 2

ในแต่ละการวนซ้ำ 4 สำเนาจากผลลัพธ์ของการวนซ้ำก่อนหน้านี้และการแปลงบางส่วนที่นำไปใช้กับสำเนาแต่ละชุดจากนั้นบล็อกทั้งหมดที่ต่อกันจะกลายเป็นผลลัพธ์ปัจจุบัน

X =[0,3;1,2];
for k = 2:log2(s)
    n=numel(X);
    X = [X',rot90(X',2)+3*n;X+n,X+2*n];
end

ดังนั้นเราจึงมี:

block(1,1): X' 
block(1,2): rot90(X',2)+3*n 
block(2,1): X+n
block(2,2): X+2*n

0    1  | 14   15
3    2  | 13   12
--------|--------
4    7  |  8   11
5    6  |  9   10

ดัชนีฮิลแบร์ตที่เรียงลำดับและดัชนีขององค์ประกอบเรียงกลับมา:

[~,S]=sort(X(:));

การนำการประยุกต์ใช้การพลิกแถวแบบสม่ำเสมอทั้งหมด:

for k = 1:3
    I(2:2:end,:,k) = fliplr(I(2:2:end,:,k));
end

ใช้การส่งเสียงซ้ำ:
-S ซ้ำสำหรับแต่ละแชนแนล
-permutation ถูกนำมาใช้ตั้งแต่ในคอลัมน์ข้อมูล Octave ที่จัดเรียงอย่างชาญฉลาด

I(S+(0:w^2:2*w^2))=permute(I,[2 1 3]);

ภาพตัวอย่าง:

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่

ป้อนคำอธิบายรูปภาพที่นี่


คุณสามารถเลือกให้โปรแกรมทำงานเป็นฟังก์ชั่นหากคุณต้องการหลีกเลี่ยงการใช้ I / O
ข้าวสาลีตัวช่วยสร้าง

คำหลักฟังก์ชั่น + สิ้นสุดกินไบต์มากขึ้น!
rahnema1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.