Program obrotu 90 °

20

Wprowadzenie

Napisz kompletny program, który obraca prostokątny blok znaków ASCII o 90 stopni w prawo. Gdy sam program jest obracany o 90 stopni w kierunku zgodnym z ruchem wskazówek zegara, obraca blok znaków ASCII o 90 w kierunku przeciwnym do ruchu wskazówek zegara.

Zasady

  • Wielu nie używa wbudowanych, które obracają lub transponują matryce. Na przykład w MATLAB / Octave rot90i operator transpozycji 'nie są dozwolone.
  • Musisz napisać pełny program, który używa STDIN i STDOUT lub najbliższego odpowiednika.
  • Twój program musi być prostokątny i zakładać, że wejście jest również prostokątne.
  • Dane wejściowe i wyjściowe są ciągami oddzielonymi znakiem nowej linii i nie będą miały końcowych znaków nowej linii.

Po uruchomieniu z kodem źródłowym jako danymi wejściowymi program musi obracać się o 90 stopni w kierunku zgodnym z ruchem wskazówek zegara. Wyjściem musi być drugi program w tym samym języku, który obraca wejście o 90 stopni przeciwnie do ruchu wskazówek zegara. Kiedy obrócony program otrzymuje kod źródłowy jako dane wejściowe, powinien wypisać kod źródłowy oryginalnego programu.

Uwaga: Oba programy muszą działać na dowolnym wejściu, nie tylko na własnym kodzie źródłowym, więc znak jednoznakowy jest niedozwolony.

Przykład

Powiedzmy, że poniżej znajduje się poprawny program, który obraca wejście o 90 stopni w hipotetycznym języku ExampleLang.

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

Po uruchomieniu z samym sobą jako wejściem, wyświetla inny prawidłowy program, który obraca swój sygnał wejściowy przeciwnie do ruchu wskazówek zegara:

D l^
8 kf

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

Ten drugi program, podany samemu sobie jako dane wejściowe, wyświetla oryginalny program. Zwróć uwagę, że pusta linia powinna mieć cztery spacje, aw drugiej do ostatniej linii znajduje się spacja, której nie można wyrenderować w przecenie. W celu wyjaśnienia:

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

Najkrótszy program wygrywa. Standardowe luki są zabronione.

intrepidcoder
źródło

Odpowiedzi:

17

CJam, 26 25 21 bajtów

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

Dzięki @ MartinBüttner za grę w golfa z 4 bajtów!

Wypróbuj online w interpretera CJam: oryginalny program | obrócony program

To jest obrócony program:

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

Pomysł

Możemy obrócić dane wejściowe o ćwierć obrotu zgodnie z ruchem wskazówek zegara, dzieląc je przy przesuwach linii, odwracając kolejność wynikowych wierszy, transponując wiersze z kolumnami, a na końcu łącząc rzędy, oddzielając je liniami.

Podobnie możemy obracać w lewo, transponując najpierw, a następnie odwracając rzędy.

Ponieważ wbudowana transpozycja zjest zabroniona, możemy użyć :.+(zredukować przez znak wektorowy lub konkatenację łańcucha znaków), aby osiągnąć ten sam efekt.

:.+jest jedyną częścią kodu źródłowego, której nie można rozbić. Pchamy ciągi "W%"i ":.+"warunkowo je odwracamy, jeśli drugi ciąg zawiera kanał, konkatenuje, usuwa wszystkie kanały i ocenia wynik.

Kod

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
źródło
Jak to jest tak krótkie? Poważnie, dlaczego nie :.+da się rozbić na kilka linii?
intrepidcoder,
1
@intrepidcoder Ze względów składniowych. Znaczenie obu :i .zależy od znaku po nim, a linie znaków nie są ważne po żadnym z nich (a nawet gdyby tak było, zmieniłoby to znaczenie programu).
Martin Ender
6

C (gcc) , 1420 1399 463 bajtów

Ach ... radość ze strun o nieokreślonej długości!

Zakłada sizeof(char*) == sizeof(int)i sizeof(char**) <= 16.

Nowe podejście

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

Wypróbuj online!

Wynik powyższego

Ostatecznie rozwiązanie było krępująco łatwe. Tworzysz jeden program A, który obraca rzeczy zgodnie z ruchem wskazówek zegara, i jeden program B, który obraca się przeciwnie do ruchu wskazówek zegara:

ZA

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

Zrób prostokąt o rozsądnych proporcjach i ogranicz do tego A i umieść wokół niego strażników komentarzy:

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

Ogranicz program B do kwadratu o tej samej szerokości co kwadrat dla A plus dwa (dla dodatkowych linii komentarzy na dolnej krawędzi), obróć go w lewo i uderz w prawo od programu A, a otrzymasz rozwiązanie powyżej.

Stare podejście

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

Wypróbuj online!

Wynik powyższego

gastropner
źródło