Operador ASCII art

22

Desafio

Dado um operador ASCII da lista abaixo e um número n, desenhe uma representação ASCII do operador usando esse operador como o caractere com os segmentos de linha do operador com comprimento n .

Entrada

Um caractere ASCII da lista = + - x /e um número inteiro em nque n >= 1. (Estou usando em xvez de *e em /vez de ÷, mas você pode usar qualquer um deles, o que for mais fácil). Para +e x, você só precisa lidar com números ímpares para evitar problemas com o alinhamento.

Saída

Um desenho ASCII do operador composto pelo caractere com segmentos de comprimento n. As partes horizontais devem ter espaços entre os caracteres para compensar as diferenças de distância vertical / horizontal.

Regras

Isso é , então o código mais curto em bytes vence. As brechas padrão são proibidas.

Exemplos

Entrada: + 3

  +
+ + +
  +

Entrada: = 4

= = = =
= = = =

Entrada: = 10

= = = = = = = = = =
= = = = = = = = = =

Entrada: - 2

- -

Entrada: / 10

         /
        /
       /
      /
     /
    /
   /
  /
 /
/

Entrada: x 7

x     x
 x   x
  x x
   x
  x x
 x   x
x     x
Yodle
fonte
você pode adicionar o caso de teste = 10?
Rod
1
Presumo que "x" e "+" implicam números ímpares? (Eu só vi DrMcMoylex perguntou quase a mesma pergunta.)
Martin Rosenau
1
@MartinRosenau Sim, na seção Entrada: "Para + e x, você só precisa manipular números ímpares para evitar problemas de alinhamento".
corvus_192
Por que X e / não estão espaçados?
Adám 08/11/16
1
é permitido espaço em branco à esquerda?
Adám 08/11/16

Respostas:

5

Pip , 62 59 56 bytes

55 bytes de código, +1 para -Ssinalizador.

[sXbRA_AEv-_aM,b(Y^aWR_Xb/2s)MyRVsX,b.aYaXbJsxyRL2x]@Aa

Observe que esta solução funciona com entrada de ÷para divisão e *multiplicação, embora use esses caracteres para desenhar ASCII-art /e x, respectivamente. O OP esclareceu que está tudo bem. Experimente online!

Quão?

Aqui está uma versão parcialmente espaçada e comentada . Observe que ae bsão os argumentos da linha de comando, ou seja, o operador e o tamanho, respectivamente. O -Ssinalizador controla como as listas são produzidas: ele se une às novas linhas primeiro, mas se une a qualquer lista aninhada nos espaços.

[                 Build a list of all possible figures:
 sXbRA_AEv-_aM,b   0 - Multiplication
 (Y^aWR_Xb/2s)My   1 - Addition
 RVsX,b.a          2 - Division
 YaXbJs            3 - Subtraction
 x                 4 - Empty
 yRL2              5 - Equals
 x                 6 - Empty
] @ Aa            Index, mod 7, with ASCII value of a

E aqui estão as seções individuais:

Multiplicação

Para cada linha da figura, geramos uma sequência de espaços e substituímos dois deles pelo caractere de entrada. Para linha i, queremos substituir os espaços no índice ie b-1-i; mas observe que o último pode usar o índice negativo -1-i. (É ainda mais curto porque a variável vé pré-inicializada para negati v e 1.)

sXbRA_AEv-_aM,b
            M,b  Map this function to range(b):
sXb                Space, repeated b times
     _             Function arg
      AE           (Implicitly) convert to list and append element...
        v-_        -1 minus function arg
   RA              Replace the characters at those indices...
           a       ... with input character
                 The resulting list is output with one item per line

Adição

