Programme auto-rotatif à 90 °

20

introduction

Écrivez un programme complet qui fait pivoter un bloc rectangulaire de caractères ASCII de 90 degrés dans le sens des aiguilles d'une montre. Lorsque le programme lui-même pivote de 90 degrés dans le sens horaire, il fait pivoter un bloc de caractères ASCII de 90 degrés dans le sens antihoraire.

Règles

  • Vous n'utilisez pas de modules intégrés qui font pivoter ou transposer les matrices. Par exemple, dans MATLAB / Octave rot90et l'opérateur de transposition 'ne sont pas autorisés.
  • Vous devez écrire un programme complet qui utilise STDIN et STDOUT ou l'équivalent le plus proche.
  • Votre programme doit être rectangulaire et supposer que l'entrée est également rectangulaire.
  • L'entrée et la sortie sont des chaînes séparées par des sauts de ligne et n'auront pas de sauts de ligne de fin.

Lorsqu'il est exécuté avec son code source en entrée, votre programme doit se tourner de 90 degrés dans le sens des aiguilles d'une montre. La sortie doit être un deuxième programme dans la même langue qui tourne son entrée de 90 degrés dans le sens antihoraire. Lorsque le programme pivoté reçoit son code source en entrée, il doit sortir le code source du programme d'origine.

Remarque: Les deux programmes doivent fonctionner pour n'importe quelle entrée, pas seulement pour leur propre code source, donc une quine à un caractère n'est pas autorisée.

Exemple

Supposons que ce qui suit est un programme valide qui fait pivoter son entrée de 90 degrés dans un langage hypothétique ExampleLang.

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

Lorsqu'il est exécuté avec lui-même en entrée, il génère un autre programme valide qui tourne son entrée dans le sens antihoraire:

D l^
8 kf

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

Ce deuxième programme, une fois donné à lui-même comme entrée, sort le programme d'origine. Notez que la ligne vierge doit avoir quatre espaces et il y a un espace de fin sur l'avant-dernière ligne qui ne peut pas être restituée dans la démarque. Clarifier:

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

Le programme le plus court gagne. Les failles standard sont interdites.

intrépide
la source

Réponses:

17

CJam, 26 25 21 octets

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

Merci à @ MartinBüttner pour avoir joué au golf sur 4 octets!

Essayez-le en ligne dans l'interpréteur CJam: programme original | programme tourné

Voici le programme tourné:

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

Idée

Nous pouvons faire pivoter l'entrée d'un quart de tour dans le sens des aiguilles d'une montre en la divisant au niveau des sauts de ligne, en inversant l'ordre des lignes résultantes, en transposant les lignes avec des colonnes et enfin en joignant les lignes, séparées par des sauts de ligne.

De même, nous pouvons faire pivoter dans le sens antihoraire en transposant d'abord, puis en inversant les lignes.

Étant donné que la transposition intégrée zest interdite, nous pouvons utiliser :.+(réduire par concaténation de caractère vectorisé ou chaîne de caractères) pour obtenir le même effet.

:.+est la seule partie du code source qui ne peut pas être décomposée. Nous poussons les chaînes "W%"et les inversons ":.+"conditionnellement si la deuxième chaîne contient un saut de ligne, concaténons, supprimons tous les sauts de ligne et évaluons le résultat.

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
la source
Comment est-ce si court? Sérieusement, pourquoi ne peut-il pas :.+être divisé en plusieurs lignes?
intrepidcoder
1
@intrepidcoder Pour des raisons syntaxiques. La signification des deux :et .dépend du caractère après eux, et les sauts de ligne ne sont pas valides après l'un ou l'autre (et même s'ils l'étaient, cela changerait la signification du programme).
Martin Ender
6

C (gcc) , 1420 1399 463 octets

Ah ... la joie des cordes de longueur indéterminée!

Suppose sizeof(char*) == sizeof(int)et sizeof(char**) <= 16.

La nouvelle approche

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

Essayez-le en ligne!

Sortie de ce qui précède

La solution a été embarrassante au final. Vous faites un programme A qui tourne les choses dans le sens horaire, et un programme B qui tourne dans le sens antihoraire:

UNE

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

Faites un rectangle de proportions raisonnables et limitez A à cela, et mettez des gardes de commentaires autour de lui:

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

Limitez le programme B à un carré de la même largeur que celui de A plus deux (pour les lignes de commentaires supplémentaires sur le bord inférieur), tournez-le CCW et giflez-le à droite du programme A et vous obtenez la solution ci-dessus.

L'ancienne approche

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

Essayez-le en ligne!

Sortie de ce qui précède

gastropner
la source