โปรแกรมหมุนได้เอง 90 °


20

บทนำ

เขียนโปรแกรมที่สมบูรณ์ซึ่งหมุนบล็อกสี่เหลี่ยมของอักขระ ASCII 90 องศาตามเข็มนาฬิกา เมื่อโปรแกรมหมุนตามเข็มนาฬิกา 90 องศามันจะหมุนบล็อกของอักขระ ASCII 90 ทวนเข็มนาฬิกา

กฎระเบียบ

  • คุณหลายคนไม่ได้ใช้บิวด์อินที่หมุนหรือเปลี่ยนเมทริกซ์ ตัวอย่างเช่นใน MATLAB / Octave rot90และผู้ประกอบการขนย้าย'ไม่ได้รับอนุญาต
  • คุณต้องเขียนโปรแกรมทั้งหมดที่ใช้ STDIN และ STDOUT หรือโปรแกรมที่ใกล้เคียงที่สุด
  • โปรแกรมของคุณจะต้องเป็นสี่เหลี่ยมและสมมติว่าอินพุตนั้นเป็นสี่เหลี่ยมเช่นกัน
  • อินพุตและเอาต์พุตเป็นสตริงที่คั่นด้วยบรรทัดใหม่และจะไม่มีการขึ้นบรรทัดใหม่

เมื่อรันด้วยซอร์สโค้ดของมันเป็นอินพุตโปรแกรมของคุณจะต้องหมุนตัวเองตามเข็มนาฬิกา 90 องศา ผลลัพธ์จะต้องเป็นโปรแกรมที่สองในภาษาเดียวกันที่หมุนอินพุต 90 องศาทวนเข็มนาฬิกา เมื่อโปรแกรมที่หมุนได้รับซอร์สโค้ดของมันเป็นอินพุทก็ควรเอาท์พุทซอร์สโค้ดของโปรแกรมต้นฉบับ

หมายเหตุ:ทั้งสองโปรแกรมจะต้องทำงานกับอินพุตใด ๆไม่ใช่แค่ซอร์สโค้ดของตัวเองดังนั้นจึงไม่อนุญาตให้ใช้หนึ่งอักขระ quine

ตัวอย่าง

สมมติว่าโปรแกรมต่อไปนี้เป็นโปรแกรมที่ถูกต้องซึ่งจะหมุนอินพุต 90 องศาในภาษาสมมุติฐาน ExampleLang