Usando a estratégia de minha resposta Desenhar um quadrado vazio , definimos uma função que envolve a +em b/2cópias de seu argumento e retorna o resultado como uma lista de caracteres. (A divisão inteira //não é necessária porque o operador de repetição de string é Xautomaticamente truncado para inteiro.) Primeiro, chamamos essa função em um espaço, dando [" ";" ";"+";" ";" "]; então, mapeamos a mesma função para esse resultado, fornecendo [" ";" ";"+";" ";" "]na maioria das linhas, mas ["+";"+";"+";"+";"+"]na linha central. Essa lista aninhada é gerada, devido ao -Ssinalizador, com espaços entre todos os caracteres em uma linha e novas linhas entre as linhas.

(Y^aWR_Xb/2s)My
                 Anonymous function:
      _Xb/2        Function arg, repeated b/2 times (implicitly rounded down)
   aWR             Wrap a in two copies of the above
  ^                Split resulting string into list of chars
 Y               Yank that function into y
(          s)    Apply function y to space
             My  Map y to that result

Divisão

Cada linha tem entre b-1e 0espaços, seguidos pelo caractere de entrada a.

RVsX,b.a
    ,b    Range(b)
  sX      Space, repeated that many times (works itemwise)
      .a  Concatenate a (itemwise)
RV        Reverse (puts the larger number of spaces at the beginning)
          Outputs newline-separated

Subtração

Faça uma linha separada por espaço do caractere de entrada. Salve uma cópia para mais tarde.

YaXbJs
 aXb    b copies of a
    Js  Join on space
Y       Yank into y (overwrites the function from earlier, but we're done using it anyway)
        This is a string, so it just gets output

É igual a

O passo da subtração armazenava metade do que precisamos - yapenas o dobro.

yRL2  (Implicitly) convert y to list and repeat it twice
      Outputs newline-separated

Os xvalores fictícios estão lá para preencher a lista principal, para que a indexação modular forneça um índice exclusivo para cada caractere de entrada +-*÷=.

DLosc
fonte
13

V , 78, 72, 71, 68, 65, 63, 62 , 61 bytes

Ç=ü-/Àé X
ç^Ó/é Àä$
ç+/ÀÄM|ÀR+ 
ç=/Ä
ç¯/lòhYpX
çx/rxòl3Äjxlrx

Experimente online!

Como sempre, a batalha de pescoço e pescoço com 05AB1E é realmente divertida!

Como ele contém caracteres não ASCII, eis um hexdump:

0000000: c73d fc2d 2fc0 e920 580a e75e d32f e920  .=.-/.. X..^./. 
0000010: c0e4 240a e72b 2fc0 c44d 7cc0 522b 200a  ..$..+/..M|.R+ .
0000020: e73d 2fc4 0ae7 af2f 6cf2 6859 7058 0ae7  .=/..../l.hYpX..
0000030: 782f 7278 f26c 33c4 6a78 6c72 78         x/rx.l3.jxlrx

Isso cria espaços iniciais na saída para =e -, mas isso parece ser permitido . Se isso não for permitido, fique à vontade para comentar e eu o reverterei.

Explicação

O "comando global" (por exemplo ç) aplica um certo conjunto de comandos a todas as linhas que correspondem a um determinado regex. A sintaxe é

ç<compressed regex>/<commands>

Essa é a maneira mais fácil de simular uma instrução condicional / alternar. Na minha resposta original, eu simplesmente criei toda a arte ASCII no lado direito para cada caractere diferente que precisamos procurar. No entanto, muitas dessas saídas requerem comandos semelhantes. Então eu os combinei. O primeiro comando ('Ç') é na verdade o inverso do comando global; ele aplica o comando a todas as linhas que não correspondem ao regex. Portanto, o primeiro comando é:

Ç=ü-        " On every line not containing an '=' or an '-' (e.g. inputs '/', '+', and 'x'):
    /Àé     "   Insert *n* spaces
        X   "   Delete one of them

O comando a seguir é para as entradas '=' e '-'. Esses dois são convenientemente fáceis e semelhantes. Após esse comando, não precisamos mais processar -.

ç^Ó         " On every line that starts with non-whitespace (e.g. every line not affected by our previous command):
   /é       "   Insert one space
            "   Move back a character
      À     "   Make *n* copies
       ä$   "   Of every character on this line

A partir daqui, apenas fazemos alguns comandos extras para cada entrada individual possível. Para +:

ç+/         " On every line containing a '+':
   ÀÄ       "   Make *n* copies of this line
     M|     "   Move to the first character of the middle line
       À    "   *n* times:
        R+  "   Replace the next two characters with '+ '

O comando para iguais é muito direto. Nós apenas duplicamos com Ä. Para /:

ç¯          " On every line containing a '/':
  /l        "   Move one character to the right
    ò       "   Recursively:
     h      "     Move one character to the left
      Yp    "     Make a copy of this line
        X   "     Delete one character
         ò  "   End loop (implicit)

O último é o mais complicado. É basicamente um porto dessa resposta .

çx              " On every line containing a 'x':
  /rx           "   Replace the first character with an 'x'
     ò          "   Recursively:
      l         "     Move one char to the right
       3Ä       "     Make 3 copies of this line
         j      "     Move down one line
          x     "     Delete one char
           l    "     Move one char to the right
            rx  "     Replace this char with an 'x'
DJMcMayhem
fonte
então é para isso que várias linhas são usadas?
Conor O'Brien
@Conorobrien Sim. O çcomando (bem como pesquisa e substituição, /e ?) todos parte de simulação de linha de comando do vim, onde você tem que pressione Enter para realmente executar o comando
DJMcMayhem
13

05AB1E , 81 76 74 73 70 69 68 65 64 62 60 59 57 56 bytes

Atualmente na guerra com a resposta V . Estou indo buscá-lo Dr. McMoylex: p.

Também em guerra com a resposta Pip . Eu estarei observando você, Sr. DLosc.


Código:

Ç6&"¹s<ú.s.Bívy¹'xQiÂðñ}, ¹×S)»¹'=Qƒ= ;ƒ¹})D¦»»Rû.c"#è.V

Ou de uma forma mais legível:

  Ç6&
"¹s<ú.s.Bívy¹'xQiÂðñ},
 ¹×S)»¹'=Qƒ=
 ;ƒ¹})D¦»»Rû.c"
