15
\$\begingroup\$

Find the original challenge here

Challenge

Given an integer, Z in the range -2^31 < Z < 2^31, output the number of digits in that number (in base 10).

Rules

You must not use any string functions (in the case of overloading, you must not pass a string into functions which act as both string and integer functions). You are not allowed to store the number as a string.

All mathematical functions are allowed.

You may take input in any base, but the output must be the length of the number in base 10.

Do not count the minus sign for negative numbers. Number will never be a decimal.

Zero is effectively a leading zero, so it can have zero or one digit.

Examples

Input > Output

-45 > 2
1254 > 4
107638538 > 9
-20000 > 5
0 > 0 or 1
-18 > 2

Winning

Shortest code in bytes wins.

\$\endgroup\$
5
  • \$\begingroup\$ I assume no array functions either? \$\endgroup\$
    – Cyoce
    May 19, 2017 at 16:45
  • \$\begingroup\$ @Cyoce Yes, no array functions \$\endgroup\$
    – Beta Decay
    May 19, 2017 at 17:04
  • 1
    \$\begingroup\$ So if a language only accepts input as a string, it's invalid for this challenge, right? \$\endgroup\$ May 19, 2017 at 19:24
  • \$\begingroup\$ @EngineerToast Yes, very much so \$\endgroup\$
    – Beta Decay
    May 19, 2017 at 19:33
  • 1
    \$\begingroup\$ I'm removing the restricted source tag because while this is a restriction it is not a real source restriction in that it is not computer tractable. \$\endgroup\$
    – Wheat Wizard
    May 19, 2017 at 21:50

46 Answers 46

9
\$\begingroup\$

Mathematica, 13 bytes

IntegerLength

Well...

\$\endgroup\$
5
  • \$\begingroup\$ According to codegolf.meta.stackexchange.com/a/3605/14732 this makes this question a duplicate. \$\endgroup\$ May 20, 2017 at 12:15
  • \$\begingroup\$ @IsmaelMiguel Well, this is a slightly trickier case, because the challenge is effectively a duplicate in some languages but not at all on others. \$\endgroup\$ May 20, 2017 at 12:38
  • \$\begingroup\$ Most answers there can be just copied over to here. \$\endgroup\$ May 20, 2017 at 13:00
  • \$\begingroup\$ @IsmaelMiguel I'd have to go and count, but I believe the majority of answers on the previous challenge used string processing which is not an option here. \$\endgroup\$ May 20, 2017 at 13:02
  • \$\begingroup\$ Meh, I lost the count 3 times. But seems to actually be around 30-45% of the answers. Those can be just copied over. \$\endgroup\$ May 20, 2017 at 13:07
7
\$\begingroup\$

Python 2, 30 bytes

f=lambda x:x and-~f(abs(x)/10)

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ @Notts90 I do, because it is referenced inside. \$\endgroup\$
    – Leaky Nun
    May 19, 2017 at 17:49
7
\$\begingroup\$

Japt, 5 3 bytes

ì l

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ I pushed a fix that makes the a unnecessary -- 5 minutes before the challenge was posted :-) Unfortunately, that means it'll only work on the online interpreter. (test it online!) \$\endgroup\$ May 19, 2017 at 14:28
  • \$\begingroup\$ Awesome. Well done ninja'ing the question ; ) \$\endgroup\$
    – Luke
    May 19, 2017 at 14:33
6
\$\begingroup\$

JavaScript (ES6), 19 bytes

f=n=>n&&f(n/10|0)+1

console.log(f(-45))       // 2
console.log(f(1254))      // 4
console.log(f(107638538)) // 9
console.log(f(-20000))    // 5
console.log(f(0))         // 0
console.log(f(-18))       // 2

\$\endgroup\$
2
  • \$\begingroup\$ do we count "f="? lots of the other languages here present the function definition by itself. \$\endgroup\$
    – Sparr
    May 19, 2017 at 15:06
  • 5
    \$\begingroup\$ @Sparr This is a recursive function that references itself. So in this special case, yes, we count f=. \$\endgroup\$
    – Arnauld
    May 19, 2017 at 15:07
5
\$\begingroup\$

My answer from the other challenge still works:

Brachylog, 1 byte

l

Try it online!

The l builtin is overloaded, but on integers, it takes the number of digits of the integer, ignoring sign.

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

Jelly, 3 2 bytes

1 byte saved thanks to Leaky Nun

DL

Try it online!

Explanation

 L    Length of
D     Decimal expansion of input argument. Works for negative values too
\$\endgroup\$
4
  • \$\begingroup\$ DL? \$\endgroup\$
    – Leaky Nun
    May 19, 2017 at 13:55
  • \$\begingroup\$ I was trying to do this. But I couldn't find what I needed on the code page :( \$\endgroup\$ May 19, 2017 at 14:01
  • \$\begingroup\$ "length" of an integer, using the same function that gives the length of a string, really feels like a string function... \$\endgroup\$
    – Sparr
    May 19, 2017 at 15:04
  • 1
    \$\begingroup\$ Not lenght of an integer, but of a list of its digits (obtained with D). The challenge says: in the case of overloading, you must not pass a string into functions which act as both string and integer functions This answer follows that rule: I'm not passing a string \$\endgroup\$
    – Luis Mendo
    May 19, 2017 at 15:08