^f a2% 3
lk (^_^&
       v
D8 $4  /

เมื่อรันด้วยตัวเองเป็นอินพุทมันจะส่งออกโปรแกรมที่ถูกต้องอีกอันที่หมุนอินพุททวนเข็มนาฬิกา:

D l^
8 kf

$ (a
4 ^2
  _%
  ^ 
/v&3

โปรแกรมที่สองนี้เมื่อกำหนดให้กับตัวเองเป็นอินพุตเอาต์พุตโปรแกรมต้นฉบับ โปรดทราบว่าบรรทัดว่างควรมีช่องว่างสี่ช่องและมีช่องว่างต่อท้ายบนบรรทัดที่สองถึงบรรทัดสุดท้ายที่ไม่สามารถแสดงผลใน markdown เพื่อชี้แจง:

$ examplelang program < program > rotProg
$ examplelang rotProg < rotProg > program1
$ diff -s program program1
Files program and program1 are identical

โปรแกรมที่สั้นที่สุดชนะ ช่องโหว่มาตรฐานถูกแบน

คำตอบ:


17

CJam, 26 25 21 ไบต์

WqN/":.+""\%"(~+N-~N*

ขอบคุณ @ MartinBüttnerสำหรับการตีกอล์ฟขนาด 4 ไบต์!

ลองใช้ออนไลน์ในล่าม CJam: โปรแกรมต้นฉบับ | โปรแกรมหมุน

นี่คือโปรแกรมที่หมุนแล้ว:

W
q
N
/
"
:
.
+
"
"
\
%
"
(
~
+
N
-
~
N
*

ความคิด

เราสามารถหมุนอินพุทหนึ่งรอบหมุนตามเข็มนาฬิกาโดยแยกมันที่ linefeeds ย้อนกลับลำดับของแถวที่เกิดขึ้นการสลับแถวกับคอลัมน์และสุดท้ายเข้าร่วมแถวโดยคั่นด้วย linefeeds

ในทำนองเดียวกันเราสามารถหมุนทวนเข็มนาฬิกาโดยการเปลี่ยนตำแหน่งก่อนจากนั้นกลับแถว

เนื่องจากการขนย้ายในตัวzเป็นสิ่งต้องห้ามเราจึงสามารถใช้:.+(ลดขนาดด้วยตัวอักษรแบบเวกเตอร์หรือการต่ออักขระสตริง) เพื่อให้ได้ผลเช่นเดียวกัน

:.+เป็นเพียงส่วนหนึ่งของซอร์สโค้ดที่ไม่สามารถทำลายได้ เรากดสตริง"W%"และ":.+"ย้อนกลับอย่างมีเงื่อนไขหากสตริงที่สองมี linefeed เรียงต่อกันลบ linefeeds ทั้งหมดและประเมินผลลัพธ์

รหัส

W     e# Push -1.
qN/   e# Read all input at split it at linefeeds.
":.+" e# Push a string that, when evaluated, transposes rows and columns.
      e# As explained in the previous section, this does NOT use a built-in
      e# for matrix transposition.
"\%"  e# Push a string that, when evaluated, reverses the rows.
(~    e# Shift out the first character and evaluate it.
      e# For the original code, this evaluates '\', swapping the strings on
      e# the stack. For the rotated code, this evaluates `\n', doing nothing.
+N-   e# Concatenate and remove linefeeds.
      e# The stack now contains:   -1 input "%:.+"   or   -1 input ":.+\%"
~     e# Evaluate the string on top of the stack.
N*    e# Join the resulting array, separating by linefeeds.

สั้นแค่ไหน? แม้ว่าอย่างจริงจังทำไมไม่:.+สามารถแยกหลายบรรทัด?
intrepidcoder

1
@intrepidcoder ด้วยเหตุผลทางไวยากรณ์ ความหมายของทั้งสอง:และ.ขึ้นอยู่กับตัวละครหลังจากพวกเขาและ linefeeds ไม่ถูกต้องหลังจากทั้งสองอย่างใดอย่างหนึ่ง (และแม้ว่าพวกเขาจะเป็นที่จะเปลี่ยนความหมายของโปรแกรม)
Martin Ender

6

C (gcc) , 1420 1399 463 ไบต์

อ่า ... ความสุขของความยาวที่ไม่ จำกัด !

ถือว่าและsizeof(char*) == sizeof(int)sizeof(char**) <= 16

แนวทางใหม่

char**L,*r;n,i//j=>]l n}q(( 
,j,q;R(l){for(//,l)l, +;;rr 
r=l=0;(j=     //i=)[r +))oa 
getchar())>10;//,r(r( *l(fh}
r[l++]=j,r[l]=//n(r,c=6=R)c;
0)r=realloc(r,//;rajoL1q()t)
l+2);l&&R((L= //roh=l(,,r"u)
realloc(L,++n*//*fc]l(Lro"p]
16))[n-1]=r,q=//,{t+aR(=f(;q
l);}main(){for//L)e+e&c]{sn[
(R();i<q;i++, //*lglr&o1)t<]
puts(""))for(j//*(=[=ll-(uj+
=n;j--;putchar//rRjrr;lnnp;+
(L[j][i]));}  //a;(;))a[i;0j
////////////////hq;002e)a-=[
////////////////c,01=+r)m-jL

ลองออนไลน์!

การส่งออกของดังกล่าวข้างต้น

วิธีการแก้ปัญหาเป็นเรื่องง่ายที่น่าอายในที่สุด คุณสร้างโปรแกรม A ที่หมุนตามเข็มนาฬิกาและหนึ่งโปรแกรม B ที่หมุนทวนเข็มนาฬิกา:

A

char**L,*r;n,i,j,q;R(l){for(r=l=0;(j=getchar())>10;r[l++]=j,r[l]=0)r=realloc(r,l+2);l&&R((L=realloc(L,16*++n))[n-1]=r,q=l);}main(){for(R();i<q;i++,puts(""))for(j=n;j--;)putchar(L[j][i]);}

B

char**L,*r;n,i,j,q;R(l){for(r=l=0;(j=getchar())>10;r[l++]=j,r[l]=0)r=realloc(r,l+2);l&&R((L=realloc(L,16*++n))[n-1]=r,q=l);}main(){for(R();q--;puts(""))for(j=0;j<n;j++)putchar(L[j][q]);}

สร้างสัดส่วนที่สมเหตุสมผลและ จำกัด ขอบเขต A จากนั้นใส่กรอบความคิดเห็นไว้รอบ ๆ :

char**L,*r;n,i//
,j,q;R(l){for(//
r=l=0;(j=     //
getchar())>10;//
r[l++]=j,r[l]=//
0)r=realloc(r,//
l+2);l&&R((L= //
realloc(L,++n*//
16))[n-1]=r,q=//
l);}main(){for//
(R();i<q;i++, //
puts(""))for(j//
=n;j--;putchar//
(L[j][i]));}  //
////////////////
////////////////

จำกัด โปรแกรม B ให้เป็นสี่เหลี่ยมจัตุรัสซึ่งมีความกว้างเท่ากันสำหรับ A บวกสอง (สำหรับบรรทัดความคิดเห็นเพิ่มเติมที่ขอบด้านล่าง) หมุน CCW แล้วตบมันไปทางด้านขวาของโปรแกรม A แล้วคุณจะได้คำตอบข้างต้น

วิธีการแบบเก่า

 /*                                       r                               c                                                         c                                                  r               
r                                         a                               o                         n                               o                          s                       a               
a                          r              h                               l                         i       r                       l             r      -     t        r  =    +      h         q     
h                          o              c        0     +                l                         a       o             +         l       6     o      -     u    "   o  j<   +      c  */           
char**L,*s,*r;n,i,q;R(l,c){for(r=l=0;(c=getchar())>10;r[l++]=c,r[l]=0)r=realloc(r,l+2);q=l?l:q;l=r;}main(j){for(;s=R();L[n++]=s)L=realloc(L,16*n);for(;i<q;i++,puts(""))for(j=n;j--;)putchar(L[j][i]);}
 ///                        //          //e////     /     /             //e////                      ///     //            /      //e////    /     //  //  //// ///  /   // ;/   /// //u////      /    
 ///                        //          //g////     /     /             //r////                      ///     //            /      //r////    /     //  //  //// ///  /   // 0/   /// //p////      /    

ลองออนไลน์!

การส่งออกของดังกล่าวข้างต้น

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