Generowanie linijki ASCII

11

Wyzwanie polega na wygenerowaniu linijki liczenia znaków ASCII w następującym formacie:

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

Długość linijki powinna być skalowalna do dowolnej wielokrotności 10.

Zasady:

  • Linijka musi być pozioma.
  • Powiedzmy, aby uprościć sprawę, że linijka musi działać do znaku 1000, wszystkie cyfry wyrównane do lewej, jedna spacja za ostatnią liczbą .
  • Pytanie o linijkę o zerowej długości powinno wypisać NaR
  • Liczby ujemne powinny wydrukować odwróconą linijkę (-90, -80, -70, ...) z liczbami wyrównanymi do prawej, w dokładnie takim samym formacie jak powyżej

I samo drukowanie na konsoli jest w porządku

Gotowy, ustaw, golf!

użytkownik2398029
źródło
Skąd program wie, jak długo zrobić linijkę? Czy podano go jako numer w STDIN?
PhiNotPi
Tak, jak zwykle myślę!
user2398029,
1
Czy linijka musi być pozioma czy pionowa? jeśli jest w poziomie, to czy możemy założyć maksymalnie 80 znaków, czy też wysyłamy to do pliku, aby zamiast tego uniknąć zawijania? czy musimy zmienić rozmiar konsoli / terminala podczas pisania na standardowe wyjście?
Blazer
5
Jednym z głównych punktów golfa kodowego jest to, że problem musi być w 100% jednoznacznie określony (patrz: często zadawane pytania ). Rzeczywista wydajność nie ma miejsca na kreatywność, ponieważ kreatywność jest w samym kodzie. W przyszłości postaraj się przemyśleć wszystkie możliwe przypadki przed opublikowaniem pytania, ale ponieważ jesteś nowy, pomagamy ci :)
mellamokb
3
Czy możesz edytować wyzwanie, aby uwzględnić reguły określone w komentarzach?
flesk

Odpowiedzi:

8

Python - 227 232

Obsługuje całą specyfikację

edycja: ulepszone wyrażenie generatora.

Obsługa wyrównanych do prawej liczb ujemnych dodaje zaskakującą ilość kodu.

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]

Przykładowe wyniki:

-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
źródło
10

Nie pokonasz dzisiaj dynamicznych języków, ale w każdym razie ...

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

Pozwoliłem sobie na wymianę rzeczywistych znaków ASCII z lepiej wyglądającymi znakami rysunkowymi w polu Unicode.

$ echo "-50 30" | runhaskell  def0.hs
┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
│  │    │    │    │    │    │    │    │    │    │    │    │    │    │    │    │    │  │
│-50       -40       -30       -20       -10         0         10        20        30 │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘
przestał się obracać w lewo
źródło
2
Linijka wygląda bardzo, bardzo ładnie.
user2398029,
3

Python 2.7, 342 266 260 znaków

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

zwraca krotkę każdego ciągu wiersza , który można następnie wydrukować lub zapisać do pliku (wolę ten drugi dla długości dłuższych niż 70, ponieważ konsola jsut sprawi, że będzie wyglądał na pomieszany z zawijaniem)

Zakłada ysię, że jest łańcuchem (raw_input () n python lub sys.argv [1], jeśli chcesz wywoływać za pomocą cmd) liczbę całkowitą (np. Z input () w 2.x lub int (input ()) w 3.x )

Uczyniłem tę funkcję bardziej elastyczną

edycja: zmniejszona do 266 znaków. nie zwraca już krotki, ale ciąg. Teraz jako argument przyjmuje liczbę całkowitą zamiast ciągu

edit2: zmniejszono do 260 znaków, funkcja jednowierszowa

Uwaga: obsługuje liczby ujemne, ale nie usprawiedliwia (tak naprawdę nie sądzę, że uzasadnienie jest zbyt ważne

marynarka
źródło
Lub po prostu użyj konsoli nie powodującej łamania linii (np. Terminator ).
przestał się obracać w lewo o
@leftaroundabout Nie byłem pewien, czy coś takiego istnieje
Blazer
bez względu na to, że trzeba instalować osobną platformę, aby linijka wydawała się zupełnie bezcelowa, ponieważ tworzenie wartości zwracanej, której każdy mógłby użyć (zapis do pliku itp.) jest bardziej uniwersalne
Blazer
@ Blazer, czy twoja powłoka nie ma potoków i przekierowań?
Peter Taylor
1

PowerShell , 256 253 233 225 222 bajtów

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]

Wypróbuj online!

Mniej golfa:

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]
mazzy
źródło
0

Python, 291 241 znaków

Całkiem proste podejście. Jestem pewien, że można go znacznie poprawić.
Starałem się postępować zgodnie z wytycznymi w komentarzach, ale nie popieram liczb ujemnych (mam nadzieję, że był to żart).
To jest program, który wypisuje linijkę na standardowe wyjście. Jeśli ekran jest wystarczająco szeroki, powinien obsługiwać dość długie linijki.

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
źródło
Możesz zagrać w golfa z kilkoma innymi postaciami. Wygoliłem tutaj 12 postaci
Gordon Bailey
Dzięki @GordonBailey, ale i tak już jest zwycięzca, który jest krótszy niż mój kod i obsługuje pełną specyfikację.
ugoren
0

C ++, 392

Jest to programowane za pomocą konsoli Windows, dlatego właśnie wybrałem maksymalny rozmiar linijki to 70, po prostu zawiesi się na coś większego. Liczby ujemne (do -70) i ​​0 są obsługiwane poprawnie.

#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
źródło
0

Python - 208

(nie obsługuje wyrównanych do prawej liczb ujemnych)

 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"

Myślę, że moją ulubioną sztuczką było wygenerowanie ciągów, które są znacznie dłuższe niż to konieczne, a następnie ich obcięcie, na przykład:

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

Chciałbym tylko, żeby była bardziej zwięzła opcja formatowania ciągów dla wyrównania do lewej strony (chyba że jest taka, o której po prostu nie wiem)

Gordon Bailey
źródło
0

Perl 5.14, 198 224 znaków

Prawdopodobnie można go znacznie skrócić, ale oto pierwsza druga próba (z wstawionymi podziałami linii dla czytelności):

$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

EDYCJA: Edytowane, aby umrzeć z „NaR”, gdy wejście jest0 celu obsługi zakresu ujemnego.

EDYCJA 2: Nie miałem okazji nad tym więcej popracować i dopiero teraz zauważyłem regułę wyrównania do liczby ujemnej, której mój kod nie obsługuje, więc myślę, że inne rozwiązanie powinno zostać oznaczone jako odpowiedź, jeśli termin został osiągnięty.

flesk
źródło
@louism: Moja odpowiedź nie jest zgodna z wszystkimi zasadami. Jeśli to możliwe, należy wybrać inną odpowiedź.
flesk