Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Out of all of the ASCII characters, it is easy to tell that some of them form groups that are rotations of the same basic character. For example, V > ^ <. This allows the possibility to construct ASCII art that can be rotated by multiples of 90 degrees and still remain ASCII art.

The Challenge

Your goal is to golf a program that accepts ASCII art and the number of degrees to rotate it from STDIN, and prints the rotated ASCII art to STDOUT.

On the first line of input, your program will receive a number N. This number represents the width and height of the ASCII art.

You will then receive N more lines of exactly N characters each (the newline is not counted in this number). The size of the art will always be a square, although it may have padding in the form of spaces to make it a square.

You will then receive one more number on a final line: 90, 180, or 270. This represents how many degrees clockwise the picture should be rotated.

Note: The inputted image will only contain characters that can be rotated by the correct amount. If the input does not match these requirements exactly, no specific behavior is required.

As output, your program should print exactly N lines of N characters, with newlines after each line. The image should be rotated so that each character in the original has been replaced by a rotated version and has been moved to the correct place in the image.

Examples (not very beautiful ASCII art)

Input

5
<- ||
|  |V
+->+ 
   |O
<--+ 
90

Output

^ +-^
| | |
| V  
+-+--
 O <-

(Rotations by 90 and 270 won't look very good because the characters are not squares)

Input

6
+ /\ +
| \ \|
(  \/|
 \   )
I \ / 
:) V $
180

Output

$ ^ (:
 / \ I
(   \ 
|/\  )
|\ \ |
+ \/ +

Required Supported Characters

For all rotations (90, 180, and 270), the program should be able to rotate:

  • Spaces, +, @, X and O which never change
  • V > < ^
  • | - and \ / (rotated by 180 they stay the same)

For 180 degree rotation, these additional characters must be supported

  • I N Z % : 0 = S ~ $ # which stay the same
  • P d, ( ), [ ], { }, M W, and 9 6
share|improve this question
Your first example contains the lowercase v, which is not a supported character. I assume it was meant to be an uppercase V. Also, the last line in it is not padded to be 5 chars long. – Ilmari Karonen Mar 19 '12 at 17:23
@IlmariKaronen Good catch. It's fixed now. – PhiNotPi Mar 19 '12 at 20:35
P d, ( ), [ ], { }, M W, and 9 6 can ever be turned 90º or 270º? – ajax333221 Mar 20 '12 at 22:04
No, the art will only contain characters that are designated to be able to rotate the correct amount. The last two bullets list characters can be rotated by 180º only. Your program will not be asked to rotate these by any other amount. – PhiNotPi Mar 20 '12 at 22:09

5 Answers

up vote 4 down vote accepted

GolfScript, 79 75 73 67 chars

n%(;)~90/{-1%zip{{.'V<^>P(d)[{]}M9W6/\/\|-|'4/\+{.}%n+.@?)=}%}%}*n*

Looks like my and Peter Taylor's solutions are experiencing a certain amount of convergence. Anyway, looks like I'm still a few chars ahead for now. :-) Thanks (and +1) to both Peter and copy for ideas that I've shamelessly stolen.

This code completely ignores the size given on the first line, since it's redundant information. It should even handle inputs with non-square dimensions, but it very much depends on all the input lines being padded to the same length. Trying to rotate the characters P, d, (, ), [, ], {, }, M, W, 9, or 6 by 90 or 270 degrees may produce unexpected output; all other characters that are not explicitly remapped are retained unchanged.

Ps. Here's my original 79-char solution:

n%(;)~90/:z{-1%zip}*n*z'V<^>/|-\V>^<'{:c;{{.c?~.c=@if}%}*}:s~2z='P([{M96W}])d's
share|improve this answer
Convergence? :P I liked your trick for doing the lookup without repeating (many) characters, but it doesn't seem to be compatible with my trick for avoiding the if. – Peter Taylor Mar 19 '12 at 23:58

C, 336 chars

I'm sure there's room for improvement.

char*a="<^>V|-|-/\\/\\ppdd(())[[]]{{}}MMWW9966",*p,*q;
n,x,y,r;
z(c){
    return(q=strchr(a,c))?a[(q-a&-4)+(q-a+r&3)]:c;
}
#define A(r)(r&3^3?1-r%4:0)*
f(r){
    return A(r)x+A(~-r)y+(r&2)/2*~-n;
}
main(){
    scanf("%d\n",&n);
    p=q=malloc(n*n+1);
    for(y=n;y--;q+=n)gets(q);
    scanf("%d",&r);
    for(r/=90;++y<n;puts(""))for(x=0;x<n;x++)putchar(z(p[f(r)+n*f(r+1)],r));
}
share|improve this answer

javascript (181 chars)

a=prompt(f="V<^>V|-|/\\/P(d)P([{]}[}M9W6M9").split(n="\n");c=a.pop()/90;for(
b=a[0];c--;a=d.split(n))for(e=d=n;e<b*b;++e%b||(d+=n))d+=f[f.indexOf(g=a[b-e
%b][e/b|0])+1||a]||g;alert(d)

Requires every line to be padded to the given length.

share|improve this answer
can you give me an example of what exactly I need to put on prompt? I tried replacing lines with \n, normal copy paste and balancing spaces to the first/last lines and failed to make it work – ajax333221 Mar 20 '12 at 18:04
@ajax333221 Pasting multiple lines into an alert box only works in Chrome, I just noticed for the first time. Also make sure you're not copying a final newline. – copy Mar 20 '12 at 19:07

Golfscript (80 79 78 77 76 chars)

n%(;)~90/{zip{-1%{'V<^>V|-|/\/''Pd()[]{}MW96'{.4*}%4/128,+{.}%+.@?)=}%}%}*n*

NB Entering the "undefined behaviour" permitted by invalid input can produce somewhat curious output, because of placeholder characters (outside ASCII) used for certain characters whose rotation by 90 degrees is not defined. For example, ( would be mapped to code point 160, which in ISO-8859-1 and Unicode is a non-breaking space.

share|improve this answer

JavaScript

Note: this entry is not finished, it just rotates 90º for now. I have a problem when trying to loop arr[len+1]/90 times, since I don't know how to prevent overwriting.

Here is my un-golfed advance:

//<rotate 90>
arr="5\n<- ||\n|  |V\n+->+ \n   |O\n<--+ \n90".split("\n");
chrs="<^>V<|-|/\\/PúdóP(ü)ö([ï]ä[{í}á{MiWaM9u6o9";
i=len=arr.length-2;
out=[];

for(j=0;j<len;j++){
    out[j]=[];
}

for(;i>0;i--){
    for(j=0;j<len;j++){
        n=chrs.indexOf(arr[i][j]);
        out[j][-(i-len)]=(n>-1)?chrs[n+1]:arr[i][j];
    }
}
//</rotate 90>

//<display>
for(i=0,s="";i<len;i++){
    s+=out[i].join("")+"<br>";
}

document.write(arr.join("<br>").replace(/ /g,"#"));
document.write("<br><br>");
document.write(s.replace(/ /g,"#"));
//</display>

It rotates 90º perfectly, I just need to figure it out how to do it arr[len+1]/90 times

share|improve this answer
I will try to fix it tonight or tomorrow morning, it think it will be around 230 chars with the fix (and please, don't laugh at my code) – ajax333221 Mar 20 '12 at 22:11

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.