Exibir palavras usando a exibição de 7 segmentos

13

Meu primeiro quebra-cabeça de programação e código de golfe é o Seven-Slash Display . Aqui está o meu primeiro desafio, também baseado em 7 segmentos.

Costumo pensar, além dos números, em que tipo de letras posso exibir usando um simples display de 7 segmentos. Acontece que muitas letras podem ser exibidas. De fato, todas as letras, exceto K, M, V, W, X, podem ser exibidas usando uma única tela de 7 segmentos. Isso ocorre porque você pode exibir letras minúsculas ou maiúsculas. por exemplo

"abcdef" pode ser exibido como

 _     _     _  _
!_!!_ !   _!!_ !_ 
! !!_!!_ !_!!_ !  

Observe que cada caractere é uma matriz 3x3 composta por !e _.

Obviamente, a tela de 7 segmentos pode ser usada para exibir números e símbolos:

 _     _  _  _           _  _     _    
  ! _ !_ !_ !      _!  !!_ !_!!  !_!!_!
  !    _!!_ !_!   !_!  ! _!!  !_ ! ! _!

Algumas letras podem ter letras maiúsculas e minúsculas:

 _                 _          
!   _ !_!!_   !   ! ! _ ! !   
!_ !_ ! !! !  !  !!_!!_!!_!!_!

Aqui está o conjunto completo de caracteres:

 _     _  _     _  _  _  _  _                       _
! !  ! _! _!!_!!_ !_   !!_!!_!    _ !_     _     _  _!
!_!  !!_  _!  ! _!!_!  !!_! _!   !_ ! !  !!_!!_!   !  

 _     _     _  _  _                 _  _  _     _           _ 
!_!!_ !   _!!_ !_ !  !_!  !  !!   _ ! !!_!!_! _ !_ !_ ! !!_! _!
! !!_!!_ !_!!_ !  !_!! !  !!_!!_ ! !!_!!    !!   _!!_ !_! _!!_ 

Preste atenção que há um espaço em branco ( ), um traço ( -) e um ponto de interrogação ( ?). A carta I, Oe Zsão os mesmos que os números 1, 0e 2, respectivamente.

Neste desafio, você escreverá um programa ou uma função para exibir uma string usando o formato de exibição de 7 segmentos acima.

Regras

  1. Você pode escrever um programa ou uma função

  2. Isso é código-golfe, o código mais curto em bytes vence

  3. Seu programa ou função deve receber a entrada do STDIN ou como parâmetro. E gera uma string para STDOUT ou como uma string em 3 linhas sem espaço à esquerda, mas finalizada com nova linha. Manuseie as letras maiúsculas / minúsculas CHIOUcorretamente.

  4. Opcionalmente, você pode imprimir espaços em branco à direita

  5. Você deve seguir o formato acima. Usando sublinhado _e ponto de exclamação !para formar sua exibição de 7 segmentos.

  6. Você deve oferecer espaço em branco ( ), traço ( -) e ponto de interrogação ( ?)

  7. Se a sequência contiver caracteres não suportados (k, m, v, w, x), um único caractere de erro (3 linhas horizontais, veja o exemplo) será exibido. Além dos 5 caracteres não suportados, você pode assumir que a entrada é composta apenas por um conjunto de caracteres suportado.

  8. Optei por não ter uma letra para L ( l) em minúsculas devido a confusões, mas se você estiver inclinado, poderá exibi-la como uma 1à direita ou à esquerda.

Exemplos

$./a.out Start
 _     _    
!_ !_ !_! _ !_
 _!!_ ! !!  !_
$./a.out "7-seg dIsplay"
 _     _  _  _           _  _     _ 
  ! _ !_ !_ !      _!  !!_ !_!!  !_!!_!
  !    _!!_ !_!   !_!  ! _!!  !_ ! ! _!
$./a.out "0123456789 chiou-?"
 _     _  _     _  _  _  _  _                       _
! !  ! _! _!!_!!_ !_   !!_!!_!    _ !_     _     _  _!
!_!  !!_  _!  ! _!!_!  !!_! _!   !_ ! !  !!_!!_!   !
$./a.out "ABCDEFGHIJLNOPQRSTUZ"
 _     _     _  _  _                 _  _  _     _        _
