Geração de régua ASCII

11

O desafio é gerar uma régua de contagem de caracteres ASCII no seguinte formato:

+-------------------------------------------------------------------------+
||    |    |    |    |    |    |    |    |    |    |    |    |    |    |  |
|0         10        20        30        40        50        60        70 |
|                                                                         |
+-------------------------------------------------------------------------+

O comprimento da régua deve ser escalável para qualquer múltiplo de 10.

Regras:

  • A régua deve estar na horizontal.
  • Digamos, para simplificar, que a régua deve funcionar até a marca 1000, todos os números alinhados à esquerda, um espaço após o número final .
  • Solicitar uma régua com comprimento zero deve imprimir NaR
  • Os números negativos devem imprimir uma régua invertida (-90, -80, -70, ...) com números alinhados à direita, exatamente no mesmo formato que o acima, caso contrário

E apenas imprimir no console é bom

Pronto, jogo, golfe!

user2398029
fonte
Como o programa sabe quanto tempo faz a régua? É fornecido como um número no STDIN?
PhiNotPi
Sim, como sempre, eu acho!
user2398029
1
A régua precisa ser horizontal ou vertical? se for horizontal, podemos assumir um máximo de 80 caracteres ou enviaremos isso para um arquivo para evitar o agrupamento? ou precisamos redimensionar o console / terminal ao escrever no stdout?
Blazer
5
Um dos principais pontos do code-golf é que o problema deve ser 100% especificado sem ambiguidade (consulte as perguntas frequentes ). Há pouco espaço para criatividade na saída real, porque a criatividade está no próprio código. No futuro, por favor, tente pensar em todos esses casos possíveis antes de postar a pergunta, mas desde que você é novo, estamos ajudando você :)
mellamokb
3
Você poderia editar o desafio para incluir regras especificadas nos comentários?
Flesk

Respostas:

8

Python - 227 232

Suporta especificação inteira

editar: melhor expressão do gerador.

O suporte a números negativos alinhados à direita adiciona uma quantidade surpreendente de código.

b,p,d,w,='|+- '
g=input
s=''.join(('%'+d[:i>0]+'10s')%i+['',9*w][i==0] for i in range(g(),g()+1,10)).strip()+w
m,n=s[0]==d and s.find(w)-1,len(s)
t=p+n*d+p
print['\n'.join([t,b+(w*m+'|    '*n)[:n]+b,b+s+b,b+n*w+b,t]),'NaR'][n<9]

Saídas de amostra:

-30 30

+-----------------------------------------------------------------+
|  |    |    |    |    |    |    |    |    |    |    |    |    |  |
|-30       -20       -10         0         10        20        30 |
|                                                                 |
+-----------------------------------------------------------------+

-30 -30

NaR

100 150

+------------------------------------------------------+
||    |    |    |    |    |    |    |    |    |    |   |
|100       110       120       130       140       150 |
|                                                      |
+------------------------------------------------------+

-1000 -950

+--------------------------------------------------------+
|    |    |    |    |    |    |    |    |    |    |    | |
|-1000      -990      -980      -970      -960      -950 |
|                                                        |
+--------------------------------------------------------+
Steven Rumbalski
fonte
10

Não vou vencer as linguagens dinâmicas hoje, mas enfim ...

Haskell, 341

import Data.List
main=interact$unlines.m.map read.words
m[l,r]|r>l=ᴛ.("┌│││└":).(++["┬   ─","┐│││┘"]).ʀ.t.ʀ.t.takeWhile((>4).length).ᴛ$[c"┬",c"│    ",[l,l+10..r]>>=h.show,c" ",c"─"]|True=["NaR"]
h s=p s$length s;p s@('-':_)l=r(6-l)ꜱ++s++r 4ꜱ;p s l=r 5ꜱ++s++r(5-l)ꜱ
ᴛ=transpose;ʀ=reverse;r=replicate;c=cycle
ꜱ=' ';t l@(c:o)|c!!2==ꜱ=t o|True=l

Tomei a liberdade de trocar os caracteres ASCII reais com caracteres de desenho de caixa unicode mais bonitos.

$ echo "-50 30" | runhaskell  def0.hs
┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
│  │    │    │    │    │    │    │    │    │    │    │    │    │    │    │    │    │  │
│-50       -40       -30       -20       -10         0         10        20        30 │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘
deixou de girar contra-relógio
fonte
2
A régua parece muito, muito boa.
user2398029
3

Python 2.7, 342 266 260 caracteres

a,b,c,d,m='+|- \n'
def f(y):x=map(str,(range(0,y+1,10)if y>0 else range(y,1,10)));h,g=len(x[-1])+1,len(x)-1;u=a+(c*10)*g+c*h+a;return'NaR'if y==0 else u+m+b+(b+d*4)*2*g+b+d*(h-1)+b+m+b+''.join(i.ljust(10)for i in x[:-1])+x[-1].ljust(h)+b+m+b+(d*10)*g+d*h+b+m+u

retorna uma tupla de cada sequência de linhas , que você pode imprimir ou salvar em um arquivo (eu prefiro o último por comprimentos maiores que 70, pois o console apenas fará com que pareça bagunçado com o envolvimento)

Assume yser uma string (raw_input () n python ou sys.argv [1] se você desejar chamar via cmd) um número inteiro (por exemplo, com input () em 2.x ou int (input ()) em 3.x )

Eu fiz isso uma função para ser mais flexível

editar: reduzido para 266 caracteres. não retorna mais uma tupla, mas uma sequência. Agora pega um número inteiro em vez de uma sequência como argumento

edit2: reduzido para 260 caracteres, função de linha única