#è.V

Usa a codificação CP-1252 . Experimente online!

Adnan
fonte
1
Aqui vamos nós de novo ...: P
DJMcMayhem
1
@DrMcMoylex Hahaha, bons velhos tempos :).
Adnan #
30
Mais legível ... totalmente ...
Oliver Ni
1
Para uma determinada definição de "legível".
Matt Lacey
1
Estou indo
atrás de
7

Python 3, 304 283 278 bytes

Simples o suficiente, apenas cria uma matriz de caracteres e aplica as diferentes operações com base em qual delas é. O =e -tem espaços à direita, se isso não é tão ruim.

EDIT: Obrigado a @Shebang e @Rod por suas sugestões, que acabaram salvando 21 bytes!

EDIT2: Obrigado ao @Artyer por salvar 5 bytes!

t,s=input().split()
s=int(s)
r=range(s)
b=[[' ']*s for x in r]
exec(['for x in r:b[s//2][x]=b[x][s//2]=t','b=[t*s]'+'*2'*(t=='='),'for x in r:b[x][s-x-1]='+'b[x][x]='*(t=='x')+'t'][(t>'+')+(t in'x/')])
if t in'-=+':b=[[x+' 'for x in l]for l in b]
print(*map(''.join,b),sep='\n')
Azul
fonte
Você pode economizar 8 bytes removendo a if'-'==tlinha de condição e substituindo a linha acima por if t in'=-':b=[[t+' ']*s]*(2*(t>'-'))(acho).
Kade7
você pode envolver as funções dentro de uma lista e executar usando exec: exec(['+ block','/ block','x block','= block','- block']['+/x=-'.find(t)])para salvar ~ 18 bytes
Rod
Sim, espaços à direita / novas linhas são aceitáveis.
Yodle
Para a primeira linha, faça .split()(nenhum argumento é dividido em espaço em branco). Na linha 6, você perdeu um espaço ( b=[[x+' 'for). Você pode fazer a última linha print(*map(''.join,b),sep='\n')por 1 menos bytes.
Artyer
7

JavaScript (ES6), 238 225 215 202 196 bytes

(c,n)=>[...Array(i=n*(c=="="?4:c+1-1?2:c<"-"?n+n:n+1))].map(_=>--i%(n+(c=='/'|c>'w'||n))?c>'w'?i%n&&~-i%(n+2)?" ":c:c<'-'?i%(n*2)-n&&(~i&1|(n/2^i/n/2))?" ":c:c=="/"?i%n?" ":c:i%2?c:" ":`
`).join``

Provavelmente poderia ser jogado, mas é um começo.

ETHproductions
fonte
6

Scala, 275 bytes

(i,c)=>if(c<44){val b=(" "*(i-1)+"+\n")*((i-1)/2)
b+"+ "*i+"\n"+b}else
if(c<46)"- "*i else
if(c<48)i-1 to(0,-1)map(" "*_+"/\n")mkString else
if(c<62)"= "*i+"\n"+"= "*i
else{val a=0 to i/2-1 map(x=>" "*x+"x"+" "*((i/2-x)*2-1)+"x"+" "*x+"\n")mkString;a+" "*(i/2)+"x"+a.reverse}

Uso:

val f:((Int,Char)=>String)=...
print(f(10, '/'))

Explicação:

O código testa o valor ascii do caractere para escolher a maneira correta de gerar a imagem. Os valores ascii dos operadores em questão são: ('+' -> 43), ('-' ->45), ('/' -> 47), ('=' -> 61), ('x' -> 120)

(i,c)=>                              //define a function
  if(c<44){                            //if c is a plus
    val b=(" "*(i-1)+"+\n")*((i-1)/2)    //define the top/bottom part b as (i-1)/2 times (i-1) spaces, a plus sign and a newlineine
    b+"+ "*i+"\n"+b                      //return b, i times a plus and a space, a newline and b
  }else if(c<46)                       //if c is a '-'
    "- "*i                               //return "- " repeated i times
  else if(c<48)                        //if c is a '/'
    i-1 to(0,-1)                         //create a range from i-1 to 0 in steps of -1
    map(" "*_+"/\n")                     //map each number to that number of spaces plus a "/" and a newline
    mkString                             //join them together
  else if(c<62)                        //if c is '='
    "= "*i+"\n"+"= "*i                   //return "= " repeated i times, a newline and "= " repeated i times again
  else{                                //if c if 'x'
    val a=                               //define a, which will be the top part, as...
      0 to i/2-1                         //a range from 0 to i/2-1
      map(n=>                            //map each number n to
        " "*n                              //n spaces
        +"x"                               //plus an "x"
        +" "*((i/2-n)*2-1)                 //plus ((i/2)-n)*2-1 spaces
        +"x"                               //plus an "x"
        +" "*n                             //plus n spaces
        +"\n"                              //and a newline
      )mkString;                         //join them
    a+" "*(i/2)+"x"+a.reverse          //return a, i/2 spaces, "x" and the reverse of a 
  }
corvus_192
fonte
5

JavaScript (ES6), 156 bytes

(c,n)=>[...Array(n--)].map((_,i,a)=>a.map((_,j)=>({'/':a=i+j-n,x:a&&i-j,'-':a=i+i-n,'+':a&&j+j-n,'=':a+2&&a-2}[c]?' ':c)).join(c=='='|c<'/'?' ':'')).join`\n`

Onde \nrepresenta o caractere literal de nova linha.

Neil
fonte
No Firefox 49, recebo SyntaxError: invalid property ido que está escrito atualmente, mas alterar as barras de proteção ao redor da barra para apóstrofos corrigiu isso. (Por que você tem backticks lá em vez de apóstrofos?)
ETHproductions
Além disso, as saídas para +, -e =olhar diferente do que as chamadas de desafio para: "porções horizontais devem ter espaços entre os caracteres para compensar diferenças de distância vertical / horizontal."
ETHproductions
@ETHproductions a) erro de digitação b) desculpe, esqueci isso, será corrigido mais tarde.
911 Neil
Isso é ridiculamente curto. Espero corrigi-lo não adicione muitos bytes.
ETHproductions
@ETHproductions Obrigado. Eu acho que isso acontece a um custo de 19 bytes.
Neil
4

