35
\$\begingroup\$

Writing out numbers is among the Hello worlds of programming, often the numbers 1-10.

I want to write out many numbers! Many, Many numbers. But how many numbers do I have to write?

Task

Given an integer input, give a number as output that would give me the number of digits that would be in a string containing all integer numbers in the range from 0 to the input, inclusive. The negation identifier ("-") counts as a single character.

Example I/Os

Input: 8
Written out: 0,1,2,3,4,5,6,7,8
Output: 9

Input: 101
written out: 0,1,2,3....,99,100,101
Output: 196

Input: 102
written out: 0,1,2,3....,100,101,102
output: 199

Input -10
Written out: 0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10
output: 22

This is a . The lowest number of bytes wins!

\$\endgroup\$

53 Answers 53

23
\$\begingroup\$

05AB1E, 3 bytes

Code:

ÝJg

Uses the CP-1252 encoding. Try it online!

Explanation:

Ý     # Range [0 .. input]
 J    # Join into one string
  g   # Get the length of the string
\$\endgroup\$
13
\$\begingroup\$

Python 2, 55 46 bytes

lambda n:len(`range(abs(n)+1)`)+2*~n+3*n*(n<0)

Try it online!

Getting better.

\$\endgroup\$
11
\$\begingroup\$

Röda, 23 bytes

f x{[#([seq(0,x)]&"")]}

Try it online!

Explained:

f x{[#([seq(0,x)]&"")]}
f x{                  } /* Defines function f with parameter x. */
        seq(0,x)        /* Creates a stream of numbers from 0 to x. */
       [        ]       /* Creates an array. */
                 &""    /* Joins with "". */
     #(             )   /* Calculates the length of the resulting string. */
    [                ]  /* Returns the value. */
\$\endgroup\$
10
\$\begingroup\$

Python 2, 41 bytes

f=lambda n:len(`n`)+(n and f(n+cmp(0,n)))

Try it online!

\$\endgroup\$
  • \$\begingroup\$ +1: You really cannot beat this intelligently made recursive solution with Python \$\endgroup\$ – micsthepick Mar 16 '17 at 22:28
7
\$\begingroup\$

Bash + OS X (BSD) utilities, 24 22 bytes

Thanks to @seshoumara for saving 2 bytes.

seq 0 $1|fold -1|wc -l

Test runs on Mac OS X:

$ for n in 8 101 102 -10 -1 0 1; do printf %6d $n; ./digitcount $n; done
     8       9
   101     196
   102     199
   -10      22
    -1       3
     0       1
     1       2

Here's a GNU version:

Bash + coreutils, 40 38 bytes

Again, 2 bytes saved thanks to @seshoumara.

(seq $1 0;seq 0 $1)|uniq|fold -1|wc -l

Try it online!

\$\endgroup\$
  • \$\begingroup\$ @tuskiomi I wrote coreutils when I meant BSD utilities -- I tested it in Mac OS X, where it does work on negative inputs too (seq there isn't the same as GNU seq). \$\endgroup\$ – Mitchell Spector Mar 10 '17 at 5:53
  • \$\begingroup\$ @DigitalTrauma Nice GNU solution. Go ahead and post it yourself if you'd like to; I think it's too different to count as a variant of mine. \$\endgroup\$ – Mitchell Spector Mar 10 '17 at 19:42
  • \$\begingroup\$ Ok, here you are :) \$\endgroup\$ – Digital Trauma Mar 10 '17 at 19:58
  • \$\begingroup\$ How about using fold -1|wc -l to do the counting? It is shorter. \$\endgroup\$ – seshoumara Mar 11 '17 at 8:11
6
\$\begingroup\$

Python 2, 83 ,78 64 bytes

shortest version:

lambda x:sum(map(len,map(str,(range(0,x+cmp(x,.5),cmp(x,.5))))))

this version saved 5 bytes, thanks to @numbermaniac :

x=input()
print len(''.join(map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))

Try it online!

this one I came up with on my own after that (same amount of bytes):

x=input()
print sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1)))))

Try it online!

