In which number set do I belong?

0

Introduction

Mathematicians often work with number sets. These are groups of numbers that share common properties. These are number sets are, in order from most specific to most broad:

Natural numbers   (symbol N): These are the counting numbers: 1, 2, 3, ...
Integers          (symbol Z): These are all the numbers without a fractional part: ..., -3, -2, -1, 0, 1, 2, 3, ...
Rational numbers  (symbol Q): These numbers are the quotients of two integers, such as: 1.1 (11/10), 5.67 (567/100), or 0.333333333... (1/3)
-----The following two numbers sets are equally specific in describing numbers-----
Real numbers      (symbol R): These are positive, zero, and negative numbers, such as: π (3.1415926...), e (2.7182818...), or √2 (1.4142135...)
Imaginary numbers (symbol I): Numbers that give negative values when squared; for this reason they aren't very useful in everyday life.
                              These numbers contain the letter i in them, with i representing the √-1.
                              Examples: 2i, -1.5i 78i, 9i, -3.1415i, i
-----------------------------------------------------------------------------------
Complex numbers   (symbol C): The sum of a real and an imaginary number in the form a + bi, examples: 2 + 7i, 3 + 3i, 1 - i, -8 + i

Note that when there is only a single i, it is not written 1i.

Challenge

Given a number from one of these number sets, print the symbol for the most specific number set that could describe it.

Test cases

Input              Output
73.0            -> N
4/2             -> N
-73             -> Z
-1/3            -> Q
0.56            -> Q
0.555...        -> Q
0.123123123...  -> Q
3.1415926535... -> R
-1.37i          -> I
7892/5 + 23/4i  -> C

Other info

  • Natural numbers and integers may be given with a decimal point followed by a string of zeros
  • To add on to the previous point, any input that can be converted into a simpler form shall have its output corresponding to the simplified input
  • Rational numbers may be given with a / to represent a fraction, or a sequence of numbers occurring 3 or more times followed by ...
  • Numbers ending with ... represent repeated decimals or un-terminated decimal real numbers
  • Any number sets less specific than Q can also have inputs be given as a fraction
  • You do not need to handle repeated decimals or un-terminated decimals for number sets other than Q and R
  • Any error caused by lack of precision in floating point numbers will not invalidate a submission

This is code golf, so shortest code wins. If there is something unclear, let me know in the comments' section or edit the question.

ericw31415

Posted 2017-11-29T23:28:56.810

Reputation: 2 229

Question was closed 2017-11-29T23:54:10.640

9I don't see how one could distinguish Q and R given the limited precision of machine numbers. – xnor – 2017-11-29T23:34:20.517

4More fundamentally, it's not clear to me whether the inputs are number types in our languages, or strings of them. How much control do we have for how an input is given, in a language where, say, 0 can be represented as one of multiple number types? For example, when you say that inputs can be given as a fraction, do you mean that we have to handle inputs that might possibly be fractions, or this is a choice you can opt for? I think there's a lot of subtlety in specifying this challenge and suggest taking it the Sandbox. – xnor – 2017-11-29T23:37:56.753

What's the output of -3/3? – Luis Mendo – 2017-11-29T23:39:09.180

@xnor When I wrote "may", I meant that there exists a possibility. Should I clarify that? – ericw31415 – 2017-11-29T23:40:48.720

1@LuisMendo Very good point but I think you could have expanded. Indeed there are many machines employing only floating point that would say -3/3 = -0.999.. or possibly even 1.000...1. That's why many languages have different operators for integer and noninteger division, so the programmer gets to decide. – Level River St – 2017-11-29T23:44:25.127

@LuisMendo@LevelRiverSt, I hope I have addressed that fact. – ericw31415 – 2017-11-29T23:52:08.367

@xnor I hope the last bullet point addresses that. – ericw31415 – 2017-11-29T23:55:39.940

1@ericw31415 What I think xnor meant is: can we write the program and state "rationals are input with a /"? Or must the program be able to handle both 1/2 and 0.5 as input? – Luis Mendo – 2017-11-29T23:57:31.773