nota: lida com números negativos, mas não justifica corretamente (eu realmente não acho que a justificação seja muito importante de qualquer maneira

Blazer
fonte
Ou apenas use um console sem quebra de linha (por exemplo, Terminator ).
deixou de girar no sentido anti-
@leftaroundabout Eu não tinha certeza se isso existia #
Blazer
Independentemente disso, a necessidade de instalar uma plataforma separada apenas para fazer um inútil seemspretty governante, onde, como a criação de um valor de retorno que qualquer um poderia usar (gravação para um arquivo, etc) é mais universal
Blazer
@ Blazer, seu shell não possui pipes e redirecionamentos?
22412 Peter Taylor
1

PowerShell , 256 253 233 225 222 bytes

param($a,$b)('NaR',$($d=@{}
$a..$b|%{$d.$_=' ';0..($l=($s="$($_-$_%10)").Length-1)|%{$d[$_+$s-$l*(0-gt$s)]=$s[$_]}}
$d.Keys|sort|%{$e+='-';$p+='|    '[$_%5];$r+=$d.$_;$w+=' '}
@"
+$e-+
|$p |
|$r |
|$w |
+$e-+
"@))[$a-lt$b]

Experimente online!

Menos golfe:

param($a,$b)
(
    'NaR',
    $(
        # {key, value} := {position, digit|minus|space}
        $d=@{}
        $a..$b|%{
            $d.$_=' '

            # draw a nearest left number
            $n=$_-$_%10
            $s="$n"
            $l=$s.Length-1
            0..$l|%{
                $d[$_+$s-$l*(0-gt$s)]=$s[$_]
            }
        }

        # edge, points, ruler, whitespaces
        $d.Keys|sort|%{
            $e+='-'
            $p+='|    '[$_%5]
            $r+=$d.$_
            $w+=' '
        }

        # output the multiline string
@"
+$e-+
|$p |
|$r |
|$w |
+$e-+
"@
    )
)[$a-lt$b]
confuso
fonte
0

Python, 291 241 caracteres

Uma abordagem bastante simples. Tenho certeza que pode ser melhorado bastante.
Tentei seguir as orientações nos comentários, mas não apoio números negativos (era uma piada, espero).
Este é um programa, imprime a régua na saída padrão. Se sua tela for grande o suficiente, ela deverá suportar réguas muito longas.

import sys
def p(b,a="|"):print a+b+a
j="".join
l=int(sys.argv[1])//10*10
if l:
    d=j(["%-10d"%n for n in range(0,l,10)])+"%d "%l
    L=len(d)
    h="-"*L
    p(h,"+")
    p(j(["|    "[n%5] for n in range(L)]))
    p(d)
    p(" "*L)
    p(h,"+")
else: print "NaR"
Ugoren
fonte
Você pode golfe mais algumas personagens fora deste I raspado 12 caracteres aqui
Gordon Bailey
Obrigado @GordonBailey, mas já existe um vencedor de qualquer maneira, que é mais curto que o meu código e suporta a especificação completa.
ugoren
0

C ++, 392

Isso é programado usando o console do Windows, portanto, acabei de escolher um tamanho máximo de régua que é 70; ele trava para algo maior. Os números negativos (até -70) e 0 são tratados corretamente.

#include<ios>
#define q s[2][i
#define v ,memset(&s
char g,o,i,n,s[5][80];int main(int a,char**b){a=atoi(b[1])v,32,400);n=0<a;for(a=abs(a)v[0][1],45,a+3)v[4][1],45,a+3);i<a+4;++i)o=i-n,!(o%5)?s[1][n?i:i+3]='|',(o%2-1?(n?q]=i/10+48,i>9?q+1]=48:0:((a-i)>9?q+2]=(a-i)/10+48,q+1]=45:0,q+3]=48)):0):0;for(;g-5;g++)for(s[g][a+4]=s[g][i=0]=g&g-4?'|':43;i-80;i++)printf(a?"%c":g+i?"":"NaR",s[g][i]);}
Scott Logan
fonte
0

Python - 208

(não suporta números negativos alinhados à direita)

 l,u=map(int,raw_input().split())
 n=u-l
 q="+%s+\n"
 q=q+"|%s|\n"*3+q
 print q%('-'*n,(''.join("|    "for i in range(n)))[:n],(''.join("{:<10d}".format(i)for i in range(l,u,10)))[:n],' '*n,'-'*n)if n>0 else"NaR"

Eu acho que meu truque favorito era gerar strings muito mais longas do que o necessário e depois truncá-las, por exemplo:

 ''.join("|    "for i in range(n)))[:n]

Eu só gostaria que houvesse uma opção de formatação de string mais concisa para alinhamento à esquerda (a menos que exista uma que eu simplesmente não conheça)

Gordon Bailey
fonte
0

Perl 5.14, 198 224 caracteres

Provavelmente pode ser reduzido ainda mais, mas aqui está uma primeira segunda tentativa (com quebras de linha inseridas para facilitar a leitura):

$l=shift||die"NaR\n";
@n=grep!($_%10),$l>0?0..$l:$l..0;
$l=9-length$n[$#n];
@f=('-'x10,'|    'x2,'@'.'<'x9,' 'x10);
@f=map$_ x@n,@f;
map$_=~s/.{$l}$//,@f;
eval"format=\n+$f[0]+\n|$f[1]|\n|$f[2]|\n\@n\n|$f[3]|\n+$f[0]+\n.\n";
write

EDIT: Editado para morrer com "NaR" quando a entrada é 0e para suportar faixa negativa.

EDIT2: Não tive a chance de trabalhar mais nisso e só agora notei a regra alinhada à direita para números negativos, que meu código não suporta, por isso acho que outra solução deve ser marcada como a resposta, se o prazo foi atingido.

flesk
fonte
@ Louism: Minha resposta não está em conformidade com todas as regras. Outra resposta deve ser escolhida, se possível.
Flesk