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

2
\$\begingroup\$

Jelly, 6 bytes

r0Ṿ€FL

Try it online!

Jelly's surprisingly bad at this, mostly because it doesn't have a dedicated builtin for stringifying integers; it does have a builtin for stringifying anything, but that means we can't have it autovectorize over lists.

Explanation

r0Ṿ€FL
r0      All numbers from {the input} to 0, inclusive
   €    For each of those numbers numbers:
  Ṿ       Find its string representation
    F   Concatenate the resulting strings
     L  Take the length of the resulting string
\$\endgroup\$
  • \$\begingroup\$ The Length builtin doesn't work directly on integers? Preposterous! \$\endgroup\$ – ETHproductions Mar 10 '17 at 14:39
  • \$\begingroup\$ Wait, can you use D instead of Ṿ€? \$\endgroup\$ – ETHproductions Mar 10 '17 at 14:43
  • \$\begingroup\$ @ETHproductions: No, it doesn't deal with negative numbers correctly. \$\endgroup\$ – user62131 Mar 10 '17 at 14:48
  • \$\begingroup\$ Ah, got it. And I guess there's no 0-byte way to add 1 to every number if the input is negative :P \$\endgroup\$ – ETHproductions Mar 10 '17 at 15:34
2
\$\begingroup\$

JavaScript (Node.js), 37 bytes

f=n=>n?(n+"").length+f(n>0?n-1:n+1):1

Port of my Python answer.

Try it online!

\$\endgroup\$
  • \$\begingroup\$ It's not only Node.js though, it should work on any platform that supports ES6. \$\endgroup\$ – ETHproductions Mar 10 '17 at 13:24
  • \$\begingroup\$ Yeah, I just used the auto-generated TIO answer. \$\endgroup\$ – Dennis Mar 10 '17 at 13:28
  • \$\begingroup\$ Oh cool, I didn't notice there was an option to do that :-) \$\endgroup\$ – ETHproductions Mar 10 '17 at 13:33
  • \$\begingroup\$ Yep, either with the mouse or by pressing Esc, S, G. \$\endgroup\$ – Dennis Mar 10 '17 at 13:40
2
\$\begingroup\$

Japt, 4 bytes

ò ¬l

Try it online!

Explanation:

ò ¬l
ò     // Creates a range from [0...Input]
  ¬   // Joins the array into a string
   l  // Returns the length
\$\endgroup\$
2
\$\begingroup\$

SQL (PostgreSQL), 76 bytes

SELECT sum(length(a::text))FROM generate_series(least(0,$1),greatest(0,$1))a

This is an SQL function.

\$\endgroup\$
  • \$\begingroup\$ SQL! That's a rare one \$\endgroup\$ – tuskiomi Mar 10 '17 at 20:00
2
\$\begingroup\$

Java, 211 bytes

interface n{static void main(String[]a){int n=Integer.parseInt(a[0]),k=1,i;a[0]="";if(n<0)k=-1;for(i=0;i!=n+k;i+=k){a[0]+=i;if(i!=n)a[0]+=',';}System.out.print(a[0]);System.exit(a[0].replace(",","").length());}}

Takes number as first command line argument. Returns output as an error code:

Input: -10

0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-10
Process finished with exit code 22

Ungolfed version with comments:

interface n {
    static void main(String[]a) {
        int n = Integer.parseInt(a[0]),                 // Input number 
        k = 1,                                          // For loop increment
        i;                                              // For loop counter
        a[0] = "";                                      // Empty string
        if(n < 0) k = -1;                               // If input number is negative loop increment is negative
        for(i=0; i != n + k; i += k) {                  // For loop
            a[0] += i;                                  // Append number to string
            if (i != n)                                 // If not the last number
                a[0] += ',';                            // Append comma
        }
        System.out.print(a[0]);                         // Output string
        System.exit(a[0].replace(",","").length());     // Return length of string without commas as error code
    }
}
\$\endgroup\$
2
\$\begingroup\$

K, 29 Bytes

I have a feeling there is a better way...

