What's the point?

22

Write a program or function that takes in two integers that represent the X and Y coordinates of a point on a Cartesian plane.

The input may come in any reasonable format as long as the X value comes before the Y. For example, 1 -2, (1,-2), [1, -2], or 1\n-2 would all be fine for X = 1, Y = -2.

Print or return a single character string (followed by an optional trailing newline) that describes the location of the point in the plane:

  • 1 if the point is in quadrant I
  • 2 if the point is in quadrant II
  • 3 if the point is in quadrant III
  • 4 if the point is in quadrant IV
  • X if the point is on the x-axis (lowercase x is not allowed)
  • Y if the point is on the y-axis (lowercase y is not allowed)
  • O if the point is on the origin (that's a capital letter "oh", not zero)

The shortest code in bytes wins. Tiebreaker goes to the higher voted answer.

Test Cases

(1,-2) -> 4
(30,56) -> 1
(-2,1) -> 2
(-89,-729) -> 3
(-89,0) -> X
(0,400) -> Y
(0,0) -> O
(0,1) -> Y
(0,-1) -> Y
(1,0) -> X
(-1,0) -> X
(1,1) -> 1
(1,-1) -> 4
(-1,1) -> 2
(-1,-1) -> 3

Calvin's Hobbies

Posted 2016-01-29T21:55:37.400

Reputation: 84 000

So for the purposes of this challenge, X and Y axis are in no quadrant? – Rɪᴋᴇʀ – 2016-01-29T22:02:56.233

@RikerW Right. Otherwise the point (0, 9) could be said to be quadrant I or II. – Calvin's Hobbies – 2016-01-29T22:05:08.827

Is a complex number (or a string representation of it, like "30+56i") a valid input format? – Level River St – 2016-01-29T23:21:05.787

@steveverrill Yes – Calvin's Hobbies – 2016-01-29T23:50:34.877

Can the input be in the form of a complex number? (e.g. 1+2j) – Digital Trauma – 2016-01-30T19:47:19.363

Answers

16

Jelly, 14 bytes

Ṡḅ3ị“Y4X13X2YO

Try it online!

How it works

Ṡḅ3ị“Y4X13X2YO    Main link. Input: [x, y]

Ṡ                 Apply the sign function to both coordinates.
 ḅ3               Convert the resulting pair from base 3 to integer.
                  Because of how base conversion is implemented in Jelly, this maps
                  [a, b] to (3a + b), even if a and b aren't valid ternary digits.
                  Therefore:
                      [0, 1]   ->  1
                      [1, -1]  ->  2
                      [1, 0]   ->  3
                      [1, 1]   ->  4
                      [-1, -1] -> -4
                      [-1, 0]  -> -3
                      [-1, 1]  -> -2
                      [0, -1]  -> -1
                      [0, 0]   ->  0
   ị“Y4X13X2YO    Retrieve the character at that index from the string.
                Indexing is 1-based and modular in Jelly, so 1ị retrieves the
                first character, -1ị the penultimate, and 0ị the last.

Dennis

Posted 2016-01-29T21:55:37.400

Reputation: 196 637

6Joining the Jelly from phone club. – Dennis – 2016-01-29T22:14:02.830

3Aaaaaand Jelly wins once again... – ETHproductions – 2016-01-29T22:16:37.523

Very good approach! – Luis Mendo – 2016-01-29T23:40:32.313

11

Ruby, 35 bytes

->x,y{%w[OY X14 X23][x<=>0][y<=>0]}

Leveraging the "spaceship" (<=>) operator.

x <=> 0 will return

  • 0 if x == 0
  • 1 if x > 0
  • -1 if x < 0

Hence,

  • if x == 0, we return 'OY'[y<=>0]. This is

    • O if y == 0 (string indexing at 0)

    • Y if y != 0 (this is true because both 1 and -1 will result in Y when indexing on this string, as -1 refers to the last character in the string, which also happens to be the one at index 1)

  • if x > 0, we return 'X14'[y<=>0]. This is X if y == 0, 1 if y > 0, and 4 if y < 0 (see explanation above).

  • if x < 0, we return 'X23'[y<=>0].

Doorknob

Posted 2016-01-29T21:55:37.400

Reputation: 68 138

6

JavaScript, 44 bytes

(x,y)=>x?y?x>0?y>0?1:4:y>0?2:3:'X':y?'Y':'O'

f=(x,y)=>x?
            y?
                x>0?
                    y>0?1
                    :4
                :y>0?2:3
            :'X'
        :y?'Y':'O'

document.body.innerHTML = '<pre>' +
    'f(1,-2) -> ' + f(1,-2) + '<br>' +
    'f(30,56) -> ' + f(30,56) + '<br>' +
    'f(-2,1) -> ' + f(-2,1) + '<br>' +
    'f(-89,-729) -> ' + f(-89,-729) + '<br>' +
    'f(-89,0) -> ' + f(-89,0) + '<br>' +
    'f(0,400) -> ' + f(0,400) + '<br>' +
    'f(0,0) -> ' + f(0,0) + '<br>' +
    'f(0,1) -> ' + f(0,1) + '<br>' +
    'f(0,-1) -> ' + f(0,-1) + '<br>' +
    'f(1,0) -> ' + f(1,0) + '<br>' +
    'f(-1,0) -> ' + f(-1,0) + '<br>' +
    'f(1,1) -> ' + f(1,1) + '<br>' +
    'f(1,-1) -> ' + f(1,-1) + '<br>' +
    'f(-1,1) -> ' + f(-1,1) + '<br>' +
    'f(-1,-1) -> ' + f(-1,-1) + '<br>' +
'</pre>';

removed

Posted 2016-01-29T21:55:37.400

Reputation: 2 785

3My eyes hurt, that's one long chain of ternary operators – andlrc – 2016-01-29T23:10:26.273

1afaik its allowed to write an anonymous function (s/^f=//) – andlrc – 2016-01-29T23:13:40.383

5

ES6, 43 bytes

(x,y)=>"OYYX32X41"[3*!!x+3*(x>0)+!!y+(y>0)]

A whole byte shorter than all of those ternaries!

Neil

Posted 2016-01-29T21:55:37.400

Reputation: 95 035

3

Japt, 30 22 bytes

"3Y2XOX4Y1"g4+3*Ug +Vg

Inspired by @Dennis' Jelly answer before he added an explanation. Test it online!

Fun fact: this would be two bytes shorter if I had added support for negative numbers in the g function for strings.

Another attempt, closer to the Jelly one (23 bytes):

"3Y2XOX4Y1"gNmg m+1 ¬n3

Sadly, incrementing a list costs 4 bytes...

ETHproductions

Posted 2016-01-29T21:55:37.400

Reputation: 47 880

2

MATL, 22 bytes

'3X2YOY4X1'iZSQI1h*sQ)

This uses current release (10.2.1) of the language/compiler.

Try it online!

Explanation

This shamelessly borrows the great approach in Dennis' answer.

'3X2YOY4X1'     % literal string. Will be indexed into to produce result
i               % input array of two numbers
ZS              % sign of each number in that array. Gives -1, 0 or 1
Q               % add 1 to produce 0, 1 or 2
I1h             % array [3 1]
*s              % multiply both arrays element-wise and compute sum
Q               % add 1. Gives a value from 1 to 9
)               % index into string. Display