4
+100
\$\begingroup\$

APL (Dyalog Unicode), 7 bytes

⌈10⍟1+|

Try it online!

Explanation:

⌈10⍟1+|
⌈        ⍝ round up the
 10⍟     ⍝ log10 of...
    1+   ⍝ incremented
      |  ⍝ absolute value of input

If format is allowed: 4 bytes - ≢⍕∘|

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

Chaincode, 5 bytes

pqL_+

Note: This is exactly the same code as that from the other challenge

Explanation

pqL_+ print(
    +   succ(
   _      floor(
  L        log_10(
pq           abs(
               input())))))
\$\endgroup\$
3
\$\begingroup\$

dc, 1 byte

Z

Try it online!


Not using a builtin, 18 bytes:

[d10/d0!=F]dsFxz1-

Try it online!

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

R, 40 bytes

function(x)max(ceiling(log10(abs(x))),0)

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ I realize it's been 3 years, but here's a 38 byte version. \$\endgroup\$ Apr 18, 2021 at 18:48
3
\$\begingroup\$

Pip, 14 bytes

LNABq/LNt//1+1

https://tio.run/##K8gs@P/fx8/RqVDfx69EX99Q2/D/f0MDczNjC1NjCwA

Explanation

LN              natural log of...      (change of base becasue this is the only log function they had)
  ABq           the absolute value of the input...
     /          divided by...
      LNt       the natural log of 10...   (change of base)
         //1    integer divided by 1 (no floor function)
            +1  added to 1

This was inspired by the Chaincode solution.

This could probably be optimized.

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to Code Golf, nice first answer! \$\endgroup\$ Jan 7, 2021 at 5:41
3
\$\begingroup\$

Java 8, 61 59 39 37 33 bytes

n->(int)Math.log10(n<0?-n:n+.5)+1

-4 bytes thanks to @MarkJeronimus.

Try it online.

Explanation:

n->            // Method with integer as both parameter and return-type
  (int)        //  Convert the following double to an integer (truncating its decimals):
    Math.log10(//   The log_10 of:
      n<0?     //    If the input is negative:
          -n   //     Use its absolute value
         :     //    Else:
          n+.5)//     Add 0.5 to the input instead
  +1           //  And add 1 to the result at the end
\$\endgroup\$
2
  • 1
    \$\begingroup\$ 33: n->(int)Math.log10(n<0?-n:n+.5)+1 \$\endgroup\$ Apr 17, 2021 at 21:03
  • \$\begingroup\$ @MarkJeronimus Thanks! :) \$\endgroup\$ Apr 18, 2021 at 11:28
2
\$\begingroup\$

S.I.L.O.S, 41 bytes

readIO
i|
lblb
i/10
a+1
if i b
printInt a

Try it online!

Returns 1 for 0.

\$\endgroup\$
1
  • \$\begingroup\$ Why is there no love for SILOS, its golfier than python for this challenge! \$\endgroup\$ May 20, 2017 at 1:32
2
\$\begingroup\$

Lua, 40 bytes

Port from my python answer

print(math.log10(math.abs(10*...)+1)//1)

Try it online!

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

Alice, 16 bytes

/O
\I@/Hwa:].$Kq

Try it online!

Explanation

/O
\I@/...

This is simply a framework for numerical input→mathematical processing→numerical output.

The rest of the code is the real algorithm:

Hwa:].$Kq
H            Compute absolute value
 w   .$K     While the result is not zero do:
  a:           divide the number by 10
    ]          move the tape head one cell forward
        q    Get the position of the tape head
\$\endgroup\$
2
\$\begingroup\$

Julia, 7 bytes

ndigits

Try it online!

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

PowerShell Core, 46 bytes

param($a)for($s=0;$a){$s+=!!($a=[int]$a/10)}$s

Implementation Details

param($a)              # Defines the input parameter
for($s=0;$a){          # Initialise the result to 0 and iterates while the parameter is not 0 
$s+=!!($a=[int]$a/10)  # Divides the parameter by 10 and increment the result variable
                       # by one if the result is not 0
}$s                    # Returns the result

Try it online!

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

Excel, 26 bytes

=INT(LOG(A1^2+(A1=0))/2)+1

Log of the number squared / 2 is 1 byte shorter than ABS

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

K (ngn/k), 10 9 7 bytes

-3 bytes from @ngn (see Am I an insignificant array?)

#10\#!:

Try it online!

  • #!: get the absolute value of the input (literally, take the count of the range of each value; e.g. #!-2 -> #-2 -1 -> 2)
  • 10\ "digit-ize" the input
  • # take the count

A solution using $ instead of 10\ save two bytes, but may be invalid given the question's rules.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ -1 byte: #10\|/-:\ \$\endgroup\$
    – ngn
    Dec 26, 2020 at 22:17
  • \$\begingroup\$ Thanks, very neat use of monadic scan/converge! \$\endgroup\$
    – coltim
    Dec 26, 2020 at 22:31
