## [Go](//go.dev), 135 bytes ~~~go package n import."strconv" func f(s string)byte{if _,e:=Atoi(s) e==nil{return'i'} if _,e:=ParseFloat(s,64) e==nil{return'f'} return'n'} ~~~ ## [Go](//go.dev), 418 bytes Some people have mentioned that this above code doesnt pass all test cases. I realized, that the rules in the question dont actually match rules used by programming languages on what qualifies as an integer or float. For example, the rules say that `1e3` is not a float, but in reality it is: ~~~go package main import ( "fmt" "strconv" ) func main() { f, err := strconv.ParseFloat("1e3", 64) fmt.Println(f, err) // 1000 <nil> } ~~~ So I made an edit to handle these rules: ~~~go package n import."strconv" func f(s string)byte{if s[0]=='0'&&s[1]!='.'{return'n'} if len(s)>=3&&s[:2]=="-0"&&s[2]!='.'{return'n'} if s[0]=='-'{}else if s[0]>='0'&&s[0]<='9'{}else{return'n'} if s[len(s)-1]>='0'&&s[len(s)-1]<='9'{}else{return'n'} for _,r:=range s{if r=='-'{}else if r=='.'{}else if r>='0'&&r<='9'{}else{return'n'}} if _,e:=Atoi(s);e==nil{return'i'} if _,e:=ParseFloat(s,64);e==nil{return'f'} return'n'} ~~~ Test: ~~~go package n import ( "fmt" "testing" ) type testType struct { in string out byte } var tests = []testType{ {"+1.0", 'n'}, {"--1.0", 'n'}, {"-0", 'i'}, {"-0.0", 'f'}, {"-001.1", 'n'}, {"-1e3", 'n'}, {"-2", 'i'}, {".1", 'n'}, {"00", 'n'}, {"042", 'n'}, {"1.", 'n'}, {"1.0", 'f'}, {"1.0.0", 'n'}, {"1.00", 'f'}, {"1.0ec3", 'n'}, {"123", 'i'}, {"1e+3", 'n'}, {"1e-3", 'n'}, {"1e3", 'n'}, {"42", 'i'}, {"62727.0033", 'f'}, {"644c.33", 'n'}, {"NaN", 'n'}, } func TestNumber(t *testing.T) { for _, test := range tests { out := f(test.in) if out != test.out { fmt.Printf("%v %c %c\n", test.in, test.out, out) } } } ~~~