Programa de rotação automática de 90 °

20

Introdução

Escreva um programa completo que gire um bloco retangular de caracteres ASCII 90 graus no sentido horário. Quando o próprio programa é girado 90 graus no sentido horário, ele gira um bloco de caracteres ASCII 90 no sentido anti-horário.

Regras

  • Muitos não usam built-ins que giram ou transpõem matrizes. Por exemplo, no MATLAB / Octave rot90e no operador de transposição 'não são permitidos.
  • Você deve escrever um programa completo que use STDIN e STDOUT ou o equivalente mais próximo.
  • Seu programa deve ser retangular e assumir que a entrada também é retangular.
  • A entrada e a saída são seqüências separadas por uma nova linha e não terão novas linhas à direita.

Quando executado com o código fonte como entrada, seu programa deve girar 90 graus no sentido horário. A saída deve ser um segundo programa no mesmo idioma que gira sua entrada 90 graus no sentido anti-horário. Quando o programa rotado recebe seu código fonte como entrada, ele deve emitir o código fonte do programa original.

Nota: Ambos os programas devem funcionar para qualquer entrada, não apenas seu próprio código-fonte; portanto, não é permitido um quine de um caractere.

Exemplo

Digamos que o seguinte seja um programa válido que gire sua entrada 90 graus em uma linguagem hipotética ExampleLang.

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

Quando executado como entrada, ele gera outro programa válido que gira sua entrada no sentido anti-horário:

D l^
8 kf

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

Este segundo programa, quando fornecido a si próprio como entrada, gera o programa original. Observe que a linha em branco deve ter quatro espaços e há um espaço à direita na penúltima à última linha que não pode ser renderizado na remarcação. Esclarecer:

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

O programa mais curto vence. As brechas padrão são proibidas.

intrepidcoder
fonte

Respostas:

17

CJam, 26 25 21 bytes

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

Obrigado a @ MartinBüttner por jogar fora 4 bytes!

Experimente online no intérprete CJam: programa original | programa girado

Este é o programa rotacionado:

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

Idéia

Podemos girar a entrada um quarto de volta no sentido horário dividindo-a em alimentações de linha, revertendo a ordem das linhas resultantes, transpondo linhas com colunas e, finalmente, juntando as linhas, separadas por alimentações de linha.

Da mesma forma, podemos girar no sentido anti-horário, transpondo primeiro e depois invertendo as linhas.

Como a transposição interna zé proibida, podemos usar :.+(reduzir por caractere vetorizado ou concatenação de caracteres de seqüência de caracteres) para obter o mesmo efeito.

:.+é a única parte do código-fonte que não pode ser desmembrada. Empurramos as strings "W%"e ":.+", invertendo-as condicionalmente, se a segunda string contiver uma alimentação de linha, concatenar, remover todas as alimentações de linha e avaliar o 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
fonte
Como isso é tão curto? Sério, por que não pode :.+ser quebrado em várias linhas?
Intrepidcoder
1
@intrepidcoder Por razões sintáticas. O significado de ambos :e .depende do caractere após eles, e os feeds de linha não são válidos após nenhum deles (e mesmo se fossem, isso mudaria o significado do programa).
Martin Ender
6

C (gcc) , 1420 1399 463 bytes

Ah ... a alegria das cordas de comprimento indeterminado!

Assume sizeof(char*) == sizeof(int)e sizeof(char**) <= 16.

A nova abordagem

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

Experimente online!

Saída do acima

A solução foi embaraçosamente fácil no final. Você cria um programa A que gira as coisas no sentido horário e um programa B que gira no sentido anti-horário:

UMA

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

Faça um retângulo de proporções razoáveis ​​e limite A a isso, e coloque guardas de comentários em torno dele:

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 o programa B a um quadrado com a mesma largura que o de A mais dois (para as linhas extras de comentários na borda inferior), gire-o no sentido anti-horário e bata-o à direita do programa A e obtenha a solução acima.

A abordagem antiga

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

Experimente online!

Saída do acima

gastropner
fonte