Dyalog APL , 91 86 bytes

Necessidades ⎕IO←0, que é padrão em muitos sistemas. Toma n como argumento à esquerda e um de + - × ÷ = como argumento à direita.

{s←⌈⍎⍕32
t' '
d←⌽∘.=⍨⍺
s2 6:t[d∨⌽d6=s]
5=s:t[↑,/2↑¨∨/¨(⌊⍺÷2)=⍳⍺ ⍺]
(2-s)(2×⍺)⍴t}

Explicação

{
    s     3  2              calculate ceil(3 f 2), where f is the given symbol
    t  ' '                     create a string with a space before the symbol
    d   ∘.=⍨                  Boolean \ diagonal
    s  2 6: t[d   d  6 = s]  if ÷ or × index t with one or both diagonals
 find coordinates that are in the middle of at least one dimension
 pad with zeros for spacing
 use that to index into t
    5 = s: t[  ,/ 2↑¨ ∨/¨ (⌊  ÷ 2) =   ⍺]
 - or =:
    (2 - s) (2 × ⍺)  t        one or two rows of double-spaced symbols
}
Adão
fonte
3

Mathematica, 191 bytes

e=#~Mod~2==1&;StringRiffle[Normal@SparseArray[{a_,b_}/;(a+b==d+1||a==b)[e@b&&a<3,,e@b&&(a==⌈d/2⌉||b==d),,e@b&&a<2,,a+b==d+1][[Last@ToCharacterCode@#~Mod~10]]:>#,{d=#2,2d-1}," "],"
"," "]&

