Your challenge is to determine whether the given input is an integer, a string, or a decimal.


  • A string is any input that is not an integer or a float
  • An integer must contain only numeric characters and must not start with a zero
  • A decimal is any input that contains the period (.) and the period is surrounded by numeric characters.

Note: .01 is not considered a valid decimal.

  • The program should output a raw string either "string", "integer", or "decimal".
  • You may assume only printable ASCII characters are used


asdf -> string
asdf3.4 -> string
2 -> integer
2.0 -> decimal
02 -> string
40. -> string
. -> string
.01 -> string
0.0 -> decimal
.9.9.9 -> string
[empty space] -> string

EDIT: Fixed the typo. I meant .01 without the leading zero, not with. If that made it unclear, its fixed now!

This is , so shortest answer wins.

  • 5
    \$\begingroup\$ Why is 02 not an integer? These just feel like arbitrary restrictions in order to increase challenge difficulty. \$\endgroup\$ Dec 26, 2015 at 0:57
  • 1
    \$\begingroup\$ I think 02 isn't considered an integer because most languages trim leading zeros when the type is an integer but keep leading zeros when it is stored as a string. Although, I'm with @isaacg that if 0.0 is considered a decimal, then 0.01 should be too. .01 not counting makes sense, I guess... \$\endgroup\$ Dec 26, 2015 at 1:14
  • 3
    \$\begingroup\$ @Zequ .01 not counting makes sense, I guess... - why? It's valid in almost every language. \$\endgroup\$
    – user42643
    Dec 26, 2015 at 1:30
  • 2
    \$\begingroup\$ Welcome to Programming Puzzles & Code Golf! There's no need to unnecessarily ping everyone who's commented on your question; your edit automatically puts your question into the reopen queue, where it will be reopened if necessary. Furthermore, many of your challenges seem to have been closed; you might want to try running them through our Sandbox first. Thanks! \$\endgroup\$
    – Doorknob
    Dec 26, 2015 at 2:41
  • 1
    \$\begingroup\$ @CrazyPython I think the idea you're getting at with "valid integer" and "valid decimal" is the idea of a canonical representation. As I understand your rules, there's exactly one way to write each integer and each decimal. If that's the intent, adding that to the challenge will clarify why the rules are the way they are. \$\endgroup\$
    – isaacg
    Dec 26, 2015 at 2:48

8 Answers 8


Pyth, 33 bytes (39 without packed string)


Some bytes are stripped due to Markdown. Official code and test suite.

Without packed string:


It passes all of above test cases. Basically, to check if a string is a integer or decimal, it checks whether the string can be evaluated as a python literal (v), and if so, if you can add 0 to it and covert it back to its string representation, and get the input string. If so, it's an integer or a decimal. If you can also cast it to an int and still get the original string back, it's an integer.


Javascript, 112 121 87 bytes

Thanks to @edc65 for saving 34 bytes by converting the original code (in the explanation) to ES6. I didn't change the explanation because it shows the logic better.


This basically converts the rules for an integer and decimal in the question into regex checks, and tests them against the given input. If the input doesn't match, then it must be a string. It passes all of the tests given in the question.

Ungolfed + explanation