\$\endgroup\$
  • \$\begingroup\$ You can use map on the second line for 78 bytes: print len(''.join(map(str,(range(x+1)if x>0 else range(0,x-1,-1))))). You might save even more by making it a lambda. \$\endgroup\$ – numbermaniac Mar 10 '17 at 6:07
  • 1
    \$\begingroup\$ @numbermaniac can I do something similar this way? \$\endgroup\$ – micsthepick Mar 10 '17 at 6:12
  • 1
    \$\begingroup\$ @numbermaniac here is an equivalent: print sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1))))) \$\endgroup\$ – micsthepick Mar 10 '17 at 6:14
  • \$\begingroup\$ lambda x:sum(map(len,map(str,(range(x+1)if x>0 else range(0,x-1,-1))))) for 71 bytes \$\endgroup\$ – Felipe Nardi Batista Mar 16 '17 at 13:40
6
\$\begingroup\$

Java 7, 74 bytes (recursive - including second default parameter)

int c(int r,int n){r+=(n+"").length();return n>0?c(r,n-1):n<0?c(r,n+1):r;}

Explanation (1):

int c(int r, int n){     // Recursive method with two integer parameters and integer return-type
                         // Parameter `r` is the previous result of this recursive method (starting at 0)
  r += (n+"").length();  //  Append the result with the current number's width
  return n > 0 ?         //  If the input is positive
     c(r, n-1)           //   Continue recursive method with n-1
    : n < 0 ?            //  Else if the input is negative
     c(r, n+1)           //   Continue recursive method with n+1
    ?                    //  Else (input is zero)
     r;                  //   Return the result
}                        // End of method

Java 7, 81 79 bytes (loop - single parameter)

If having a default second parameter as 0 for this recursive approach isn't allowed for some reason, a for-loop like this could be used instead:

int d(int n){String r="x";for(int i=n;i!=0;i+=n<0?1:-1)r+=i;return r.length();}

Explanation (2)

int d(int n){                 // Method with integer parameter and integer return-type
  String r = "x";             //  Initial String (with length 1 so we won't have to +1 in the end)
  for(int i=n; i != 0;        //  Loop as long as the current number isn't 0
      i += n < 0 ? 1 : 1)     //   After every iteration of the loop: go to next number
    r += i;                   //   Append String with current number
                              //  End of loop (implicit / single-line body)
  return r.length();          //  Return the length of the String
}                             // End of method

Test code:

Try it here.

class M{
  static int c(int r,int n){r+=(n+"").length();return n>0?c(r,n-1):n<0?c(r,n+1):r;}

  static int d(int n){String r="x";for(int i=n;i!=0;i+=n<0?1:-1)r+=i;return r.length();}

  public static void main(String[] a){
    System.out.println(c(0, 8) + "\t" + d(8));
    System.out.println(c(0, 101) + "\t" + d(101));
    System.out.println(c(0, 102) + "\t" + d(102));
    System.out.println(c(0, -10) + "\t" + d(-10));
  }
}

Output:

9   9
196 196
199 199
22  22
\$\endgroup\$
  • 1
    \$\begingroup\$ I like this solution, :) \$\endgroup\$ – tuskiomi Jun 15 '17 at 19:48
4
\$\begingroup\$

RProgN 2, 5 bytes

n0R.L

Explination

n0R   # A Stack of all numbers between 0 and the input converted to a number.
   .L # The length of the stringification of this.

Simple solution, works like a charm.

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Brachylog, 5 bytes

⟦ṡᵐcl

Try it online!

Builds the range [0,input], converts each number to string, concatenates into a single string and returns the length of the result

\$\endgroup\$
  • \$\begingroup\$ I noticed TIO has an argument Z; what's up with that? Should it be in the count? \$\endgroup\$ – steenbergh Mar 10 '17 at 10:45
  • 3
    \$\begingroup\$ @steenbergh: Leo's submission is a function, not a full program. Giving the argument Z to the Brachylog interpreter tells it to add an appropriate wrapper to make the function testable. (If you ran it as a full program, it wouldn't produce any output.) We allow either program or function submissions here, so that shouldn't count against the byte count, as it's not actually part of the submission. \$\endgroup\$ – user62131 Mar 10 '17 at 11:00
4
\$\begingroup\$

PHP, 59 60 bytes

Outgolfed by Roberto06 - https://codegolf.stackexchange.com/a/112536/38505

Thanks to roberto06 for noticing the previous version didn't work for negative numbers.

Simply builds an array of the numbers, puts it to a string, then counts the digits (and minus sign)

<?=preg_match_all("/\-|\d/",implode(",",range(0,$argv[1])));

Run example: php -f 112504.php 8