f:{#,/$((+;-)x<0).(0;!1+abs x)}

(+;-)x<0     ---> Call this A. If x is less that 0, return - otherwise return +
(0;!1+abs x) ---> Call this B. A list; (0;the numbers from 1 to the absolute value of x)
A.B          ---> Apply A to B, e.g1. (-).(0;0 1 2) ==> 0 -1 -2 e.g2 (+).(0;0 1 2) ==> 0 1 2
,/$x         ---> $tring x (x is numbers asc or desc) and flatten the list ,/
#x           ---> Finally count the flattened list

Some tests...

  f 8
9
  f 10
12
  f 101
196
  f 102
199
  f -10
22
  f -100
293
\$\endgroup\$
  • \$\begingroup\$ {$[x<0;a;0]+#,/$!1+a:abs x} for 27 bytes. Sums up string of 0..abs[input], if input was negative then add the abs[input] as this is the number of - you'd need to print the string. \$\endgroup\$ – streetster Dec 12 '17 at 12:22
2
\$\begingroup\$

Clojure, 48 bytes

(count(apply str(range(min 0 %)(max 1(inc %)))))

(defn how-much-to-write? [n]
  ; Count the characters in the resulting string
  (count
    ; Basically "joins" the list with ""
    (apply str
      ; Creates an ascending/descending range, depending on the value of n
      (range (min 0 n) (max 1 (inc n))))))
\$\endgroup\$
2
\$\begingroup\$

Stacked, 25 bytes

:sign\0\abs|>*''join size

Try it online!

Explanation

:sign\0\abs|>*''join size    stack: (n)
:                            stack: (n n)
 sign                        stack: (n sign[n])
     \                       stack: (sign[n] n)
      0                      stack: (sign[n] n 0)
       \                     stack: (sign[n] 0 n)
        abs                  stack: (sign[n] 0 abs[n])
           |>                stack: (sign[n] range[0, abs[n]])
             *               negates the range if negative
              ''join         said range as a single string
                     size    the desired length
\$\endgroup\$
2
\$\begingroup\$

Scala 75 Bytes

(x:Int)=>{
  val? =Math.abs _
  (0 to?(x))./:("")((a,c)=>a+","+c* ?(x)/x).size-1
}

I'm not sure how I can improve it any further. The Math.abs is really really annoying. I think there is probably a better way to go about doing the negative stuff.

\$\endgroup\$
1
\$\begingroup\$

Javascript, 65 bytes

T=n=>{m=n>0?1:-1,o="";for(i=0;i!=n+m;i=i+m){o+=i}return o.length}

\$\endgroup\$
1
\$\begingroup\$

Swift, 72 bytes

let f={i in(min(i,0)...max(0,i)).reduce(0){$0+"\($1)".characters.count}}

The "characters.count" really kills the score.

\$\endgroup\$
1
\$\begingroup\$

Retina, 42 41 bytes

-(.+)
$*-¶$1
.+$
$*
\d|$
$%` 
(1*) 
$.1
.

Try it online!

Explanation

-(.+)
$*-¶$1

If the number is a negative, let's say -n (i.e. there is a - in the input), then replace the input with n -s, and n on the next line. In the end we just want to count the characters, and for -n as input, there will be exactly n - signs in the range.

.+$
$*

Convert the number at the end of string into unary.

\d|$
$%` 

Replace any digit character or the end of the string with all the text before it on the same line, plus a space. For a sequence of 1s, this results in  1 11 111 ... up until the original sequence. This builds the range from 0 to n, in unary.

(1*) 
$.1

Conversion back to decimal. Any series of 1s followed by a space is replaced with the number of 1s.

.

Count the matches of . and output it. . matches any single character except linefeed.

\$\endgroup\$
1
\$\begingroup\$

Pip, 13 12 bytes

#J:^0\,a|a,1

Takes input from command-line argument. Verify all test cases at Try it online!

Explanation

Some weird tricks in this one:

0\,a is the inclusive range from 0 to a.

If a is negative, we want to take the inclusive range from a to 0 instead. A naive approach would be a ternary expression with a<0, but we can do better. The problem is that something like (0,-11) is a perfectly valid Range object and is truthy, even though the range it represents contains no numbers1. We want to convert it to an empty list (falsey).

To achieve this, we apply unary ^ to split the Range into characters. This operator works itemwise, so for example giving it 0\,10 would result in the list [[0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [1 0]]. Splitting into characters won't make a difference to the result, since we're going to join everything together anyway. But crucially, it forces the conversion of the Range into a List. So an input of -10 now results in the empty list [].

Now since [] is falsey, we can take the logical Or of the above with a,1 (i.e. range(a,1), not including the upper bound) and get the elements we want.

Next, we need to join them together. Unfortunately, Join has a higher precedence than Or, so we would need parentheses. But another approach is to modify Join with the compute-and-assign meta-operator : (which is like the = in += in C-like languages, but more flexible). This lowers the precedence of the operator such that parentheses aren't needed. Assigning to an rvalue is a warning, but not an error.

Finally, we take the length (#) of the resulting string, which is then autoprinted.

1 Such "backwards" ranges are used in string slicing, where the negative number means "the index 11 characters from the end."

\$\endgroup\$
1
\$\begingroup\$

C++ 102 Bytes

int f(int n){int o=0;std::string s;for(n=n<0?o=-n:n;n>=0;)s+=std::to_string(n--);return s.length()+o;}

Ungolfed

int f(int n)
{
    int o=0;
    std::string s;
    for(n=n<0?o=-n:n;n>=0;)
        s+=std::to_string(n--);
    return s.length()+o;
}

Will add explanations.

\$\endgroup\$
  • \$\begingroup\$ Suggest int o=n<0?(n=-n):0;std::string s;for(;n>=0;) instead of int o=0;std::string s;for(n=n<0?o=-n:n;n>=0;) \$\endgroup\$ – ceilingcat Mar 14 '17 at 4:22
1
\$\begingroup\$

Pyth, 6 5 bytes

ljk}0
Uses ais523's Jelly algorithm, except that the range starts from 0.

Thanks to RK. for -1.

\$\endgroup\$
  • \$\begingroup\$ You could get rid of the M by just doing ljk}0 \$\endgroup\$ – RK. Mar 11 '17 at 22:16
  • \$\begingroup\$ @RK. And I knew there is a shorter way than s`M! \$\endgroup\$ – Erik the Outgolfer Mar 12 '17 at 7:39
  • \$\begingroup\$ that's the feeling, right? \$\endgroup\$ – RK. Mar 12 '17 at 17:34
1
\$\begingroup\$

PHP, 38 35 bytes

<?=strlen(join(range(0,$argv[1]))); // 35 bytes
<?=strlen(join("",range(0,$argv[1]))); // 38 bytes

Useage: php file.php 8

The join is a little used alias of implode(), and php can easily join numbers together as a string. Titus commented that the glue isn't needed in join() if you want a empty string.

\$\endgroup\$
  • \$\begingroup\$ Save three bytes: The glue parameter for join is optional (see codegolf.stackexchange.com/a/86340/55735 and php.net/implode). \$\endgroup\$ – Titus Mar 13 '17 at 12:38
1
\$\begingroup\$

Java 8, 80 bytes

Golfed:

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

Ungolfed:

public class HowMuchDoIHaveToWrite {

  public static void main(String[] args) {
    for (final int[] test : new int[][] { { 8, 9 }, { 101, 196 }, { 102, 199 }, { -10, 22 } }) {
      final int input = test[0];
      final int expected = test[1];
      final int actual = q(n -> {
        String r = "";
        for (int i = 0; i <= (n < 0 ? -n : n); ++i) {
          r += i;
        }
        return r.length() - (n < 0 ? n : 0);
      } , input);
      System.out.println("Input:    " + input);
      System.out.println("Expected: " + expected);
      System.out.println("Actual:   " + actual);
      System.out.println();
    }
  }

  private static int q(java.util.function.IntFunction<Integer> f, final int input) {
    return f.apply(input);
  }
}
\$\endgroup\$
1
\$\begingroup\$

J, 20 bytes

(#":i.1+|p)-(p+|p)%2
\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! By default, all answers to code golf challenges must be full programs or functions. Taking input from predefined varibales is not allowed. \$\endgroup\$ – Dennis Mar 14 '17 at 3:34
  • \$\begingroup\$ Sorry, I was unaware, I'll correct it as soon as I figure out a compact valid method. \$\endgroup\$ – Bijan Mar 14 '17 at 12:56
1
\$\begingroup\$

CJam, 15 bytes

ri_g\z),f*:`:+,

Try it online!

Explanation:

ri_g\z),f*:`:+, e# Accepts an integer from STDIN.
ri              e# Get integer from STDIN.
  _g\           e# Store the integer's sign behind it.
     z)         e# Take the absolute value and increment it, to make an
                e# implicit range.
       ,        e# Create range [0..N].
        f*      e# Multiply every integer in the range with the sign we
                e# stored earlier, so as to include the - signs.
          :`    e# Map repr.
            :+  e# Concatenate.
              , e# Length.
\$\endgroup\$
0
\$\begingroup\$

C#, 59 76 bytes

n=>string.Concat(System.Linq.Enumerable.Range(n>0?0:n,(n<0?-n:n)+1)).Length;

Longer than I wanted it to be because of the minus and Range takes a start and a count not start and end.

\$\endgroup\$
0
\$\begingroup\$

GolfScript, 33 bytes

~.abs),\.{.abs/}0if:S;{S*`,}%{+}*

Try it online!

Explanation:

~.abs),\.{.abs/}0if:S;{S*`,}%{+}* # Evals STDIN.
~                                 # Eval.
 .abs),\                          # Store an absolute value inclusive range behind the original integer.
        .{.abs/}0if:S;            # Store the integer's sign in S.
                      {S*`,}%     # After applying the input's sign, get the length of the string representation of every integer in the range.
                             {+}* # Sum.
\$\endgroup\$
0
\$\begingroup\$

Python, 63 bytes

lambda n:sum(map(len,map(str,range(*[[0,n-1,-1],[n+1]][n>0]))))
\$\endgroup\$
0
\$\begingroup\$

Bean, 44 bytes

xxd-style hexdump:

00000000: 2653 4da0 6280 40a0 7852 a043 ccd0 80cc  &SM b.@ xR CÌÐ.Ì
00000010: a043 8b23 0020 8001 8b53 a062 4da0 4382   C.#. ...S bM C.
00000020: 53d0 80a0 1f20 8048 2043 253a            SÐ. . .H C%:

Equivalent JavaScript (adapted from @Dennis) (45 bytes):

(f=_=>A?(A+"").length+f(A-=Math.sign(A)):1)()

Explanation

Declares a recursive IIFE (immediately invoked function expression) f, using pre-initialized variable A with numeric input to count down and incrementally calculate the amount of characters in the range of numbers.

Try the demo here

\$\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.