Programma auto-rotante a 90 °


20

introduzione

Scrivi un programma completo che ruota un blocco rettangolare di caratteri ASCII di 90 gradi in senso orario. Quando il programma stesso viene ruotato di 90 gradi in senso orario, ruota un blocco di caratteri ASCII di 90 in senso antiorario.

Regole

  • Molti non usano built-in che ruotano o traspongono matrici. Ad esempio, in MATLAB / Octave rot90e l'operatore di trasposizione 'non sono consentiti.
  • È necessario scrivere un programma completo che utilizza STDIN e STDOUT o l'equivalente più vicino.
  • Il programma deve essere rettangolare e supporre che anche l'input sia rettangolare.
  • L'input e l'output sono stringhe separate da una nuova riga e non avranno nuove righe finali.

Se eseguito con il suo codice sorgente come input, il programma deve ruotare di 90 gradi in senso orario. L'output deve essere un secondo programma nella stessa lingua che ruota il suo input di 90 gradi in senso antiorario. Quando al programma ruotato viene assegnato il suo codice sorgente come input, dovrebbe generare il codice sorgente del programma originale.

Nota: entrambi i programmi devono funzionare per qualsiasi input, non solo per il proprio codice sorgente, quindi non è consentito un quine di un carattere.

Esempio

Supponiamo che il seguente sia un programma valido che ruota il suo input di 90 gradi in un linguaggio ipotetico ExampleLang.

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

Se eseguito con se stesso come input, genera un altro programma valido che ruota il suo input in senso antiorario:

D l^
8 kf

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

Questo secondo programma, se dato a se stesso come input, emette il programma originale. Si noti che la linea vuota dovrebbe avere quattro spazi e che c'è uno spazio finale sulla penultima riga che non può essere renderizzato in markdown. Chiarire:

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

Vince il programma più breve. Le scappatoie standard sono vietate.

Risposte:


17

CJam, 26 25 21 byte

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

Grazie a @ MartinBüttner per giocare a golf con 4 byte!

Provalo online nell'interprete CJam: programma originale | programma ruotato

Questo è il programma ruotato:

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

Idea

Possiamo ruotare l'input di un quarto di giro in senso orario suddividendolo in avanzamenti di riga, invertendo l'ordine delle righe risultanti, trasponendo le righe con colonne e infine unendo le righe, separate da avanzamenti di riga.

Allo stesso modo, possiamo ruotare in senso antiorario trasponendo prima, quindi invertendo le file.

Poiché la trasposizione incorporata zè vietata, possiamo usare :.+(riduci di carattere vettoriale o concatenazione di caratteri stringa) per ottenere lo stesso effetto.

:.+è l'unica parte del codice sorgente che non può essere suddivisa. Spingiamo le stringhe "W%"e ":.+", in modo condizionale, invertirle se la seconda stringa contiene un avanzamento riga, concatenare, rimuovere tutti gli avanzamenti riga e valutare il risultato.

Codice

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.

Come è così breve? Scherzi a parte, perché non può :.+essere suddiviso su più righe?
intrepidcoder

1
@intrepidcoder Per motivi sintattici. Il significato di entrambi :e .dipende dal carattere , dopo di loro, e ritorni a capo non sono validi dopo uno di questi (e anche se lo fossero, che avrebbe cambiato il significato del programma).
Martin Ender,

6

C (gcc) , 1420 1399 463 byte

Ah ... la gioia delle corde di lunghezza indeterminata!

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

Il nuovo approccio

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

Provalo online!

Uscita di quanto sopra

La soluzione alla fine è stata imbarazzantemente facile. Si crea un programma A che ruota le cose in senso orario e un programma B che ruota in senso antiorario:

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

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

Crea un rettangolo di proporzioni ragionevoli e limita A a quello, e metti guardie intorno ai commenti:

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

Confina il programma B su un quadrato della stessa larghezza di quello per A più due (per le righe extra di commenti sul bordo inferiore), ruotalo in senso antiorario e schiaffeggia a destra del programma A e otterrai la soluzione sopra.

Il vecchio approccio

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

Provalo online!

Uscita di quanto sopra

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.