\$\endgroup\$
  • \$\begingroup\$ This doesn't work for a negative input, see here \$\endgroup\$ – roberto06 Mar 10 '17 at 10:53
  • \$\begingroup\$ You could save 3 bytes using join instead of implode because it is an alias. \$\endgroup\$ – Mario Mar 11 '17 at 7:37
  • \$\begingroup\$ there is no need to escape the minus -1 Byte. On the other hand you can change your regex to [--9] \$\endgroup\$ – Jörg Hülsermann Mar 11 '17 at 13:37
4
\$\begingroup\$

Haskell, 39 38 bytes

f 0=1
f n=length$show=<<[0..n]++[n..0]

Try it online! Edit: saved 1 byte thanks to @xnor!

Explanation:

In Haskell for numbers a and b [a..b] is the range from a to b in 1-increments or 1-decrements, depending on whether b is larger a. So for a positive n the first list in [0..n]++[n..0] is [0,1,2,...,n] and the second one is empty. For negative n the second range yields [0,-1,-2,...,n] and the first one is empty. However if n=0 both ranges yield the list [0], so the concatenation [0,0] would lead to a false result of 2. That's why 0 is handled as a special case.

The =<<-operator on a list is the same as concatMap, so each number is converted into a string by show and all those strings are concatenated in one long string of which the length is finally returned.


Before xnor's tip I used [0,signum n..n] instead of [0..n]++[n..0]. signum n is -1 for negative numbers, 0 for zero and 1 for positive numbers and a range of the form [a,b..c] builds the list of numbers from a to c with increment b. Thereby [0,signum n..n] builds the range [0,1,2,...,n] for positive n and [0,-1,-2,...,n] for negative n. For n=0 it would build the infinite list [0,0,0,...] so we need to handle 0 as a special case, too.

\$\endgroup\$
  • \$\begingroup\$ I think [0..n]++[n..0] should do for [0,signum n..n]. \$\endgroup\$ – xnor Mar 10 '17 at 13:31
4
\$\begingroup\$

PHP, 41 35 bytes

Saved 6 bytes thanks to user59178

Since ʰᵈ's answer was wrong for a negative input, I took it upon myself to build a new solution :

<?=strlen(join(range(0,$argv[1])));

This function :

  • Builds an array from 0 to $argv[1] (aka the input)
  • Implodes it with an empty character (i.e. transforms it to a string)
  • Echoes the length of the string

Try it here!