function b(a) {
    if(/^[1-9]\d*$/.test(a)) // regex check for the rules of an 'integer':
        return"integer";     // ^[1-9] - check to make sure the first digit
                             // \d* - check to make sure that it is followed by zero or more digits
                             // $ - ensures that the previous check continues to the end of the word
    if(/^([1-9]\d+|\d)\.\d+$/.test(a)) // regex check for the rules of a 'decimal', starting from the middle
        return"decimal";     // \. checks for a '.' in the word
                             // the ([1-9]\d+|\d) and \d+ check to make sure the '.' is surrounded by
                             // one or more numerical characters on each side.
                             // the ^,$ ensure that the match is for the whole word
return"string";              // none of the others match, so it must be a string.


  • \$\begingroup\$ This seems to fail on inputs such as 01.23. \$\endgroup\$ Dec 26, 2015 at 11:15
  • \$\begingroup\$ I fixed it, it passes the b("0.123") case. Sorry about that, since it was only explicitly mentioned in the question that an integer couldn't have leading zeros, I assumed it didn't apply to decimals. \$\endgroup\$ Dec 26, 2015 at 22:30
  • \$\begingroup\$ Shortened to ES6 is 83 a=>/^[1-9]\d*$/.test(a)?"integer":/^([1-9]\d+|\d)\.\d+$/.test(a)?"decimal":"string" ... not the shortest possible anyway \$\endgroup\$
    – edc65
    Dec 27, 2015 at 14:39
  • \$\begingroup\$ Thank you, I updated the code, I had to add b= for it to work in Chrome. For me, it shows the original one you posted to be 85 bytes, instead of 83, plus the 2 bytes for a total of 87. \$\endgroup\$ Dec 27, 2015 at 19:15
  • \$\begingroup\$ @Zequ usually assigning the function to a variable (b=) is not counted. And the rest is 83, beware of strange invisible characters inserted by the comment editor - there is some in my previous comment between "str" and "ing" \$\endgroup\$
    – edc65
    Dec 27, 2015 at 20:52

Java, 133 bytes

String t(String v){if(v.matches("[1-9]\\d*"))return "integer";if(v.matches("(0|[1-9]\\d+)\\.\\d+"))return "decimal";return "string";}

JavaScript (ES6), 74 75

Edit 1 byte saved thx Zequ




console.log=x=>O.textContent +=x +'\n';

// test cases from the question and some more
i=['2', '11', '1000']
d=['2.0','0.0', '1.009', '911.1','123.4567890']

s.forEach(x=>console.log('<'+x+'> -> '+f(x)))
i.forEach(x=>console.log('<'+x+'> -> '+f(x)))
d.forEach(x=>console.log('<'+x+'> -> '+f(x)))
<pre id=O></pre>

  • \$\begingroup\$ You could save a byte by changing [^0\D] in the regex match to [1-9] \$\endgroup\$ Dec 27, 2015 at 19:22
  • \$\begingroup\$ @Zequ good hint, thanks ... using a compound range seemed so clever :( \$\endgroup\$
    – edc65
    Dec 27, 2015 at 20:49

Perl 5, 59 bytes

With the -p argument on the command line (which is calculated into the byte count):

  • \$\begingroup\$ Fails for any 00.nn (try 00.00) \$\endgroup\$
    – edc65
    Dec 27, 2015 at 15:53
  • 1
    \$\begingroup\$ Fixed. Though perhaps that should be in the test cases given. \$\endgroup\$
    – Codefun64
    Dec 27, 2015 at 18:43
  • \$\begingroup\$ It should. On the other hand, often the test cases do not cover all the possible cases. \$\endgroup\$
    – edc65
    Dec 28, 2015 at 19:51
  • \$\begingroup\$ Still wrong, now it gives 'integer' for input .0. What is the chop for? \$\endgroup\$
    – edc65
    Dec 28, 2015 at 19:53
  • \$\begingroup\$ Fixed. Lost interest in this challenge. Not sure if I could've optimized this fix or not. Chop was necessary in a previous iteration of the script. It didn't like the newline from user input. \$\endgroup\$
    – Codefun64
    Dec 28, 2015 at 22:19

Perl 6, 61 bytes

{<string integer decimal>[?/^[(\d+\.\d+)|<[1..9]>\d*]$/+?$0]} # 61


say «asdf asdf3.4 2 2.0 02 40. . .01 0.0 .9.9.9 ''».map: {...}
(string string integer decimal string string string string decimal string string)

Python 2, 148 bytes

def f(s):
  t=float(s);assert s[0]!='0'
  if `t+0`==s:return'decimal'
  if `int(t)`==s:return'integer'

assert f('asdf') == 'string'
assert f('asdf3.4') == 'string'
assert f('2') == 'integer'
assert f('2.0') == 'decimal'
assert f('.') == 'string'
assert f('.01') == 'string'
assert f('.9.9.9') == 'string'
assert f(' ') == 'string'    
assert f('40.') == 'string'
assert f('02') == 'string'
assert f('0.0') == 'string'
assert f('00.00') == 'string'

JavaScript ES6, 74 70 bytes

  • \$\begingroup\$ it fails with the test cases from the question. Really, please, test before posting. \$\endgroup\$
    – edc65
    Dec 28, 2015 at 19:41
  • \$\begingroup\$ @edc Thanks for the feedback, though could you please tell me what cases do fail except 02? \$\endgroup\$
    – nicael
    Dec 28, 2015 at 19:45
  • \$\begingroup\$ Glad that you find it by yourself \$\endgroup\$
    – edc65
    Dec 28, 2015 at 20:01
  • \$\begingroup\$ Have a look at my answer for a fiddle. \$\endgroup\$
    – Pavlo
    Dec 29, 2015 at 18:14
  • \$\begingroup\$ It should work with the test cases if you changed /^\d+$/ to ^[1-9]\d* (75 bytes). \$\endgroup\$
    – Chiru
    Feb 8, 2016 at 18:18

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.