Генерация ASCII-линейки


11

Задача состоит в том, чтобы сгенерировать линейку ASCII-символов в следующем формате:

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

Длина линейки должна быть масштабируемой до любого кратного 10.

Правила:

  • Линейка должна быть горизонтальной.
  • Скажем, для простоты, линейка должна работать до отметки 1000, все числа выровнены по левому краю, через один пробел после последнего числа .
  • При запросе линейки с нулевой длиной следует напечатать NaR
  • Отрицательные числа должны печатать перевернутую линейку (-90, -80, -70, ...) с выровненными по правому краю числами в том же формате, что и выше, в противном случае

И, просто печать на консоль в порядке

Готово, установлено, гольф!


Как программа узнает, как долго делать линейку? Предоставляется ли он как номер на STDIN?
PhiNotPi

Да, как обычно, я думаю!
user2398029

1
Должна ли линейка быть горизонтальной или вертикальной? если он горизонтальный, можем ли мы принять максимум 80 символов, или мы выводим это в файл, чтобы избежать переноса? или мы должны изменить размер консоли / терминала при записи в стандартный вывод?
Блейзер

5
Одним из основных моментов Code-Golf является то, что проблема должна быть определена на 100% (см. Часто задаваемые вопросы ). В фактическом выводе мало места для творчества, потому что творчество в самом коде. В будущем, пожалуйста, постарайтесь продумать все эти возможные случаи, прежде чем публиковать вопрос, но, поскольку вы новичок, мы помогаем вам :)
mellamokb

3
Не могли бы вы отредактировать задачу, чтобы включить правила, указанные в комментариях?
Флеш

Ответы:


8

Питон - 227 232

Поддерживает всю спецификацию

редактировать: улучшено выражение генератора.

Поддержка выровненных по правому краю отрицательных чисел добавляет удивительный объем кода.

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]

Пример выходов:

-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 |
|                                                        |
+--------------------------------------------------------+

10

Не буду бить динамические языки сегодня, но все равно ...

Хаскелл, 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

Я позволил себе сменить настоящие символы ASCII на более привлекательные символы рисования юникодных блоков.

$ echo "-50 30" | runhaskell  def0.hs
┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
│  │    │    │    │    │    │    │    │    │    │    │    │    │    │    │    │    │  │
│-50       -40       -30       -20       -10         0         10        20        30 │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘

2
Правитель выглядит очень, очень красиво.
user2398029

3

Python 2,7, 342 266 260 символов

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

возвращает кортеж каждой строковой строки, которую вы можете затем распечатать или сохранить в файл (я предпочитаю последний для длин более 70, потому что консоль просто заставит ее выглядеть испорченной с переносом)

Предполагается, yчто это строка (raw_input () n python или sys.argv [1], если вы хотите вызвать через cmd) целое число (например, с input () в 2.x или int (input ()) в 3.x )

Я сделал это функцией, чтобы быть более гибким

редактировать: уменьшено до 266 символов. больше не возвращает кортеж, а вместо этого строку. Теперь принимает целое число вместо строки в качестве аргумента

edit2: уменьшено до 260 символов, функция одной строки

примечание: обрабатывает отрицательные числа, но не оправдывает правильность (я не думаю, что обоснование слишком важно в любом случае


Или просто используйте не ломающуюся консоль (например, Terminator ).
перестал поворачиваться против часовой стрелки с

@leftaroundabout Я не был уверен, что такая вещь существовала
Blazer

независимо от того, нужно ли устанавливать отдельную платформу просто для того, чтобы сделать линейку довольно бесполезной, поскольку создание возвращаемого значения, которое любой может использовать (запись в файл и т. д.), более универсально
Blazer

@Blazer, в вашей оболочке нет каналов и перенаправлений?
Питер Тейлор

1

PowerShell , 256 253 233 225 222 байта

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]

Попробуйте онлайн!

Меньше гольфа:

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]

0

Python, 291 241 символов

Довольно простой подход. Я уверен, что это может быть улучшено довольно много.
Я пытался следовать рекомендациям в комментариях, но я не поддерживаю отрицательные числа (это была шутка, я надеюсь).
Это программа, выводящая линейку на стандартный вывод. Если ваш экран достаточно широк, он должен поддерживать довольно длинные линейки.

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"

Вы можете сыграть в гольф еще несколько персонажей из этого. Я сбрил 12 персонажей здесь
Гордон Бейли,

Спасибо @GordonBailey, но в любом случае уже есть победитель, который короче моего кода и поддерживает полную спецификацию.
Угорен

0

С ++, 392

Это запрограммировано с помощью консоли Windows, поэтому я просто выбрал максимальный размер линейки, равный 70, он просто рухнет для чего-то большего. Отрицательные числа (до -70) и 0 обрабатываются правильно.

#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]);}

0

Питон - 208

(не поддерживает выравнивание по правому краю отрицательных чисел)

 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"

Я думаю, что мой любимый трюк состоял в том, чтобы генерировать строки, которые намного длиннее, чем необходимо, а затем обрезать их, например:

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

Я просто хотел бы, чтобы была более краткая опция форматирования строки для выравнивания по левому краю (если только я не знаю о ней)


0

Perl 5.14, 198 224 символа

Вероятно, может быть сокращено намного дальше, но вот первая вторая попытка (с разрывами строки, вставленными для удобства чтения):

$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

РЕДАКТИРОВАТЬ: Отредактировано, чтобы умереть с «NaR», когда вход 0и поддерживает отрицательный диапазон.

РЕДАКТИРОВАТЬ 2: У меня не было возможности поработать над этим, и я только сейчас заметил правило выравнивания по правому краю для отрицательных чисел, которое не поддерживается в моем коде, поэтому я думаю, что другое решение должно быть помечено как ответ, если срок был достигнут.


@louism: мой ответ не соответствует всем правилам. Другой ответ должен быть выбран, если это возможно.
flesk
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.