Função anônima. Pega uma sequência e um número como entrada e retorna uma sequência como saída. Não é o mais curto de longe, mas ainda assim divertido de escrever.

LegionMammal978
fonte
3

C, 396 bytes

#define p(x) printf(x);
i,j,k,m;f(char s,int n){i=k=0;if(s==45)for(;i<n;++i)p("- ")m=n/2;if(s==43)for(;i<n;++i)for(j=0;j<=m;++j)if(i-m)p(j-m?"  ":"+\n")else{for(;k<n;++k)p("+ ")p("\n")j+=m;}if(s==61)for(;i<2;++i){for(k=0;k<n;++k)p("= ")p("\n")}j=n;if(s==47)for(;i<n;++i){--j;for(k=0;k<j;++k)p(" ")p("/\n")}if(s==120)for(;i<n;++i){k=m-abs(m-i);for(j=0;j<n-k;++j)p(j-k?" ":"x")p(i-m?"\bx\n":"\n")}}

Ligue para:

int main()
{
   f('x', 5);
   return 0;
}
Steadybox
fonte
2

SOML , 104 100 bytes (não concorrente)

    Cd³³b»E +=?ce*d+e{t}bd*Oe{t}} ==?b*tt} -=?b*t} /=?bc*b{j:d+p}} x=?"”cb*e{jj⁴⁴d;d+++tGG;c+;}XOdoe{O

Isso é meio que competitivo, pois tenho certeza de que tudo o que usei aqui tem documentos no github antes desta data de publicação das perguntas, mas o analisador não tem suporte para algumas funções que usei para o idk.

dzaima
fonte
2

