38
\$\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\$
0

59 Answers 59

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\$
1
  • \$\begingroup\$ +1: You really cannot beat this intelligently made recursive solution with Python \$\endgroup\$ Commented Mar 16, 2017 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\$
4
  • \$\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\$ Commented Mar 10, 2017 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\$ Commented Mar 10, 2017 at 19:42
  • \$\begingroup\$ Ok, here you are :) \$\endgroup\$ Commented Mar 10, 2017 at 19:58
  • \$\begingroup\$ How about using fold -1|wc -l to do the counting? It is shorter. \$\endgroup\$
    – seshoumara
    Commented Mar 11, 2017 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\$
4
  • \$\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\$ Commented Mar 10, 2017 at 6:07
  • 1
    \$\begingroup\$ @numbermaniac can I do something similar this way? \$\endgroup\$ Commented Mar 10, 2017 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\$ Commented Mar 10, 2017 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\$ Commented Mar 16, 2017 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
  • 1
    \$\begingroup\$ I like this solution, :) \$\endgroup\$
    – tuskiomi
    Commented Jun 15, 2017 at 19:48
5
\$\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\$
2
  • 1
    \$\begingroup\$ You can use Sign@# for #/Abs@#. \$\endgroup\$ Commented Mar 10, 2017 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\$ Commented Mar 10, 2017 at 8:23
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\$
2
  • \$\begingroup\$ I noticed TIO has an argument Z; what's up with that? Should it be in the count? \$\endgroup\$
    – steenbergh
    Commented Mar 10, 2017 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
    Commented Mar 10, 2017 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\$
3
  • \$\begingroup\$ This doesn't work for a negative input, see here \$\endgroup\$
    – roberto06
    Commented Mar 10, 2017 at 10:53
  • \$\begingroup\$ You could save 3 bytes using join instead of implode because it is an alias. \$\endgroup\$
    – Mario
    Commented Mar 11, 2017 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\$ Commented Mar 11, 2017 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\$
1
  • \$\begingroup\$ I think [0..n]++[n..0] should do for [0,signum n..n]. \$\endgroup\$
    – xnor
    Commented Mar 10, 2017 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\$
5
  • \$\begingroup\$ This is a nicer solution to mine, idk why I thought I had to do that preg_match() :( \$\endgroup\$
    – ʰᵈˑ
    Commented Mar 10, 2017 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
    Commented Mar 10, 2017 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
    Commented Mar 10, 2017 at 15:10
  • 1
    \$\begingroup\$ And 3 more by omitting the 'glue' parameter. \$\endgroup\$
    – user59178
    Commented Mar 10, 2017 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
    Commented Mar 10, 2017 at 15:29
4
\$\begingroup\$

Ruby, 20 26 29 bytes

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

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Why the increase? \$\endgroup\$ Commented Mar 10, 2017 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
    Commented Mar 10, 2017 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\$
1
  • \$\begingroup\$ you could do sum(nchar(0:scan())) instead and read n from stdin instead. \$\endgroup\$
    – Giuseppe
    Commented May 15, 2017 at 16:24
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\$
1
  • \$\begingroup\$ The exact solution I had in my head when I read this question 😝 \$\endgroup\$
    – briantist
    Commented Mar 11, 2017 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\$
0
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\$
4
  • \$\begingroup\$ Yep, I'm pretty sure one keystroke is one byte. \$\endgroup\$ Commented Mar 14, 2017 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
    Commented Mar 14, 2017 at 19:01
  • \$\begingroup\$ I really don't know. But you can ask on Meta. \$\endgroup\$ Commented Mar 14, 2017 at 19:05
  • \$\begingroup\$ @cheryllium Some languages use a SBCS that fits a different set of 256 characters in 1 byte than ASCII. You can only count it as 1 byte if there are less than 256 characters to choose from in that language. \$\endgroup\$ Commented Feb 28, 2023 at 8:43
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\$
3
  • \$\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\$ Commented Mar 10, 2017 at 10:26
  • \$\begingroup\$ @Kevin Cruijssen You are right, thanks. \$\endgroup\$ Commented Mar 10, 2017 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\$ Commented Mar 10, 2017 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 and acknowledge you have read our privacy policy.

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