!_!!_ !   _!!_ !_ !  !_!  !  !!   _ ! !!_!!_! _ !_ !_ ! ! _!
! !!_!!_ !_!!_ !  !_!! !  !!_!!_ ! !!_!!    !!   _!!_ !_!!_
$./a.out "abcdefghijlnopqrstuz"
 _           _  _  _                    _  _     _        _
!_!!_  _  _!!_ !_ !  !_      !!   _  _ !_!!_! _ !_ !_     _!
! !!_!!_ !_!!_ !  !_!! !  !!_!!_ ! !!_!!    !!   _!!_ !_!!_
$./a.out "Bad Form"
 _
 _
 _
$./a.out "Hello"
    _       
!_!!_ !  !   _
! !!_ !_ !_ !_!
$./a.out "World"
 _
 _
 _
algum usuário
fonte
Sim, você pode assumir que não há símbolos não suportados. Minha intenção é garantir que as seqüências que contêm k, m, v, w, xnão sejam exibidas.
algum usuário
Eu acho que você confundiu retorno de carro (CR \r) com avanço de linha (LF, \n). * nix usa LF e Windows usa CRLF. Apenas certos sistemas legados usam o CR por si só. Mais informações aqui: en.wikipedia.org/wiki/Newline
Winny
Seu personagem "8" parece ter uma barra "|" em vez de um ponto de exclamação "!". É pretendido?
Coredump
1
@ Winin, você está certo, é claro. Eu estava com preguiça de procurar quando escrevi.
algum usuário

Respostas:

7

CJam, 123 114 112 110 bytes