PHP, 306 292 281 282 281 275 270 bytes

$r=str_pad("",2*$n=$argv[2],($c=$argv[1])." ")."\n";if(",">$c)$r=($m=str_repeat(str_pad($c,$n," ",0)."\n",$n/2))."$r$m";if(9<$c)$r.=$r;if(w<$c)for($r=$c;$i<$n;$r[$i*(2+$n)]=$r[++$i*$n-1]=x)$r[$i*$n+$i+$n]="\n";if("/"==$c)for($r=$s="";$i++<$n;$s.=" ")$r="$s/\n$r";echo$r;

Ooh, isso é volumoso ... precisa de mais golfe.
Eu poderia salvar 4 bytes com quebras de linha físicas ou um byte colocando "\ n" em uma variável.

Titus
fonte
1
Bom.para o "+", acho que você precisa coincidir com a altura e nem sempre 3. Além disso, você deve poder jogar mais golfe se if () em vez de case / break;
Crypto
2

C #, 744 bytes

Acho que tem 1 milhão de caracteres, mas não me importo, estou tão feliz que resolvi isso ...

Golfe:

string A(string s,int n){string O="";Func<string,int,string>R=(a,b)=>{return string.Join("",Enumerable.Repeat(a,b))+"\r\n";};switch(s){case"+":for(int i=0;i<n;i++){if(i==n/2){O+=R("+",n);}else{O+="+".PadLeft(n-n/2,' ').PadRight(n-n/2,' ')+"\r\n";}}return O;case"=":return R("=",n)+R("=",n);case "-":return R("-",n);case "/":for(int i=n;i>0;i--){O+="/".PadLeft(i)+"\r\n";}return O;case "x":int x=0;string[]r=new string[n];for(int i=n;i>0;i--){if(n-x-x<0){O+="x".PadLeft(x+1)+"\r\n";break;}string row=string.Join("",Enumerable.Repeat(" ",x))+"x"+string.Join("",Enumerable.Repeat(" ",n-x-x))+"x"+"\r\n";O+=row;x++;r[x]=row;if(i==n/2)break;}for(int i=r.Length-1;i>0;i--){if(string.IsNullOrEmpty(r[i]))continue;O+=r[i];}return O;default:return "";}}

Ungolfed:

public string A(string s, int n)
{
  string O = "";

  Func<string, int, string> R = (a, b) =>
  {
    return string.Join("", Enumerable.Repeat(a, b)) + "\r\n";
  };

  switch (s)
  {
    case "+":
      for (int i = 0; i < n; i++)
      {
        if (i == n / 2)
        {
          O += R("+", n);
        }
        else
        {
          O += "+".PadLeft(n - n / 2, ' ').PadRight(n - n / 2, ' ') + "\r\n";
        }
      }
      return O;
    case "=":
      return R("=", n) + R("=", n);
    case "-":
      return R("-", n);
    case "/":
      for (int i = n; i > 0; i--)
      {
        O += "/".PadLeft(i) + "\r\n";
      }
      return O;
    case "x":
      int x = 0;
      string[] r = new string[n];
      for (int i = n; i > 0; i--)
      {
        if (n - x - x < 0)
        {
          O += "x".PadLeft(x + 1) + "\r\n";
          break;
        }
        string row = string.Join("", Enumerable.Repeat(" ", x))
          + "x"
          + string.Join("", Enumerable.Repeat(" ", n - x - x)) + "x" + "\r\n";
        O += row;
        x++;
        r[x] = row;
        if (i == n / 2)
          break;
      }
      for (int i = r.Length - 1; i > 0; i--)
      {
        if (string.IsNullOrEmpty(r[i]))
          continue;
        O += r[i];
      }
      return O;
    default:
      return "";
  }
}

Teste:

+: 3, 5, 7, 9, 11
/: 7, 8, 9, 10
-: 3, 4, 5, 6
=: 3, 4, 5, 6, 7
x: 5, 7, 9, 11