\$\endgroup\$
  • \$\begingroup\$ This is a nicer solution to mine, idk why I thought I had to do that preg_match() :( \$\endgroup\$ – ʰᵈˑ Mar 10 '17 at 11:13
  • \$\begingroup\$ Well, I wouldn't have thought of range() if it wasn't for your solution, I guess we're even ;) \$\endgroup\$ – roberto06 Mar 10 '17 at 11:21
  • 1
    \$\begingroup\$ you can save 3 bytes by using join() instead of implode(). it's an alias for the same thing. php.net/manual/en/function.join.php \$\endgroup\$ – user59178 Mar 10 '17 at 15:10
  • 1
    \$\begingroup\$ And 3 more by omitting the 'glue' parameter. \$\endgroup\$ – user59178 Mar 10 '17 at 15:18
  • \$\begingroup\$ I knew there was an alias for implode, but I didn't know I could omit the gue parameter. Thanks ! \$\endgroup\$ – roberto06 Mar 10 '17 at 15:29
4
\$\begingroup\$

Ruby, 20 26 29 bytes

->x{[*x..-1,0,*1..x]*''=~/$/}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Why the increase? \$\endgroup\$ – Brian Minton Mar 10 '17 at 19:13
  • \$\begingroup\$ The first version did not work for negative numbers, the second version had a problem with zero as input. \$\endgroup\$ – G B Mar 10 '17 at 21:43
4
\$\begingroup\$

R, 26 20 bytes

sum(nchar(0:scan()))

Very basic approach:

  • Make a vector 0:x

  • Count the characters in each value (will be coerced to a string automatically)

  • Sum

Not sure if there are any tricks to cut down the function definition? 6 bytes saved thanks to Giuseppe, by taking input from stdin instead.

\$\endgroup\$
  • \$\begingroup\$ you could do sum(nchar(0:scan())) instead and read n from stdin instead. \$\endgroup\$ – Giuseppe May 15 '17 at 16:24
4
\$\begingroup\$

Mathematica, 48 47 46 bytes

-1 byte thanks to Martin Ender!

StringLength[""<>ToString/@Range[0,#,Sign@#]]&

Anonymous function, taking the number as an argument.

Shorter solution by Greg Martin, 39 bytes

1-#~Min~0+Tr@IntegerLength@Range@Abs@#&
\$\endgroup\$
  • 1
    \$\begingroup\$ You can use Sign@# for #/Abs@#. \$\endgroup\$ – Martin Ender Mar 10 '17 at 8:01
  • 1
    \$\begingroup\$ You can save a few bytes with a slightly different approach: 1-#~Min~0+Tr@IntegerLength@Range@Abs@#&. The initial 1 accounts for the digit of 0, while -#~Min~0 accounts for all the negative signs if the input is negative. \$\endgroup\$ – Greg Martin Mar 10 '17 at 8:23
3
\$\begingroup\$

Batch, 110 bytes

@set/a"n=%1,t=n>>31,n*=t|1,t=1-t*n,i=0
@for /l %%i in (0,1,9)do @set/a"t+=(i-n)*(i-n>>31),i=i*10+9
@echo %t%

Computes sum(min(0,abs(n)+1-10^k),k=0..9)+(n<0?1-n:1). (I only have to go up to 9 because of the limitations of Batch's integer arithmetic.)

\$\endgroup\$
3
\$\begingroup\$

Python 2, 68 bytes

def f(i,j=1):
 if i==0:print j
 else:j+=len(`i`);f((i-1,i+1)[i<0],j)

Try it online!

Longer than but different from other Python solutions. Defines a recursive function called as e.g. f(10)

\$\endgroup\$
3
\$\begingroup\$

MATL, 11 bytes

0hSZ}&:VXzn

Try it online!

0h           % Implicitly input n. Append a 0: gives array [n 0]
  S          % Sort
   Z}        % Split array: pushes 0, n or n, 0 according to the previous sorting
     &:      % Binary range: from 0 to n or from n to 0
       V     % Convert to string. Inserts spaces between numbers
        Xz   % Remove spaces
          n  % Length of string. Implicit display
\$\endgroup\$
3
\$\begingroup\$

PowerShell, 23 bytes

-join(0.."$args")|% Le*

Try it online! (will barf on TIO for very large (absolute) inputs)

Uses the .. range operator to construct a range from 0 to the input $args (cast as a string to convert from the input array). That's -joined together into a string (e.g., 01234) and then the Length is taken thereof. That is left on the pipeline and output is implicit.

\$\endgroup\$
  • \$\begingroup\$ The exact solution I had in my head when I read this question 😝 \$\endgroup\$ – briantist Mar 11 '17 at 3:57
3
\$\begingroup\$

Perl 6, 18 bytes

{chars [~] 0...$_}

Try it

Expanded:

{  # bare block lambda with implicit parameter 「$_」

  chars        # how many characters (digits + '-')
    [~]        # reduce using string concatenation operator &infix:<~>
      0 ... $_ # deductive sequence from 0 to the input
}
\$\endgroup\$
3
\$\begingroup\$

QBIC, 25 bytes

:[0,a,sgn(a)|A=A+!b$]?_lA

Explanation:

:[0,a     Read 'a' from the cmd line, start a FOR loop from 0 to 'a'
,sgn(a)|  with incrementer set to -1 for negative ranges and 1 for positive ones
A=A+!b$   Add a string cast of each iteration (var 'b') to A$
]         NEXT
?_lA      Print the length of A$
\$\endgroup\$
3
\$\begingroup\$

JavaScript, 50 bytes

Collaborated with @ETHproductions

n=>{for(t="";n;n<0?n++:n--)t+=n;alert(++t.length)}
\$\endgroup\$
3
\$\begingroup\$

Bash + GNU coreutils, 28

eval printf %s {0..$1}|wc -c

Try it online.

\$\endgroup\$
3
\$\begingroup\$

Retina, 28 bytes

\d+
$*
1
$`1¶
1+
$.&
^-?
0
.

Try it online!

Explanation

\d+
$*

Convert the number to unary, keeping the sign untouched.

1
$`1¶

Each 1 is replaced by everything up to itself plus a newline. With this we get a range from 1 to n if n was positive, from -1 to n with an additional - at the start if it was negative. All numbers are in unary and separed by newlines.

1+
$.&

Convert each sequence of ones to the corresponding decimal number.

^-?
0

Put a 0 at the start, replacing the extra - if it's there.

.

Count the number of (non-newline) characters.

\$\endgroup\$
3
\$\begingroup\$

Emacs, 20 bytes

C-x ( C-x C-k TAB C-x ) M-{input} C-x e C-x h M-=

The command itself is 20 keystrokes, but I need clarification on how this should be counted as bytes. I reasoned that counting each keystroke as 1 byte would be the most fair. The command above is written conventionally for easier reading.

Explanation

C-x (

Begin defining a keyboard macro.

C-x C-k TAB

Create a new macro counter. Writes 0 to the buffer; the counter's value is now 1.

C-x )

End keyboard macro definition.

M-{input} C-x e

After hitting META, type in your input number. The C-x e then executes the macro that many times.

C-x h

Set mark to beginning of buffer (which selects all of the text thus generated).

M-=

Run character count on the selected region. The number of characters will be printed in the minibuffer.

Example

Apologies for the terrible highlighting color. This is an example of using this command with the input 100. The output is in the minibuffer at the bottom of the screen.

Example execution with input of 100

\$\endgroup\$
  • \$\begingroup\$ Yep, I'm pretty sure one keystroke is one byte. \$\endgroup\$ – NoOneIsHere Mar 14 '17 at 18:55
  • \$\begingroup\$ @NoOneIsHere There are two thoughts I had about that: 1) Can Ctrl+character be represented as a single byte? And 2) I see a lot of answers here counting Unicode chars as one byte, but they are not, so I thought maybe CodeGolf maybe has its own definition of "byte"? Thanks. \$\endgroup\$ – cheryllium Mar 14 '17 at 19:01
  • \$\begingroup\$ I really don't know. But you can ask on Meta. \$\endgroup\$ – NoOneIsHere Mar 14 '17 at 19:05