Qq_eu";=KMVWX":T&"@"@?" -chiou"Tereu{i"^A^W^G;^Þ¯     ^Þ^Û9³·^É¿»
^@
^P
^Ü^Ò½7¦^_¶´§=   ^O^V&5^U¯¼¹^T³6/"=i2b9Ue[3/"!_!"f.{S?}.+}/N*

O exemplo acima usa notação de intercalação, pois o código contém caracteres não imprimíveis. Um deles é um byte nulo ( ^@), o que significa que esse código só pode ser executado a partir da linha de comando.

Ao custo de apenas mais dois bytes (para um total de 112 ), podemos corrigir isso.

Qq_eu";=KMVWX":T&"@"@?" -chiou"Tereu{i"AWG{ÞïIÞÛyó÷Éÿû
@
P
ÜÒýwæ_öôç}IOVfuUïüùTóvo"=i448+2b1>3/"!_!"f.{S?}.+}/N*

Desta vez, todos os caracteres são imprimíveis. Experimente on-line no intérprete CJam .

Exemplo de execução

$ LANG=en_US
$ xxd -ps -r > 7seg.cjam <<< 51715f6575223b3d4b4d565758223a5426224022403f22202d6368696f752254657265757b69220117073b9eaf099e9b39b3b789bfbb0a000a100a9c92bd37a61fb6b4a73d090f16263515afbcb914b3362f223d6932623955655b332f22215f2122662e7b533f7d2e2b7d2f4e2a
$ wc -c 7seg.cjam 
110 7seg.cjam
$ echo -n '0123456789 chiou-?' | cjam 7seg.cjam; echo
 _     _  _     _  _  _  _  _                       _ 
! !  ! _! _!!_!!_ !_   !!_!!_!    _ !_     _     _  _!
!_!  !!_  _!  ! _!!_!  !!_! _!   !_ ! !  !!_!!_!   !  
$ echo -n 'ABCDEFGHIJLNOPQRSTUYZ' | cjam 7seg.cjam; echo
 _     _     _  _  _                 _  _  _     _           _ 
!_!!_ !   _!!_ !_ !  !_!  !  !!   _ ! !!_!!_! _ !_ !_ ! !!_! _!
! !!_!!_ !_!!_ !  !_!! !  !!_!!_ ! !!_!!    !!   _!!_ !_! _!!_ 
$ echo -n 'World' | cjam 7seg.cjam; echo
 _ 
 _ 
 _

Ideia (versão para impressão)

Cada caractere pode ser mostrado no visor de 9 segmentos

!_!
!_!
!_!

substituindo alguns de seus caracteres por espaços.

Podemos transformar um caractere específico em um número inteiro substituindo cada segmento mostrado, em ordem de leitura natural, por 1 , cada segmento não mostrado com 0 e considerando os dígitos binários do resultado.

O primeiro e o terceiro segmento nunca são mostrados, portanto, isso produzirá números inteiros nos intervalos [0,64) e [128,192) .

Podemos codificar cada um desses números inteiros como um único byte, mas metade deles resultará em caracteres não imprimíveis. Assim, adicionamos 64 a cada número inteiro antes de converter o caractere, o que garante que os pontos de código estejam nos intervalos [64,128) e [192,256) .

O único caractere não imprimível nesses dois intervalos é DEL (ponto de código 127), que corresponde à seguinte configuração de exibição não impressa:

!_!
!_!

Podemos reverter a codificação acima adicionando 448 == 512 - 64 a cada ponto de código, convertendo para a base 2 e removendo o primeiro dígito binário.

Tudo o que resta para encontrar uma maneira eficiente de associar esses segmenets codificados aos seus caracteres ASCII correspondentes.

Se mapearmos os caracteres de " -chiou"para os caracteres de ";=KMVWX"e convertermos toda a entrada em maiúscula, podemos simplesmente armazenar a codificação para todos os caracteres entre 0(ponto de código 48) e Z(ponto de código 90), fornecendo um intervalo de 43.

A indexação de matrizes é modular no CJam, portanto, se Afor uma sequência de comprimento 43 A86=, A43=e A0=todas produzem os mesmos resultados. O caractere com o ponto de código 86 é V, então simplesmente armazenamos os segmentos codificados de V - Z e 0 - U , em ordem.

No código real, selecionamos o sinal de arroba como "formato incorreto", substituímos toda a entrada pela string "@"se ela contiver uma letra proibida e inverta as etapas acima.

Código (versão para impressão)

Q            e# Push an empty array for posterior concatenation.
q            e# Read from STDIN.
_eu          e# Copy the input and convert is to uppercase.
";=KMVWX":T& e# Intersect the result with with T := ";=KMVWX".
"@"@?        e# Select "@" if truthy and the input if falsy.
" -chiou"Ter e# Perform transliteration.
eu           e# Convert everything to uppercase.
{            e# For each character in the modified input:
  i          e#   Push its code point.
  "…"=       e#   Select the corresponding character from the string.
  i448+      e#   Push that character's code point and add 448.
  2b1>       e#   Convert to base 2 and discard the first digit.
  3/         e#   Group into triplets of digits (rows).
  "!_!"      e#   Push that string.
  f.{        e#   For each group of digits:
    S?       e#     Select the corresponding char of "!_!" for 1 and " " for 0.
  }          e#
  .+         e#   Concatenate along the rows with the previous results.
}/           e#
N*           e# Join, separating by linefeeds.
Dennis
fonte
2

Perl, 475 469 424 390 280 272 bytes

$_=<>;die" -
"x3if/[kmvwx]/i;y/chiou/kmvwx/;$_=lc;while(/(.)/g){$z=ord($1=~y/a-z0-9\-\? /{v\x17nWS7z(.F\x16rb?[yBuV> f&|O?(Omxuw)\x7f}@K\0/r);$i.=$z&1?' _ ':$"x3;$m.=($z&16?'!':$").($z&64?'_':$").($z&8?'!':$");$p.=substr("  !  _!_",$z&6,2).($z&32?'!':$")}print"$i
$m
$p
"

multilinhas com comentários:

$_=<>;   # accept input
die" -   # check for invalid chars
"x3if/[kmvwx]/i;
y/chiou/kmvwx/;$_=lc;   # substitute invalid chars, convert to lowercase
while(/(.)/g)   # loop over each character
    # lookup character from string using transliteration and convert to
    # number using ord() for bit checking:
    {$z=ord($1=~y/a-z0-9\-\? /{v\x17nWS7z(.F\x16rb?[yBuV> f&|O?(Omxuw)\x7f}@K\0/r);
    $i.=$z&1?' _ ':$"x3;    # first row
    $m.=($z&16?'!':$").($z&64?'_':$").($z&8?'!':$");   # second row
    $p.=substr("  !  _!_",$z&6,2).($z&32?'!':$")}    # third row
# print result:
print"$i
$m
$p
"

Os padrões de bits que codificam os segmentos são armazenados em uma string (escapando de 3 caracteres não imprimíveis usando \xe usando \0espaço) e são mapeados para os caracteres de entrada usando o operador de transliteração Perl.

Para 5 dos 7 segmentos, um bit a bit e é usado junto com o operador ternário para gerar um espaço ou o caractere de segmento. Para os dois segmentos inferior esquerdo (codificados por 2 e 4 no conjunto de bits), uma pesquisa de substring em uma cadeia de 8 caracteres é usada para salvar 2 bytes.

Obrigado a Dom Hastings por suas dicas de golfe em Perl.

Versão antiga (usando expressões regulares para codificar os padrões), 390 bytes:

$_=<>;if(/[kmvwx]/i){print" -\n"x3;exit}y/chiou/kmvwx/;$_=lc;while(/(.)/g){$z=$1;$i.=($z=~/[acefgopqsz\?0235-9]/?' _ ':'   ');$m.=($z=~/[abce-hlmopqstuy045689]/?'!':' ').($z=~/[abdefhkmnp-twyz\-\?2-689]/?'_':' ').($z=~/[adhijopquyz\?0-4789]/?'!':' ');$p.=($z=~/[a-hj-prtuwxz\?0268]/?'!':' ').($z=~/[b-egjklostuw-z0235689]/?'_':' ').($z=~/[abdg-jmnoqsu-y013-9]/?'!':' ')}print"$i\n$m\n$p\n"

multilinhas com comentários:

$_=<>;   # accept input
if(/[kmvwx]/i){print" -\n"x3;exit}   # check for invalid chars
y/chiou/kmvwx/;$_=lc;   # substitute invalid chars, convert to lowercase
while(/(.)/g)
{$z=$1;$i.=($z=~/[acefgopqsz\?0235-9]/?' _ ':'   '); # first row
$m.=($z=~/[abce-hlmopqstuy045689]/?'!':' ').
($z=~/[abdefhkmnp-twyz\-\?2-689]/?'_':' ').
($z=~/[adhijopquyz\?0-4789]/?'!':' '); # second row
$p.=($z=~/[a-hj-prtuwxz\?0268]/?'!':' ').
($z=~/[b-egjklostuw-z0235689]/?'_':' ').
($z=~/[abdg-jmnoqsu-y013-9]/?'!':' ')} # third row
print"$i\n$m\n$p\n" # print result

A sequência é lida e verificada quanto a caracteres inválidos usando um regex, saindo se houver algum. Os caracteres minúsculos permitidos são substituídos pelos caracteres inválidos e a string inteira é convertida em minúsculas.

As linhas são geradas uma de cada vez, com 1 segmento por letra na primeira linha e 3 nas outras duas. Para cada linha, a sequência é processada um caractere de cada vez e o caractere é comparado a uma expressão regular para cada segmento para verificar se a! ou _ deve ser exibido. O uso de uma regex significa que, para caracteres em que o segmento não está definido, são necessários zero bits por segmento por caractere para codificá-lo, ou seja, para aqueles em que está, são necessários um pouco menos de 8 bits, em média, porque os intervalos de caracteres de expressão regular podem ser usava. Portanto, funciona em torno de 3 ou 4 bits por segmento por caractere no conjunto, ou em torno de 21 a 24 bits por caractere.

Ele não lida com quebra de linha.

samgak
fonte
1
Hey @sgagak, feliz em ver mais amor Perl! Percebi algumas coisas que poderiam ajudá-lo a economizar alguns bytes e queria compartilhá-los! Você pode usar algumas das variáveis ​​mágicas do Perl para ajudar a reduzir isso; ' 'pode ser substituído por $"e ' 'pode ser o $"x3que apara alguns, seus \ns podem ser novas linhas literais para se livrar de mais alguns. Sua saída antecipada também pode ser curta, usando die, para que isso if(/[kmvwx]/i){print" -\n"x3;exit}se torne die" - "x3if(/[kmvwx]/i). Com um pouco mais de falsificação, você também pode reorganizar o loop para evitar os colchetes e não precisa $zeconomizar mais!
Dom Hastings
1
Espero que você não esteja ofendido, mas tentei reduzir mais, gist.github.com/dom111/e651b5de8c7e7fc9a6cf . Até 323!
Dom Hastings
@DomHastings sem ofensas, obrigado pelas ótimas dicas de golfe! Eu usei o maior número possível na minha resposta editada, que mudei para usar a codificação bit a bit em vez de expressões regulares para os padrões de segmento. Infelizmente, o $ z está de volta e não consigo descobrir como me livrar dele. Além disso, $_=lc<>não trabalho, porque então o código não pode discriminar entre maiúsculas e minúsculas Chiou
samgak
1

Lisp comum, 488 416

(lambda(z)(dotimes(r 3)(map()(lambda(c)(do((i 0(+ 17 i))n)((or(and(> i 901)(setf n 146))(=(char-code c)(ldb(byte 8 9)(setf n(ldb(byte 17 i)#36RIL884OIVFXJY4DCQ0O8DPH8MOMR2DSLPP3O4ESYHS234A9HEQYSV8IBDBZI6Z3C3MCVR77OYD3QN5G6CX2UQWGL4UY5R9PKYI1JQ5Y6DC27MQQGUZSCGI8Q9JCYP9N1L4YYKRWM1ZNMSVTSB4792UUWV6Z3906VSP981WCCBMDNJ02)))))(loop for v from(* 3 r)for d across"!_!"do(format t"~:[ ~;~A~]"(logbitp v n)d)))))z)(terpri)))

Exemplo

Com "abcdefg'hijklnopqrstuz", imprime:

 _           _  _  _  _           _           _  _     _        _ 
!_!!_  _  _!!_ !_ !   _ !_   !  ! _ !   _  _ !_!!_! _ !_ !_     _!
! !!_!!_ !_!!_ !  !_! _ ! !  !!_! _ !_ ! !!_!!    !!   _!!_ !_!!_ 

Observações

Os caracteres e suas representações são codificados neste número na base 36:

IL884OIVFXJY4DCQ0O8DPH8MOMR2DSLPP3O4ESYHS234A9HEQYSV8IBDBZI6Z3C3MCVR77OYD3QN5G6CX2UQWGL4UY5R9PKYI1JQ5Y6DC27MQQGUZSCGI8Q9JCYP9N1L4YYKRWM1ZNMSVTSB4792UUWV6Z3906VSP981WCCBMDNJ02

A representação binária desse dígito é dividida em grupos de 17 bits.

Por exemplo, o último grupo de 17 bits 110000111101010é decomposto aqui em duas partes:

  1. 110000, o código de caractere 0
  2. 111101010, uma codificação do desenho, melhor representada da seguinte maneira:

    010 (bits 0-2)         _ 
    101 (bits 3-5)   =>   ! !
    111 (bits 6-8)        !_!
    

    Os bits na primeira e na última "coluna" são para !caracteres, os da coluna do meio para o _caractere. Quando necessário, as versões maiúsculas e minúsculas de um caractere são armazenadas.

A função itera três vezes sobre a sequência de entrada, uma para cada linha de saída, procura um caractere correspondente na tabela (ou o padrão é 146, também conhecido como três barras) e imprime a representação na linha atual.

coredump
fonte
Obrigado por participar do desafio. Notei que o seu 'K' é exibido como 'L' na sua saída. Você pode ter entendido mal o requisito de que caracteres não suportados não possam ser impressos junto com outros caracteres válidos. Além disso, vejo que você adicionou o 'personagem, o que é legal; no entanto, ele será exibido fora do que uma tela de 7 segmentos é capaz. Se você mover o !down em 1 linha, seria perfeito.
algum usuário
Vou atualizar o 'caractere e editar a pergunta Kporque, de fato, coloquei o Klugar errado na string de entrada ("... jlKn ...") ;-) Você pode ver as barras triplas (erro) apenas depois do L. Obrigado por perceber.
Coredump
1

JavaScript (ES6), 380 352 324 bytes

( Nota: O código usa notação de intercalação, pois contém alguns caracteres não imprimíveis. Para obter o código original, clique aqui e selecione os dados brutos. E não, hnão é um programa CJam.;)

d=s=>{a=' ',u=n=>r>>n&1?'!':a,v=n=>r>>n&1?'_':a,g='ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz0123456789-? ÿ',h='{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)^??^BK^0^G',x=y=z='';for(i=0;i<s.length;x+=a+v(0)+a,y+=u(4)+v(1)+u(3),z+=u(6)+v(2)+u(5)){q=g.indexOf(s[i++]);if(q<0)return d`ÿ`;r=h.charCodeAt(q)}return x+`
${y}
`+z}

Chamado como d("7-seg display")ou similar. Funciona no Firefox 40, mas pode não estar em outros navegadores. Por alguma razão, o snippet HTML / JS não salva os não imprimíveis, mas você pode copiar e colar os dados brutos daqui .

Ungolfed:

( Nota: g e hforam preenchidos com espaços para combinar 8, -, ÿe spacecom seus valores Unicode correspondentes.)

d = function (s) {
  t = function (n) { return Math.floor(n) % 2; };
  g = 'ABCDEFGHIJLNOPQRSTUYZabcdefghijlnopqrstuyz012345679? 8      -      ÿ      space ';
  h = '{vUnWSuz(lTb}[;B7V|>O{vFnWSur lTbf[;B7Vd>O}(O/:7w)?K \u007f \u0002 \u0007 \u0000';
  x = y = z = '';
  for(var i = 0; i < s.length; i++) {
    q = g.indexOf(s.charAt(i));
    if (q < 0)          // if g does not contain the character
      return d('ÿ');    // ÿ is equivalent to the error character, '\u0007'
    r = h.charCodeAt(q);
    x += ' ' + (r % 2 === 1 ? '_' : ' ') + ' ';
    y += (t(r / 16) === 1 ? '!' : ' ') + (t(r / 2) === 1 ? '_' : ' ') + (t(r / 8) === 1 ? '!' : ' ');
    z += (t(r / 64) === 1 ? '!' : ' ') + (t(r / 4) === 1 ? '_' : ' ') + (t(r / 32) === 1 ? '!' : ' ');
  }
  return x + '\n' + y + '\n' + z;
}

Explicação:

Percebi imediatamente que os 7 segmentos, convertidos em 0/ 1bits, combinariam bem com os primeiros 128 caracteres Unicode. O problema com essa idéia é que 1/4 desses caracteres são caracteres de controle não imprimíveis. Usá-los no meu código faria com que parecesse incrivelmente bagunçado (ou incrivelmente inteligente; ainda não decidi qual). Para resolver isso, mantendo o restante do código simples, surgiu a seguinte idéia:

Com a excepção de -, espaço , e erro , nenhum dos caracteres faltavam ambos os segmentos verticais inferiores. Portanto, para garantir que todos esses caracteres fiquem entre 0020e 007f, simplesmente mapeei os 64 e 32 bits para esses segmentos, da seguinte forma:

     1
    ---
16 |   | 8
  2 ---
64 |   | 32
    ---
     4

Os números dos outros 5 segmentos não são muito importantes; eles podem ser organizados de qualquer outra maneira e ainda ter os mesmos caracteres "dentro dos limites".

Como exemplo, aqui está a versão codificada de A :

     1
    ---
16 |   | 8
  2 ---
64 |   | 32

Dec: 64 + 32 + 16 + 8 + 2 + 1 = 123
Hex: 40 + 20 + 10 + 8 + 2 + 1 = 7B = u+007B = {

Em seguida, coloquei a versão codificada de cada caractere 7-seg h. No entanto, 8resultou em 007f(o código de controle de exclusão ; constante, independentemente de como os segmentos estão organizados), o espaço resultou em 0000(o código nulo ; também constante), -resultou em 0002e resultou em erro0007 . Copiei e colei os bytes brutos na posição correta para8 , -e erro ; espaço foi facilmente alcançado com \0.

Depois de toda essa codificação, tudo que eu precisava fazer era usá-lo para decodificar a string e produzi-la em um formato legível em 7 seg. Eu usei uma por laço e três variáveis ( x, y, ez , cada um correspondente a uma linha de saída) para passar por cada carácter na cadeia e adicionar o seu equivalente 7-seg para a saída. Eu escolhi ÿo caractere de erro porque o AFAIK não está em nenhum teclado e é o último caractere no u+0000-u+00ffintervalo. Talvez eu pudesse ter sido espirituoso e escolhido Ξ(letra grega xi) ...;)

Editar 1: Salvo um grupo de espaço, criando mini-funções para determinar se !, _ou é necessário.

Editar 2: economizei muito mais espaço usando os truques que aprendi desde a última vez que visitei este post.

Como sempre, as sugestões são muito apreciadas!

ETHproductions
fonte