Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

The challenge is to generate an ASCII character count ruler in the following format:

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

The length of the ruler should be scalable to any multiple of 10.

Rules:

  • Ruler must be horizontal.
  • Let's say, to keep things simpler, that the ruler must work until the 1000 mark, all numbers left-aligned, one space after the final number.
  • Asking for a ruler with zero length should print NaR
  • Negative numbers should print a reversed ruler (-90, -80, -70, ...) with right-aligned numbers, in the exact same format as the one above otherwise

And, just printing to console is fine

Ready, set, golf!

share|improve this question
How does the program know how long to make the ruler? Is it provided as a number on STDIN? – PhiNotPi Feb 15 '12 at 4:11
Yes, as usual I guess! – louism Feb 15 '12 at 4:26
1  
Does the ruler have to be horizontal or vertical? if it's horizontal, can we assume a maximum of 80 characters, or do we output this to a file to avoid wrapping instead? or do we have to resize the console/terminal when writing to stdout? – Blazer Feb 15 '12 at 4:49
4  
One of the main points of code-golf is that the problem must be 100 % unambiguously specified (see the faq). There is little room for creativity in the actual output, because the creativity is in the code itself. In the future, please try to think through all of these possible cases before posting the question, but since you're new, we're helping you out :) – mellamokb Feb 15 '12 at 19:14
3  
Could you please edit the challenge to include rules specified in the comments? – flesk Feb 16 '12 at 12:38
show 9 more comments

7 Answers

up vote 6 down vote accepted

Python - 227 232

Supports entire specification

edit: improved generator expression.

Supporting right aligned negative numbers adds a surprising amount of code.

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]

Sample outputs:

-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 |
|                                                        |
+--------------------------------------------------------+
share|improve this answer

Not going to beat the dynamic languages today, but anyway...

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

I took the liberty of exchanging the actual ASCII characters with better-looking unicode box drawing chars.

$ echo "-50 30" | runhaskell  def0.hs
┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
│  │    │    │    │    │    │    │    │    │    │    │    │    │    │    │    │    │  │
│-50       -40       -30       -20       -10         0         10        20        30 │
│                                                                                     │
└─────────────────────────────────────────────────────────────────────────────────────┘
share|improve this answer
2  
The ruler looks very, very nice. – louism Feb 18 '12 at 0:47
+1. I agree--ver nice job. – Steven Rumbalski Feb 20 '12 at 1:16

Python 2.7, 342 266 260 chars

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

returns a tuple of each line string, which you can then print or save to a file (I prefer the latter for lengths longer than 70 becuase the console will jsut make it look messed up with wrapping)

Assumes y to be a string (raw_input() n python, or sys.argv[1] if you wish to invoke via cmd) an integer (eg with input() in 2.x or int(input()) in 3.x)

I made this a function to be more flexible

edit: reduced to 266 characters. no longer returns a tuple, but a string instead. Now takes an integer instead of a string as the argument

edit2: reduced to 260 chars, single line function

note: does handle negative numbers, but doesn't right justify (I don't really htink the justification is too important anyways

share|improve this answer
Or just use a non-linebreaking console (e.g. Terminator). – leftaroundabout Feb 15 '12 at 18:34
@leftaroundabout I wasn't sure such a thing existed – Blazer Feb 15 '12 at 18:46
regardless, having to install a separate platform just to make a ruler seemspretty pointless, where-as creating a return value that anybody could use (write to a file, etc) is more universal – Blazer Feb 15 '12 at 18:57
@Blazer, does your shell not have pipes and redirects? – Peter Taylor Feb 15 '12 at 20:25

Python, 291 241 characters

A pretty simple approach. I'm sure it can be improved quite a lot.
I tried to follow the guidelines in the comments, but I don't support negative numbers (it was a joke, I hope).
This is a program, prints the ruler to standard output. If your screen is wide enough, it should support pretty long rulers.

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"
share|improve this answer
You can golf a few more characters off of this I shaved off 12 characters here – Gordon Bailey Feb 19 '12 at 19:39
Thanks @GordonBailey, but there's already a winner anyway, which is shorter than my code and supports the full specification. – ugoren Feb 20 '12 at 7:18

C++, 392

This is programmed using the windows console, therefore I just chose a maximum ruler size is 70, it'll just crash for anything bigger. Negative numbers( up to -70) and 0 are handled correctly.

#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]);}
share|improve this answer

Python - 208

(does not support right aligned negative numbers)

 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"

I think my favourite trick was to generate strings that are way longer than necessary and then truncate them, for example:

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

I just wish there was a more concise string formatting option for left-alignment (unless there is one that I just don't know about)

share|improve this answer

Perl 5.14, 198 224 chars

Probably can be shortened a lot further, but here's a first second attempt (with line breaks inserted for readability):

$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: Edited to die with "NaR" when input is 0 and to support negative range.

EDIT2: I haven't had a chance to work more on this, and I only just now noticed the right aligned for negative numbers rule, which my code doesn't support, so I think another solution should be marked as the answer if the deadline has been reached.

share|improve this answer
@louism: My answer doesn't conform to all the rules. Another answer should be chosen if possible. – flesk Feb 18 '12 at 10:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.