Luis Mendo

Posted 2016-01-29T21:55:37.400

Reputation: 87 464

2

Pyth, 18 bytes

@"OY4X13X2Y"i._RQ3

Explanation:

                   - Autoassign Q = eval(input())
             ._RQ  - map(cmp, Q)
            i    3 - convert to base 3
@"OY4X13X2Y"       - "OY4X13X2Y"[^] (A lookup table)

Try it here.

Or the whole test suite

Blue

Posted 2016-01-29T21:55:37.400

Reputation: 26 661

1

Python 2, 75 bytes

lambda x,y,b=bool:[['OX','YO'][b(y)][b(x)],[[1,2],[4,3]][y<0][x<0]][b(x*y)]

Pretty straightforward.

Mego

Posted 2016-01-29T21:55:37.400

Reputation: 32 998

1

Mathematica 81 bytes

Switch[Sign@#,{1,-1},4,{1,1},1,{-1,1},2,{-1,-1},3,{0,0},"O",{_,0},"X",{0,_},"Y"]&

%/@{{1, -2}, {30, 56}, {-2, 1}, {-89, -729}, {-89, -0}, {0, 400}, {0, 0},{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}

{4, 1, 2, 3, "X", "Y", "O", "Y", "Y", "X", "X", 1, 4, 2, 3}

DavidC

Posted 2016-01-29T21:55:37.400

Reputation: 24 524

1

Retina, 52

This is a simple substitution-based method:

^0 0
O
^0.*
Y
.* 0
X
-.*-.*
3
^-.*
2
.*-.*
4
.* .*
1

Try it online. The extra m` at the start of some lines is only needed to test multiple inputs in one go, so are not counted in the score.


Previously I tried this more interesting approach, but its quite a bit longer (about 65 without the m modifiers):

[1-9]\d*
1
-1
2
(.) (.)
$1$*3$2$*1
3
111
m`^(.)*$
$#1
T`d`OYYX14X23
  • substitute all non-zero numbers to 1, leaving - signs in place
  • Substitute -1 with 2
  • Convert 1st and 2nd numbers unary with 3 and 1 respectively as the unary digits . This effectively gives 2 base3 digits, expressed in unary
  • Convert to 3s to 111. This effectively gives the a single unary number that corresponds to each of the quadrants, axes and origin
  • Convert the unary to one decimal digit
  • Transpose the decimal digit to the appropriate output char.

Digital Trauma

Posted 2016-01-29T21:55:37.400

Reputation: 64 644

1I don't think the X stage needs $ since there won't be leading zeroes in the input. – Martin Ender – 2016-01-30T10:10:55.370

1

The more interesting approach can be shortened to at least 40 bytes. Now I will look at it tomorrow some more.

– randomra – 2016-01-31T00:28:36.513

For batch run you need some tweaking.

– randomra – 2016-01-31T00:28:42.943

1

Pyth, 24

Too long, but perhaps an interesting approach:

?Q?sQ?eQh%/yPQ.n04\X\Y\O

The input must be specified as a complex number, e.g. 1-2j. Basically a nested ternary to test:

  • if input is zero - output O
  • else if real part is zero - output Y
  • else if imaginary part is zero - output X
  • else calculate the complex phase, multiply by 2, integer divide by π, then mod and add to give the appropriate quadrant number.

Try it online.

Digital Trauma

Posted 2016-01-29T21:55:37.400

Reputation: 64 644

1

Octave, 34 bytes

@(p)['3X2YOY4X1'](sign(p)*[3;1]+5)

The old base-3 trick through vector multiplication (although I had to add 5 to account for 1-based array indices) plus some Octave indexing magic.

Input is a vector of the form [1, -2] (with or without the comma), so when assigned to a variable w:

>> w([1 -2])
ans = 4

Here it is on ideone.

beaker

Posted 2016-01-29T21:55:37.400

Reputation: 2 349

Ideone seems to be working again. Did you do anything special to use it? – Luis Mendo – 2016-02-01T20:35:13.030

@LuisMendo This one uses an anonymous function. Named functions are still borked for me. :( – beaker – 2016-02-01T21:17:45.457

Aah, you are right. It was named functions that were not working. So still the same :-/ – Luis Mendo – 2016-02-01T21:54:49.087

1

Java 8, 64 bytes

this is a lambda expression for a BiFunction<Integer,Integer,String>.

(x,y)->"OYYX14X23".charAt(3*(x>0?1:x<0?2:0)+(y>0?1:y<0?2:0))+"";

3 bytes could be saved by returning a Character instead of a String but i'm not completely sure if autoboxing will play nicely with the lambda.

Jack Ammo

Posted 2016-01-29T21:55:37.400

Reputation: 430

1

Oh neat, this answer using the PCCG Handicap System scores better (1.5598) than Dennis's Jelly answer (1.5929).

– Draco18s no longer trusts SE – 2016-02-10T17:59:38.543

that's quite interesting. thanks for pointing that out – Jack Ammo – 2016-02-10T18:49:59.430

1Ran the values for a few entries on this one out of curiosity (all scores were between 1.5 and 2, for reference). – Draco18s no longer trusts SE – 2016-02-10T18:51:51.890