1
\$\begingroup\$

Jelly, 5 bytes

A‘l⁵Ċ

Try it online!

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

C#, 49 56 bytes

namespace System.Math{n=>n==0?1:Floor(Log10(Abs(n))+1);}
\$\endgroup\$
0
1
\$\begingroup\$

Python 2, 48 bytes

-3 thanks to ovs -1 thanks to pizzapants

lambda x:math.log10(abs(10*x)+1)//1
import math

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ lambda x:1+log10(abs(x)+.1)//1 for 48 bytes \$\endgroup\$
    – ovs
    May 19, 2017 at 14:14
  • \$\begingroup\$ import math and math.log10 saves one byte \$\endgroup\$ May 19, 2017 at 19:47
1
\$\begingroup\$

C, 27 bytes

Try Online

f(n){return n?1+f(n/10):0;}

C (gcc), 22 bytes

f(n){n=n?1+f(n/10):0;}

Using math, 29 bytes

f(n){return 1+log10(abs(n));}
\$\endgroup\$
1
\$\begingroup\$

Ruby, 27 bytes

f=->x{x==0?0:1+f[x.abs/10]}

As a test:

tests = [[-45 , 2],
         [1254 , 4],
         [107638538 , 9],
         [-20000 , 5],
         [0 , 0 ],
         [-18 , 2]]

tests.each do |i, o|
  p f.call(i) == o
end

It outputs:

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

@yBASIC, 53 bytes.

_#=@_>.@_
_%=_%/(_#*_#+!.)_=_+!.GOTO(@_)+"_"*!_%@__?_

Input should be stored in variable _%

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

Rust, 41 bytes

fn f(n:i32)->u8{n!=0&&return f(n/10)+1;0}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to PPCG. \$\endgroup\$ Apr 22, 2018 at 8:25
1
\$\begingroup\$

Pyth, 10 bytes

.xhs.l.aQT

Test suite

Explanation:
.xhs.l.aQT  # Code
.xhs.l.aQTQ # With implicit variables
            # Print (implicit):
    .l   T  #   the log base 10 of:
      .aQ   #    the absolute value of the input
   s        #   floored
  h         #   plus 1
.x        Q #  unless it throws an error, in which case the input
Python 3 translation:
import math
Q=eval(input())
try:
    print(int(math.log(abs(Q),10))+1)
except:
    print(Q)
\$\endgroup\$
1
\$\begingroup\$

Gol><>, 12 bytes

SA:z+aSLS(PB

Try it online!

Example full program & How it works

1AGIE;GN
SA:z+aSLS(PB

1AGIE;GN
1AG       Register row 1 as function G
   IE;    Take input as int, halt if EOF
      GN  Call G and print the result as int

SA:z+aSLS(PB
SA            Absolute value
  :z+         Add 1 if zero
     aSL      Take log 10
        S(    Floor
          PB  Increment and return

Many math functions are prefixed with S, which made the code longer.

Adding 0.9 unconditionally (9a,+) and using ceiling (S)) is also possible with same byte count. Zero input yields 0 in this case.

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

ARM Thumb-2 (no div instruction, no libgcc), 30 bytes

Raw machine code:

2800 d00b bfb8 4240 2201 2100 3101 380a
dafc 3201 0008 280a daf7 0010 4770     

Uncommented assembly:

        .syntax unified
        .globl count_digits
        .thumb
        .thumb_func
count_digits:
        cmp     r0, #0
        beq     .Lret
        it      lt
        neglt   r0, r0
        movs    r2, #1
.Lcountloop:
        movs    r1, #0
.Ldivloop:
        adds    r1, #1
        subs    r0, #10
        bge     .Ldivloop
.Ldivloop_end:
        adds    r2, #1
        movs    r0, r1
        cmp     r0, #10
        bge     .Lcountloop
.Lcountloop_end:
        movs    r0, r2
.Lret:
        bx      lr

Returns 0 if 0.

Explanation

C function signature:

int32_t count_digits(int32_t val);

First, we compare val to zero.

If it is zero, we return zero. If it is less than zero, we negate it.

count_digits:
        cmp     r0, #0
        beq     .Lret
        it      lt
        neglt   r0, r0

Set up our digit counter for the outer loop.

        movs    r2, #1

Now, a naïve subtraction based division loop

        movs    r1, #0
.Ldivloop:
        adds    r1, #1
        subs    r0, #10
        bge     .Ldivloop

Increment the digits counter, then loop to the outer loop if we are still more than 10.

.Ldivloop_end:
        adds    r2, #1
        movs    r0, r1
        cmp     r0, #10
        bge     .Lcountloop

Move the result into the return register and return.

.Lcountloop_end:
        movs    r0, r2
.Lret:
        bx      lr
\$\endgroup\$
1
\$\begingroup\$

Perl 5 -Minteger -p, 26 24 bytes

1while++$\*abs($_/=10)}{

Try it online!

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