Programa de auto rotación de 90 °

20

Introducción

Escriba un programa completo que gire un bloque rectangular de caracteres ASCII 90 grados en el sentido de las agujas del reloj. Cuando el programa en sí mismo gira 90 grados en el sentido de las agujas del reloj, gira un bloque de caracteres ASCII 90 en sentido antihorario.

Reglas

  • Es posible que no use incorporados que roten o transpongan matrices. Por ejemplo, en MATLAB / Octave rot90y el operador de transposición 'no están permitidos.
  • Debe escribir un programa completo que use STDIN y STDOUT o el equivalente más cercano.
  • Su programa debe ser rectangular y asumir que la entrada también es rectangular.
  • La entrada y la salida son cadenas separadas por una nueva línea y no tendrán nuevas líneas finales.

Cuando se ejecuta con su código fuente como entrada, su programa debe girar 90 grados en el sentido de las agujas del reloj. La salida debe ser un segundo programa en el mismo idioma que gira su entrada 90 grados en sentido antihorario. Cuando el programa girado recibe su código fuente como entrada, debe generar el código fuente del programa original.

Nota: Ambos programas deben funcionar para cualquier entrada, no solo para su propio código fuente, por lo que no se permite una quine de un carácter.

Ejemplo

Digamos que el siguiente es un programa válido que gira su entrada 90 grados en un lenguaje hipotético ExampleLang.

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

Cuando se ejecuta consigo mismo como entrada, genera otro programa válido que gira su entrada en sentido antihorario:

D l^
8 kf

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

Este segundo programa, cuando se da a sí mismo como entrada, emite el programa original. Tenga en cuenta que la línea en blanco debe tener cuatro espacios y hay un espacio final en la penúltima línea que no se puede representar en markdown. Para aclarar:

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

El programa más corto gana. Las lagunas estándar están prohibidas.

codificador intrépido
fuente

Respuestas:

17

CJam, 26 25 21 bytes

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

¡Gracias a @ MartinBüttner por jugar golf 4 bytes!

Pruébelo en línea en el intérprete de CJam: programa original | programa rotado

Este es el programa rotado:

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

Idea

Podemos rotar la entrada un cuarto de vuelta en el sentido de las agujas del reloj dividiéndola en avances de línea, invirtiendo el orden de las filas resultantes, transponiendo filas con columnas y finalmente uniendo las filas, separadas por avances de línea.

Del mismo modo, podemos rotar en sentido antihorario transponiendo primero, luego invirtiendo las filas.

Dado que la transposición incorporada zestá prohibida, podemos usar :.+(reducir por concatenación de caracteres vectorizados o caracteres de cadena) para lograr el mismo efecto.

:.+es la única parte del código fuente que no se puede dividir. Empujamos las cadenas "W%"y las invertimos ":.+"condicionalmente si la segunda cadena contiene un salto de línea, concatenamos, eliminamos todos los saltos de línea y evaluamos el resultado.

Código

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
fuente
¿Cómo es esto tan corto? En serio, ¿por qué no se :.+puede dividir en varias líneas?
intrepidcoder
1
@intrepidcoder Por razones sintácticas. El significado de ambos :y .depende del carácter después de ellos, y saltos de línea no son válidos después de uno de los (e incluso si lo fueran, que cambiaría el significado del programa).
Martin Ender
6

C (gcc) , 1420 1399 463 bytes

Ah ... la alegría de las cuerdas de longitud indeterminada!

Asume sizeof(char*) == sizeof(int)y sizeof(char**) <= 16.

El nuevo enfoque

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

Pruébalo en línea!

Salida de lo anterior

La solución fue vergonzosamente fácil al final. Haces un programa A que gira las cosas en sentido horario, y un programa B que gira en sentido antihorario:

UN

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

si

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

Haga un rectángulo de proporciones razonables y limite A a eso, y ponga protectores de comentarios a su alrededor:

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

Limite el programa B a un cuadrado que tenga el mismo ancho que el de A más dos (para las líneas adicionales de comentarios en el borde inferior), gírelo en sentido antihorario y golpéelo a la derecha del programa A y obtendrá la solución anterior.

El viejo enfoque

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

Pruébalo en línea!

Salida de lo anterior

gastropner
fuente