Girar uma imagem artística ASCII

17

De todos os caracteres ASCII, é fácil dizer que alguns deles formam grupos que são rotações do mesmo caractere básico. Por exemplo V > ^ <,. Isso permite a possibilidade de construir arte ASCII que pode ser girada em múltiplos de 90 graus e ainda permanecer arte ASCII.

O desafio

Seu objetivo é jogar golfe em um programa que aceite arte ASCII e o número de graus para girá-lo de STDIN e imprima a arte ASCII girada em STDOUT.

Na primeira linha de entrada, seu programa receberá um número N. Esse número representa a largura e a altura da arte ASCII.

Você receberá N mais linhas com exatamente N caracteres cada (a nova linha não é contada nesse número). O tamanho da arte será sempre um quadrado, embora possa ter preenchimento na forma de espaços para torná-lo um quadrado.

Você receberá mais um número na linha final: 90, 180 ou 270. Isso representa quantos graus no sentido horário a imagem deve ser girada.

Nota: A imagem inserida conterá apenas caracteres que podem ser girados na quantidade correta. Se a entrada não corresponder exatamente a esses requisitos, nenhum comportamento específico será necessário.

Como saída, seu programa deve imprimir exatamente N linhas de N caracteres, com novas linhas após cada linha. A imagem deve ser girada para que cada caractere no original seja substituído por uma versão girada e movido para o local correto na imagem.

Exemplos (arte ASCII não muito bonita)

Entrada

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

Resultado

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

(Rotações de 90 e 270 não parecerão muito boas porque os caracteres não são quadrados)

Entrada

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

Resultado

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

Caracteres suportados necessários

Para todas as rotações (90, 180 e 270), o programa deve poder girar:

  • Spaces, +, @, Xe Onão que a mudança
  • V > < ^
  • | -e \ /(girado em 180, eles permanecem iguais)

Para rotação de 180 graus, esses caracteres adicionais devem ser suportados

  • I N Z % : 0 = S ~ $ # que permanecem os mesmos
  • P d, ( ), [ ], { }, M W, E9 6
PhiNotPi
fonte
Seu primeiro exemplo contém minúsculas v, que não é um caractere suportado. Suponho que era para ser uma letra maiúscula V. Além disso, a última linha não é preenchida para ter 5 caracteres.
Ilmari Karonen 19/03/12
@IlmariKaronen Good catch. Está consertado agora.
PhiNotPi 19/03/12
P d, ( ), [ ], { }, M W, and 9 6pode ser girado 90º ou 270º?
ajax333221
Não, a arte conterá apenas caracteres designados para poder girar a quantidade correta. Os dois últimos caracteres da lista de marcadores podem ser girados apenas em 180º. Seu programa não será solicitado a rotacioná-los por qualquer outro valor.
PhiNotPi 20/03/12

Respostas:

4

GolfScript, 79 75 73 67 caracteres

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

Parece que as minhas soluções e as de Peter Taylor estão passando por uma certa convergência. Enfim, parece que ainda estou alguns caracteres à frente por enquanto. :-) Obrigado (e +1) a Peter e copie por idéias que eu descaradamente roubei.

Esse código ignora completamente o tamanho fornecido na primeira linha, pois é uma informação redundante. Ele deve manipular entradas com dimensões não quadradas, mas depende muito de todas as linhas de entrada serem preenchidas com o mesmo comprimento. Tentando rodar os caracteres P, d, (, ), [, ], {, }, M, W, 9, ou 6por 90 ou 270 graus, pode produzir uma saída inesperada; todos os outros caracteres que não são explicitamente remapeados são mantidos inalterados.

Ps. Aqui está a minha solução original de 79 caracteres:

n%(;)~90/:z{-1%zip}*n*z'V<^>/|-\V>^<'{:c;{{.c?~.c=@if}%}*}:s~2z='P([{M96W}])d's
Ilmari Karonen
fonte
Convergência? : PI gostou do seu truque para fazer a pesquisa sem repetir (muitos) caracteres, mas não parece ser compatível com o meu truque para evitar o if.
22412 Peter Taylor em
5

C, 336 caracteres

Tenho certeza de que há espaço para melhorias.

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));
}
Ugoren
fonte
4

javascript (181 caracteres)

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)

Requer que todas as linhas sejam preenchidas no comprimento especificado.

cópia de
fonte
você pode me dar um exemplo do que exatamente eu preciso colocar no prompt? Eu tentei substituindo linhas com \n, cópia normal colar e equilibrar espaços para as primeiras / últimas linhas e não conseguiu fazê-lo funcionar
ajax333221
@ ajax333221 Colar várias linhas em uma caixa de alerta só funciona no Chrome, notei pela primeira vez. Verifique também se você não está copiando uma nova linha final.
copie
4

Golfscript ( 80 79 78 77 76 caracteres)

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

Nota: A inserção do "comportamento indefinido" permitido por entrada inválida pode produzir resultados um tanto curiosos, devido aos caracteres de espaço reservado (fora do ASCII) usados ​​para determinados caracteres cuja rotação em 90 graus não está definida. Por exemplo, (seria mapeado para o ponto de código 160, que na ISO-8859-1 e Unicode é um espaço sem interrupção.

Peter Taylor
fonte