@ericw31415 I don't understand it. It seems like it allows treating R and Q interchangeably -- is that what you mean? And I'm even more confused now with "expression of possibility" vs "permission". – xnor – 2017-11-29T23:57:59.960

@xnor I was trying to say that such an input was possible. For some reason I can't seem to word it correctly though. – ericw31415 – 2017-11-30T00:01:57.650

1@xnor 3 repeats of a sequence of digits before the ... seems to be the distinguishing factor between them – PrincePolka – 2017-11-30T00:09:03.823

such an input was possible Again, possible as in you can choose to use it, or as in you need to support it? – Luis Mendo – 2017-11-30T00:15:35.390

Suggested test case: 4/2 -> N (my initial answer wasn't passing that one; now fixed) – Arnauld – 2017-11-30T00:41:45.307

I is irrational number set... – user202729 – 2017-11-30T01:29:18.530

@user202729 Where'd you see that? – ericw31415 – 2017-11-30T02:22:59.970

Here. – user202729 – 2017-11-30T02:30:07.840

@user202729 From here, I get I is imaginary, and from here I get I is integers.

– ericw31415 – 2017-11-30T02:32:50.053

@LuisMendo I think users can use their judgment as clearly, the first test case and all the ones containing / would fail if they were not supported. – ericw31415 – 2017-11-30T02:44:42.530

Answers

1

JavaScript (ES6), 121 110 bytes

s=>[...'QRCI'].find((_,i)=>[/(.+)\1\1\.\./,/\.\./,/.+[+-].*i/,/i/][i].test(s))||'QNZ'[k=eval(s),k%1?0:k>0?1:2]

Test cases

let f =

s=>[...'QRCI'].find((_,i)=>[/(.+)\1\1\.\./,/\.\./,/.+[+-].*i/,/i/][i].test(s))||'QNZ'[k=eval(s),k%1?0:k>0?1:2]

console.log(f('73.0'           )) // -> N
console.log(f('4/2'            )) // -> N
console.log(f('-73'            )) // -> Z
console.log(f('-1/3'           )) // -> Q
console.log(f('0.56'           )) // -> Q
console.log(f('0.555...'       )) // -> Q
console.log(f('0.123123123...' )) // -> Q
console.log(f('3.1415926535...')) // -> R
console.log(f('-1.37i'         )) // -> I
console.log(f('7892/5 + 23/4i' )) // -> C

Formatted and commented

s =>                  // given the input string s
  [...'QRCI'].find(   // we first apply some regular expressions:
    (_, i) => [       //   i = index
      /(.+)\1\1\.\./, //     i = 0 (Q): 3x the same pattern, followed by '..' -> rational
      /\.\./,         //     i = 1 (R): '..' without the repeated pattern -> real
      /.+[+-].*i/,    //     i = 2 (C): a real part +/- an imaginary part -> complex
      /i/             //     i = 3 (I): just an imaginary part -> imaginary
    ][i].test(s)      //   this is a find(), so we exit as soon as something matches
  ) || 'QNZ'[         // if all regular expressions failed:
    k = eval(s),      //   assume the expression can now be safely evaluated as JS code
    k % 1 ?           //   if there's a decimal part:
      0               //     -> rational
    :                 //   else:
      k > 0 ?         //     if strictly positive:
        1             //       -> natural
      :               //     else:
        2             //       -> integer
  ]                   //

Arnauld

Posted 2017-11-29T23:28:56.810

Reputation: 111 334

Very nice! I probably would not have been able to come up with a regex that fast. – ericw31415 – 2017-11-29T23:54:27.943

Save 1 B using (.+){3} vs. (.+)\1\1 – Ephellon Dantzler – 2017-11-30T03:14:46.943

1@EphellonDantzler This would match any string of at least 3 characters instead of 3 times the same string. – Arnauld – 2017-11-30T07:49:57.053