90 ° selbstdrehendes Programm

20

Einführung

Schreiben Sie ein vollständiges Programm, das einen rechteckigen Block mit ASCII-Zeichen um 90 Grad im Uhrzeigersinn dreht. Wenn das Programm selbst um 90 Grad im Uhrzeigersinn gedreht wird, wird ein Block mit ASCII-Zeichen um 90 Grad gegen den Uhrzeigersinn gedreht.

Regeln

  • Sie verwenden häufig keine integrierten Funktionen, mit denen Sie Matrizen drehen oder transponieren können. Beispielsweise sind in MATLAB / Octave rot90und dem Transponierungsoperator 'nicht zulässig.
  • Sie müssen ein vollständiges Programm schreiben, das STDIN und STDOUT oder das nächste Äquivalent verwendet.
  • Ihr Programm muss rechteckig sein und davon ausgehen, dass die Eingabe ebenfalls rechteckig ist.
  • Die Eingabe und Ausgabe sind durch Zeilenumbrüche getrennte Zeichenfolgen und enthalten keine nachgestellten Zeilenumbrüche.

Wenn Ihr Programm mit dem Quellcode als Eingabe ausgeführt wird, muss es sich um 90 Grad im Uhrzeigersinn drehen. Die Ausgabe muss ein zweites Programm in derselben Sprache sein, das seine Eingabe um 90 Grad gegen den Uhrzeigersinn dreht. Wenn das gedrehte Programm seinen Quellcode als Eingabe erhält, sollte er den Quellcode des ursprünglichen Programms ausgeben.

Hinweis: Beide Programme müssen für jede Eingabe funktionieren , nicht nur für ihren eigenen Quellcode. Daher ist ein aus einem Zeichen bestehender Quine nicht zulässig.

Beispiel

Angenommen, das Folgende ist ein gültiges Programm, das seine Eingabe in einer hypothetischen Sprache um 90 Grad dreht.

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

Wenn es mit sich selbst als Eingabe ausgeführt wird, gibt es ein anderes gültiges Programm aus, das seine Eingabe gegen den Uhrzeigersinn dreht:

D l^
8 kf

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

Dieses zweite Programm gibt, wenn es sich selbst als Eingabe gegeben wird, das ursprüngliche Programm aus. Beachten Sie, dass die leere Zeile vier Leerzeichen enthalten sollte und in der vorletzten Zeile ein Leerzeichen nachgestellt ist, das beim Abzeichnen nicht gerendert werden kann. Zu klären:

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

Kürzeste Sendung gewinnt. Standardlücken sind verboten.

unerschrockener Kodierer
quelle

Antworten:

17

CJam, 26 25 21 Bytes

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

Danke an @ MartinBüttner für das Golfen mit 4 Bytes!

Probieren Sie es online im CJam-Interpreter aus: Originalprogramm | Programm gedreht

Dies ist das gedrehte Programm:

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

Idee

Wir können die Eingabe um eine Vierteldrehung im Uhrzeigersinn drehen, indem wir sie in Zeilenvorschübe aufteilen, die Reihenfolge der resultierenden Zeilen umkehren, Zeilen mit Spalten transponieren und schließlich die durch Zeilenvorschübe getrennten Zeilen verbinden.

Ebenso können wir gegen den Uhrzeigersinn drehen, indem wir zuerst transponieren und dann die Reihen umkehren.

Da die eingebaute Transposition zverboten ist, können wir :.+(durch Verketten von vektorisierten Zeichen oder Zeichenketten) den gleichen Effekt erzielen.

:.+ist der einzige Teil des Quellcodes, der nicht aufgeteilt werden kann. Wir verschieben die Zeichenfolgen "W%"und ":.+"kehren sie unter bestimmten Bedingungen um, wenn die zweite Zeichenfolge einen Zeilenvorschub enthält. Verketten Sie, entfernen Sie alle Zeilenvorschübe und werten Sie das Ergebnis aus.

Code

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.
Dennis
quelle
Wie ist das so kurz? Im Ernst, warum kann nicht :.+über mehrere Zeilen aufgeteilt werden?
intrepidcoder
1
@intrepidcoder Aus syntaktischen Gründen. Die Bedeutung von beiden :und .hängt von dem Zeichen nach ihnen ab, und Zeilenvorschübe sind nach beiden nicht gültig (und selbst wenn dies der Fall wäre, würde dies die Bedeutung des Programms ändern).
Martin Ender
6

C (gcc) , 1420 1399 463 Bytes

Ah ... die Freude an Saiten unbestimmter Länge!

Angenommen, sizeof(char*) == sizeof(int)und sizeof(char**) <= 16.

Der neue Ansatz

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

Probieren Sie es online!

Ausgabe der oben genannten

Die Lösung war am Ende peinlich einfach. Sie erstellen ein Programm A, das sich im Uhrzeigersinn dreht, und ein Programm B, das sich gegen den Uhrzeigersinn dreht:

EIN

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

Bilden Sie ein Rechteck mit vernünftigen Proportionen und beschränken Sie A darauf.

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]));}  //
////////////////
////////////////

Beschränken Sie Programm B auf ein Quadrat mit derselben Breite wie das für A plus zwei (für die zusätzlichen Kommentarzeilen am unteren Rand), drehen Sie es im Uhrzeigersinn und klopfen Sie es rechts neben Programm A, und Sie erhalten die obige Lösung.

Der alte Ansatz

 /*                                       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////      /    

Probieren Sie es online!

Ausgabe der oben genannten

Gastropner
quelle