Demais para colar e formatar aqui, criei um pastebin:

Pastebin

Pete Arden
fonte
Golf-o e forneça uma contagem de bytes.
mbomb007
2

C, 331 bytes

i,j;f(o,n){if(47==o)for(i=n;i;puts("")){for(j=i--;j--;putchar(j?32:o)){}}
if(43==o)for(i=n;i--;puts("")){for(j=n;j--;printf(i==n/2||!j?"+ ":" ")){}}
if(45==o)for(i=n;i--;putchar(o)){}
if(61==o)for(i=3;i--;puts("")){for(j=n;j--;putchar(i&1?32:o)){}}
if(120==o)for(i=n;i;puts("")){for(j=0;j++<n;putchar(j==i||j==n-i+1?o:32)){}i--;}}

O operador é passado como código ASCII oe a contagem de caracteres n. Eu apenas adicionei espaços entre caracteres consecutivos horizontalmente no sinal de mais, já que este era o único onde a saída teria sido distorcida se eu não tivesse e na tarefa que apenas dizia "deveria". Eu uso dois loops aninhados em contagem regressiva (exceto para- onde eu só preciso de uma linha).

= Três linhas, uma delas vazia, para a frente

+ usando printf por causa dos espaços

- direto

/ faça o loop interno imprimir em zero e comece no balcão do loop externo

x imprima o loop interno no balcão do loop externo e seu "inverso" n-i . Ainda preciso ver por que estou aqui um por um.

Exemplo de chamada:

#include <stdio.h>
/*  =       61
    +       43
    -       45
    /       47
    Space   32
    x       120
*/
int main(int argc, char **argv){
    printf("%s\n%s\n",argv[1], argv[2]);
    f(*argv[1],strtol(argv[2],NULL,10));
}
Florian
fonte
1

Lua, 402 344 312 bytes

312:

r,p,b,x=string.rep,print,' ','x'function d(s,n)h,l=(n+1)/2,s..b;e=r(l,n)if s=='-'then p(e)elseif s=='='then p(e)p(e)else for f=1,n do p(s=='/'and(r(b,n-f)..s)or s=='+'and(f~=h and r(' ',n-1)..'+'or r('+ ',n))or f<h and r(b,f-1)..x..r(b,n-2*f)..x or f>h and r(b,n-f)..x..r(b,2*f-2-n)..x or r(b,f-1)..x)end end end

344:

r,p,b,x=string.rep,print,' ','x'function d(s,n)h,l=(n+1)/2,s..b;e=r(l,n)if s=='-'then p(e)elseif s=='='then p(e)p(e)else for f=1,n do if s=='/'then p(r(b,n-f)..s)elseif s=='+'then p(f~=h and r(' ',n-1)..'+'or r('+ ',n))elseif s=='x'then p(f<h and r(b,f-1)..x..r(b,n-2*f)..x or f>h and r(b,n-f)..x..r(b,2*f-2-n)..x or r(b,f-1)..x)end end end end

402:

r,p,b,x=string.rep,print,' ','x'function d(s,n)h=(n+1)/2;if s=='-'then p(r(s..b,n))end;if s=='='then p(r(s..b,n))p(r(s..b,n))end;if s=='/'then for i=1,n do p(r(b,n-i)..s)end end;if s=='+'then for i=1,n do p(i~=h and r(' ',n-1)..'+'or r('+ ',n))end end;if s=='x'then for i=1,n do if i<h then p(r(b,i-1)..x..r(b,n-2*i)..x)elseif i>h then p(r(b,n-i)..x..r(b,-n+2*i-2)..x)else p(r(b,i-1)..x)end end end end

90 caracteres reduzidos e agora é doloroso olhar mesmo quando expandido. : |

Blab
fonte
"Parece também que este é um desafio antigo. Ops" Não há nada de errado em responder aos desafios antigos.
Steadybox