3
\$\begingroup\$

Lua, 52 bytes

t=0;for i=0,io.read()do t=t+#tostring(i)end;print(t)

Iterates through a for loop from 0 - input, converts the integer i to a string and adds the length of the string to t before printing t

\$\endgroup\$
2
\$\begingroup\$

Perl 5, 32 bytes

31 bytes of code + -p flag.

$\+=y///c for$_>0?0..$_:$_..0}{

Try it online!

\$\endgroup\$
2
\$\begingroup\$

C#, 77 73 bytes

-4 bytes thanks to @Kevin Cruijssen

Lambda function:

(r)=>{var l="";for(int i=0,s=r<0?-1:1;i!=r+s;i+=s)l+=i;return l.Length;};

Ungolfed and with test cases:

class P
{
    delegate int numbers(int e);
    static void Main()
    {
        numbers n = (r) =>
        {
            var l = ""; 
            for (int i = 0, s = r < 0 ? -1 : 1; i != r + s; i += s)
                l += i; 
            return l.Length;
        };
        System.Console.WriteLine(n(8));
        System.Console.WriteLine(n(101));
        System.Console.WriteLine(n(102));
        System.Console.WriteLine(n(-10));
        System.Console.ReadKey();
    }
}
\$\endgroup\$
  • \$\begingroup\$ You can change the while to for to save a couple of bytes: (r)=>{var l="";for(int i=0,s=r<0?-1:1;i!=r+s;i+=s)l+=i;return l.Length;}; (73 bytes) \$\endgroup\$ – Kevin Cruijssen Mar 10 '17 at 10:26
  • \$\begingroup\$ @Kevin Cruijssen You are right, thanks. \$\endgroup\$ – Mr Scapegrace Mar 10 '17 at 10:36
  • \$\begingroup\$ You can probably use an int counter and add the length inside the loop to save some bytes. If you compile to a Func<int, int> you can call the functions like r=>... to save 2 bytes (can probably do this anyway). \$\endgroup\$ – TheLethalCoder Mar 10 '17 at 13:10
2
\$\begingroup\$

JavaScript, 44 bytes

f=(n,i=1)=>n<0?f(-n)-n:n<i?1:n+1-i+f(n,i*10)
<input type=number oninput=o.textContent=f(+this.value)><pre id=o>

\$\endgroup\$
2
\$\begingroup\$

REXX, 56 bytes

arg n
l=0
do i=0 to n by sign(n)
  l=l+length(i)
  end
say l
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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