# Is it an integer, a string, or a decimal?

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

# Rules

• 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

Cases:

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.

• Why is 02 not an integer? These just feel like arbitrary restrictions in order to increase challenge difficulty. – Addison Crump Dec 26 '15 at 0:57
• 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... – hargasinski Dec 26 '15 at 1:14
• @Zequ .01 not counting makes sense, I guess... - why? It's valid in almost every language. – mınxomaτ Dec 26 '15 at 1:30
• 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! – Doorknob Dec 26 '15 at 2:41
• @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. – isaacg Dec 26 '15 at 2:48

# Pyth, 33 bytes (39 without packed string)

@_c."at%¸Ã9hàãáÊ"7.x/MsB+vz0z0


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

Without packed string:

@_c"integerdecimalstring"7.x/MsB+vz0z0


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, 112121 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.

b=a=>/^[1-9]\d*$/.test(a)?"integer":/^([1-9]\d+|\d)\.\d+$/.test(a)?"decimal":"str‌​ing"


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.


}

• This seems to fail on inputs such as 01.23. – LegionMammal978 Dec 26 '15 at 11:15
• 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. – hargasinski Dec 26 '15 at 22:30
• 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 – edc65 Dec 27 '15 at 14:39
• 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. – hargasinski Dec 27 '15 at 19:15
• @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" – edc65 Dec 27 '15 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

f=i=>(i=i.match(/^(0|[1-9]\d*)(\.\d+)?$/))?i[2]?'decimal':'integer':'string'  Test f=i=>(i=i.match(/^(0|[1-9]\d*)(\.\d+)?$/))?i[2]?'decimal':'integer':'string'

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

// test cases from the question and some more
s=['asdf','asdf3.4','02','40.','.','.01','.9.9.9','','0.0.0','00.00','02.00']
i=['2', '11', '1000']
d=['2.0','0.0', '1.009', '911.1','123.4567890']

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

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

# Perl 5, 59 bytes

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

chop;$_=!/\D|^0/?"integer":/^\d+\.\d+$/?"decimal":"string"

• Fails for any 00.nn (try 00.00) – edc65 Dec 27 '15 at 15:53
• Fixed. Though perhaps that should be in the test cases given. – Codefun64 Dec 27 '15 at 18:43
• It should. On the other hand, often the test cases do not cover all the possible cases. – edc65 Dec 28 '15 at 19:51
• Still wrong, now it gives 'integer' for input .0. What is the chop for? – edc65 Dec 28 '15 at 19:53
• 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. – Codefun64 Dec 28 '15 at 22:19

# Perl 6, 61 bytes

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


Usage:

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):
try:
t=float(s);assert s[0]!='0'
if t+0==s:return'decimal'
if int(t)==s:return'integer'
return'string'
except:return'string'

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

w=>w.match(/^\d+\.\d+$/)?"decimal":w.match(/^\d+$/)?"integer":"string"

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