Convert Input to Direction

15

1

Challenge

Given input in the form <n1>, <n2> where number can be -1, 0, or 1, return the corresponding cardinal direction. Positive numbers move East in the x-axis and South in the y-axis, Negative numbers move West in the x-axis and North in the y-axis.

Output must be in the form South East, North East, North. It is case-sensitive.

If the input is 0, 0, your program must return That goes nowhere, silly!.

Sample Input/Outpot:

1, 1 -> South East

0, 1 -> South

1, -1 -> North East

0, 0 -> That goes nowhere, silly!

This is , the shortest answer in bytes wins.

Matias K

Posted 2017-03-23T21:37:35.440

Reputation: 283

Loosely related – HyperNeutrino – 2017-03-23T21:49:46.467

1Some examples with W, NW and SW are needed. – seshoumara – 2017-03-23T22:10:15.807

@seshoumara I'm on mobile, so no backticks, but NW would be -1, -1 – Matias K – 2017-03-23T23:41:09.617

1Are trailing Spaces allowed? – Arjun – 2017-03-23T23:53:40.483

Uhh... Sure, I guess. As long as it looks the same. – Matias K – 2017-03-24T00:45:00.417

Can we take +1 instead of 1? – user41805 – 2017-03-24T07:38:42.427

No (15 chars minimum to comment) – Matias K – 2017-03-24T07:40:49.723

Can we take the numbers in the opposite order? 1, 0 is "South"? – Stewie Griffin – 2017-03-24T10:21:21.860

No. Must be x, y. – Matias K – 2017-03-24T10:22:19.413

Can we take numbers as two separate command-line arguments? – Erik the Outgolfer – 2017-03-24T12:29:39.097

@EriktheOutgolfer Yes, you can. – Matias K – 2017-03-24T22:14:52.333

Answers

12

Japt, 55 51 bytes

`
SÆ 
NÆ° `·gV +`
E†t
Wƒt`·gU ª`T•t goƒ Í2€e, Ðéy!

Explanation

                      // Implicit: U, V = inputs
`\nSÆ \nNÆ° `       // Take the string "\nSouth \nNorth ".
·                     // Split it at newlines, giving ["", "South ", "North "].
gV                    // Get the item at index V. -1 corresponds to the last item.
+                     // Concatenate this with
`\nE†t\nWƒt`·gU       // the item at index U in ["", "East", "West"].
ª`T•t goƒ Í2€e, Ðéy!  // If the result is empty, instead take "That goes nowhere, silly!".
                      // Implicit: output result of last expression

Try it online!

ETHproductions

Posted 2017-03-23T21:37:35.440

Reputation: 47 880

Um... I... ??? How on earth does this work? Does Japt have like some fancy things that replace common character pairs? – HyperNeutrino – 2017-03-23T21:44:21.340

@HyperNeutrino Yes, Japt uses the shoco compression library which replaces common pairs of lowercase characters with a single byte.

– ETHproductions – 2017-03-23T21:46:29.597

Okay, that's really cool! I'll look into that, see if I can make any use out of it. – HyperNeutrino – 2017-03-23T21:47:19.020

9

Python, 101 87 bytes

Really naive solution.

lambda x,y:['','South ','North '][y]+['','West','East'][x]or'That goes nowhere, silly!'

Thanks to @Lynn for saving 14 bytes! Changes: Using the string.split method actually makes it longer ;_; And also, negative indexes exist in python.

HyperNeutrino

Posted 2017-03-23T21:37:35.440

Reputation: 26 575

5You can cut it down to 87 like this: lambda x,y:('','South ','North ')[y]+('','East','West')[x]or'That goes nowhere, silly!' – Lynn – 2017-03-24T00:35:46.610

2I found a neat way to get some directions, but unfortunately it doesn't seem like it will work for this challenge. Figured I'd share it anyways (perhaps someone craftier than I can figure out how to deal with its problems, like when x or y = 0): lambda x,y:'North htuoS'[::x][:6]+'EastseW'[::y][:4] Edit: it likely will now be too long, but you can make the second slicing [:6*x**2], likewise for the East/West string, if you can circumvent the error on the first slicing. – cole – 2017-03-24T06:48:55.267

@Lynn lambda x,y:('North ','South ')[y+1]+('West','East')[x+1]or'That goes nowhere, silly!' is shorter by 2 bytes – Dead Possum – 2017-03-24T09:22:46.960

@Lynn Oh, thanks! (I forgot about negative indexes!) – HyperNeutrino – 2017-03-24T12:15:28.303

@DeadPossum That won't work because it will return South East for (0, 0). Thank you though! – HyperNeutrino – 2017-03-24T12:17:57.070

@HyperNeutrino Yeah, I missed that – Dead Possum – 2017-03-24T12:26:10.580

Here's a working variant of my alternate solution; I'm bummed that it's unfortunately 99 bytes (it would be closer if it didn't need the or 1).

lambda x,y:'North htuoS'[::y or 1][:6*y*y]+'EastseW'[::x or 1][:4*x*x]or"That goes nowhere, silly!" – cole – 2017-03-24T18:31:35.363

6

PHP, 101 Bytes

[,$b,$a]=$argv;echo$a|$b?[North,"",South][1+$a]." ".[West,"",East][1+$b]:"That goes nowhere, silly!";

Jörg Hülsermann

Posted 2017-03-23T21:37:35.440

Reputation: 13 026

It's a long time since I programmed in PHP, but how does it know North, South, West and East are strings without double-quotes around them? Is this because of the empty String that shares the same array? If yes, does this also mean you cannot have an array with different types at once (like an array with both a string and an integer)? – Kevin Cruijssen – 2017-03-24T12:32:27.923

1

@KevinCruijssen North is a constant http://php.net/manual/en/language.constants.php If the constant not exists it will be interpreted as string. An array in PHP can contain different types. strings can be specified in four ways http://php.net/manual/en/language.types.string.php

– Jörg Hülsermann – 2017-03-24T12:56:40.383

6

Perl 6, 79 bytes

{<<'' East South North West>>[$^y*2%5,$^x%5].trim||'That goes nowhere, silly!'}

Try it

Expanded:

{ # bare block lambda with placeholder parameters 「$x」 and 「$y」

  << '' East South North West >>\ # list of 5 strings
  [                               # index into that with:

    # use a calculation so that the results only match on 0
    $^y * 2 % 5, # (-1,0,1) => (3,0,2) # second parameter
    $^x % 5      # (-1,0,1) => (4,0,1) # first parameter

  ]
  .trim  # turn that list into a space separated string implicitly
         # and remove leading and trailing whitespace

  ||     # if that string is empty, use this instead
  'That goes nowhere, silly!'
}

Brad Gilbert b2gills

Posted 2017-03-23T21:37:35.440

Reputation: 12 713

6

JavaScript (ES6), 106 100 97 93 bytes

It's a very simple approach. It consists of a few ternary operators nested together -

f=a=>b=>a|b?(a?a>0?"South ":"North ":"")+(b?b>0?"East":"West":""):"That goes nowhere, silly!"

Test Cases

f=a=>b=>a|b?(a?a>0?"South ":"North ":"")+(b?b>0?"East":"West":""):"That goes nowhere, silly!"

console.log(f(1729)(1458));
console.log(f(1729)(-1458));
console.log(f(-1729)(1458));
console.log(f(-1729)(-1458));
console.log(f(0)(1729));
console.log(f(0)(-1729));
console.log(f(1729)(0));
console.log(f(-1729)(0));

Arjun

Posted 2017-03-23T21:37:35.440

Reputation: 4 544

a!=0 can be replaced by just a, since 0 is falsy and all other values are truthy. Also, taking input in currying syntax is shorter, and the array appoach is also shorter. – Luke – 2017-03-24T06:27:19.030

@Luke Thanks for the suggestion! I have edited the answer. Now, I am beating the PHP and Python solutions! All because of you!!! Thanks! – Arjun – 2017-03-24T06:30:42.127

Save another byte by doing f=a=>b=> and calling the function like f(1729)(1458); which is the currying syntax that @Luke mentioned. – Tom – 2017-03-24T07:35:10.827

You can safely use a|b instead of a||b. Assuming that the input only consists of -1, 0 or 1 (which is unclear to me), you could replace a>0 and b>0 with ~a and ~b. – Arnauld – 2017-03-24T07:42:26.073

Also, you don't need these parentheses: a?(...):"" / b?(...):"" – Arnauld – 2017-03-24T07:48:30.793

Are you sure you need the semi-colon at the end? – user41805 – 2017-03-24T07:51:53.390

@Luke I think you should post it as an answer! – Arjun – 2017-03-24T09:37:45.910

I don't think you need any of the parentheses ;) – ETHproductions – 2017-03-24T14:50:20.417

He does... These parentheses cannot be left out: a|b?(...)+(...):"", all others can, saving 4B in total. – Luke – 2017-03-24T16:32:52.553

@ETHproductions Thanks a lot! I removed 4 of them. The rest 2 are necessary are necessary, as Luke mentions. – Arjun – 2017-03-25T00:03:40.897

4

Batch, 156 bytes

@set s=
@for %%w in (North.%2 South.-%2 West.%1 East.-%1)do @if %%~xw==.-1 call set s=%%s%% %%~nw
@if "%s%"=="" set s= That goes nowhere, silly!
@echo%s%

The for loop acts as a lookup table to filter when the (possibly negated) parameter equals -1, and concatenating the matching words. If nothing is selected then the silly message is printed instead.

Neil

Posted 2017-03-23T21:37:35.440

Reputation: 95 035

4

JavaScript (ES6), 86 bytes

a=>b=>["North ","","South "][b+1]+["West","","East"][a+1]||"That goes nowhere, silly!"

Explanation

Call it with currying syntax (f(a)(b)). This uses array indices. If both a and b are 0, the result is a falsy empty string. In that case, the string after the || is returned.

Try it

Try all test cases here:

let f=
a=>b=>["North ","","South "][b+1]+["West","","East"][a+1]||"That goes nowhere, silly!"

for (let i = -1; i < 2; i++) {
    for (let j = -1; j < 2; j++) {
        console.log(`${i}, ${j}: ${f(i)(j)}`);
    }
}

Luke

Posted 2017-03-23T21:37:35.440

Reputation: 4 675

3

GNU sed, 100 + 1(r flag) = 101 bytes

s:^-1:We:
s:^1:Ea:
s:-1:Nor:
s:1:Sou:
s:(.*),(.*):\2th \1st:
s:0...?::
/0/cThat goes nowhere, silly!

By design, sed executes the script as many times as there are input lines, so one can do all the test cases in one run, if needed. The TIO link below does just that.

Try it online!

Explanation:

s:^-1:We:                         # replace '-1' (n1) to 'We'
s:^1:Ea:                          # replace '1' (n1) to 'Ea'
s:-1:Nor:                         # replace '-1' (n2) to 'Nor'
s:1:Sou:                          # replace '1' (n2) to 'Sou'
s:(.*),(.*):\2th \1st:            # swap the two fields, add corresponding suffixes
s:0...?::                         # delete first field found that starts with '0'
/0/cThat goes nowhere, silly!     # if another field is found starting with '0',
                                  #print that text, delete pattern, end cycle now

The remaining pattern space at the end of a cycle is printed implicitly.

seshoumara

Posted 2017-03-23T21:37:35.440

Reputation: 2 878

2

Japt, 56 bytes

N¬¥0?`T•t goƒ Í2€e, Ðéy!`:` SÆ NÆ°`¸gV +S+` E†t Wƒt`¸gU

Try it online! | Test Suite

Explanation:

N¬¥0?`Tt go Í2e, Ðéy!`:` SÆ NÆ°`¸gV +S+` Et Wt`¸gU
Implicit U = First input
         V = Second input

N´0?`...`:` ...`qS gV +S+` ...`qS gU
N¬                                                     Join the input (0,0 → "00")
  ¥0                                                   check if input is roughly equal to 0. In JS, "00" == 0
    ?                                                  If yes:
      ...                                               Output "That goes nowhere, silly!". This is a compressed string
     `   `                                              Backticks are used to decompress strings
          :                                            Else:
           ` ...`                                       " South North" compressed
                 qS                                     Split on " " (" South North" → ["","South","North"])
                   gV                                   Return the string at index V
                     +S+                                +" "+ 
                        ` ...`                          " East West" compressed
                              qS gU                     Split on spaces and yield string at index U

Oliver

Posted 2017-03-23T21:37:35.440

Reputation: 7 160

Hint: 00 is exactly the same as 0, as the extra digit gets removed ;) – ETHproductions – 2017-03-24T11:17:21.870

1The second-best solution yet no upvote. I upvote for you. – Arjun – 2017-03-25T15:22:12.333

2

05AB1E, 48 45 43 bytes

õ'†Ô'…´)èUõ„ƒÞ „„¡ )èXJ™Dg_i“§µ—±æÙ,Ú¿!“'Tì

Try it online!

Explanation

õ'†Ô'…´)                                       # push the list ['','east','west']
        èU                                     # index into this with first input
                                               # and store the result in X
          õ„ƒÞ „„¡ )                           # push the list ['','south ','north ']
                    èXJ                        # index into this with 2nd input
                                               # and join with the content of X
                       ™                       # convert to title-case
                        Dg_i                   # if the length is 0
                            “§µ—±æÙ,Ú¿!“       # push the string "hat goes nowhere, silly!"
                                        'Tì    # prepend "T"

Emigna

Posted 2017-03-23T21:37:35.440

Reputation: 50 798

2

Jelly, 40 bytes

Ṛị"“¡ƘƓ“¡+9“»,“wµ“¡ḳ]“»Kt⁶ȯ“¬ɼ¬<¬O÷ƝḤẎ6»

Try it online!

Erik the Outgolfer

Posted 2017-03-23T21:37:35.440

Reputation: 38 134

1

Retina, 84 82 81 bytes

1 byte saved thanks to @seshoumara for suggesting 0...? instead of 0\w* ?

(.+) (.+)
$2th $1st
^-1
Nor
^1
Sou
-1
We
1
Ea
0...?

^$
That goes nowhere, silly!

Try it online!

user41805

Posted 2017-03-23T21:37:35.440

Reputation: 16 320

The output is wrong. OP wants positive numbers to move S in the y-axis and negative numbers to move N. – seshoumara – 2017-03-24T10:08:57.283

@seshoumara Right, fixed it for same bytecount (just had to swap Nor and Sou) – user41805 – 2017-03-24T10:14:03.097

Ok. Also, you can shave 1 byte by using 0...?. – seshoumara – 2017-03-24T10:18:06.347

@seshoumara Thanks for the tip :) – user41805 – 2017-03-24T10:21:41.077

1

C#, 95 102 bytes


Golfed

(a,b)=>(a|b)==0?"That goes nowhere, silly!":(b<0?"North ":b>0?"South ":"")+(a<0?"West":a>0?"East":"");

Ungolfed

( a, b ) => ( a | b ) == 0
    ? "That goes nowhere, silly!"
    : ( b < 0 ? "North " : b > 0 ? "South " : "" ) +
      ( a < 0 ? "West" : a > 0 ? "East" : "" );

Ungolfed readable

// A bitwise OR is perfomed
( a, b ) => ( a | b ) == 0

    // If the result is 0, then the 0,0 text is returned
    ? "That goes nowhere, silly!"

    // Otherwise, checks against 'a' and 'b' to decide the cardinal direction.
    : ( b < 0 ? "North " : b > 0 ? "South " : "" ) +
      ( a < 0 ? "West" : a > 0 ? "East" : "" );

Full code

using System;

namespace Namespace {
    class Program {
        static void Main( string[] args ) {
            Func<Int32, Int32, String> f = ( a, b ) =>
                ( a | b ) == 0
                    ? "That goes nowhere, silly!"
                    : ( b < 0 ? "North " : b > 0 ? "South " : "" ) +
                      ( a < 0 ? "West" : a > 0 ? "East" : "" );

            for( Int32 a = -1; a <= 1; a++ ) {
                for( Int32 b = -1; b <= 1; b++ ) {
                    Console.WriteLine( $"{a}, {b} = {f( a, b )}" );
                }
            }

            Console.ReadLine();
        }
    }
}

Releases

  • v1.1 - + 7 bytes - Wrapped snippet into a function.
  • v1.0 -  95 bytes - Initial solution.

Notes

I'm a ghost, boo!

auhmaan

Posted 2017-03-23T21:37:35.440

Reputation: 906

1That's a code snippet you need to wrap it in a function i.e. add the (a,b)=>{...} bit – TheLethalCoder – 2017-03-24T16:23:43.357

You can use currying to save a byte a=>b=>, might not need the () around the a|b, you might be able to use interpolated strings to get the string built up nicer as well – TheLethalCoder – 2017-03-24T16:26:07.677

Completely forgot to wrap into a function :S. For the () around the a|b, I do need it, otherwise Operator '|' cannot be applied to operands of type 'int' and 'bool'. I've also tried the interpolated strings, but didn't give much though due to the "" giving me errors. – auhmaan – 2017-03-24T16:35:21.953

1

Swift 151 bytes

func d(x:Int,y:Int){x==0&&y==0 ? print("That goes nowhere, silly!") : print((y<0 ? "North " : y>0 ? "South " : "")+(x<0 ? "West" : x>0 ? "East" : ""))}

Stephen

Posted 2017-03-23T21:37:35.440

Reputation: 121

1

PHP, 95 bytes.

This simply displays the element of the array, and if there's nothing, just displays the "default" message.

echo['North ','','South '][$argv[1]+1].[East,'',West][$argv[2]+1]?:'That goes nowhere, silly!';

This is meant to run with the -r flag, receiving the coordenates as the 1st and 2nd arguments.

Ismael Miguel

Posted 2017-03-23T21:37:35.440

Reputation: 6 797

1

Scala, 107 bytes

a=>b=>if((a|b)==0)"That goes nowhere, silly!"else Seq("North ","","South ")(b+1)+Seq("West","","East")(a+1)

Try it online

To use this, declare this as a function and call it:

val f:(Int=>Int=>String)=...
println(f(0)(0))

How it works

a =>                                // create an lambda with a parameter a that returns
  b =>                              // a lambda with a parameter b
    if ( (a | b) == 0)                // if a and b are both 0
      "That goes nowhere, silly!"       // return this string
    else                              // else return
      Seq("North ","","South ")(b+1)    // index into this sequence
      +                                 // concat
      Seq("West","","East")(a+1)        // index into this sequence

corvus_192

Posted 2017-03-23T21:37:35.440

Reputation: 1 889

1

C, 103 bytes

f(a,b){printf("%s%s",b?b+1?"South ":"North ":"",a?a+1?"East":"West":b?"":"That goes nowhere, silly!");}

Steadybox

Posted 2017-03-23T21:37:35.440

Reputation: 15 798

0

Java 7, 130 bytes

String c(int x,int y){return x==0&y==0?"That goes nowhere, silly!":"North xxSouth ".split("x")[y+1]+"WestxxEast".split("x")[x+1];}

Explanation:

String c(int x, int y){               // Method with x and y integer parameters and String return-type
  return x==0&y==0 ?                  //  If both x and y are 0:
     "That goes nowhere, silly!"      //   Return "That goes nowhere, silly!"
    :                                 //  Else:
     "North xxSouth ".split("x"[y+1]  //   Get index y+1 from array ["North ","","South "] (0-indexed)
     + "WestxxEast".split("x")[x+1];  //   Plus index x+1 from array ["West","","East"] (0-indexed)
}                                     // End of method

Test code:

Try it here.

class M{
  static String c(int x,int y){return x==0&y==0?"That goes nowhere, silly!":"North xxSouth ".split("x")[y+1]+"WestxxEast".split("x")[x+1];}

  public static void main(String[] a){
    System.out.println(c(1, 1));
    System.out.println(c(0, 1));
    System.out.println(c(1, -1));
    System.out.println(c(0, 0));
  }
}

Output:

South East
South 
North East
That goes nowhere, silly!

Kevin Cruijssen

Posted 2017-03-23T21:37:35.440

Reputation: 67 575

0

CJam, 68 bytes

"
South 
North 

East
West"N/3/l~W%.=s_Q"That goes nowhere, silly!"?

Try it online! or verify all test cases

Prints one trailing space on [0 -1] or [0 1] (North or South).

Explanation

"\nSouth \nNorth \n\nEast\nWest"  e# Push this string
N/                                e# Split it by newlines
3/                                e# Split the result into 3-length subarrays,
                                  e#  gives [["" "South " "North "]["" "East" "West"]]
l~                                e# Read and eval a line of input
W%                                e# Reverse the co-ordinates
.=                                e# Vectorized get-element-at-index: accesses the element
                                  e#  from the first array at the index given by the 
                                  e#  y co-ordinate. Arrays are modular, so -1 is the last
                                  e#  element. Does the same with x on the other array.
s                                 e# Cast to string (joins the array with no separator)
_                                 e# Duplicate the string
Q"That goes nowhere, silly!"?     e# If it's non-empty, push an empty string. If its empty, 
                                  e#  push "That goes nowhere, silly!"

Business Cat

Posted 2017-03-23T21:37:35.440

Reputation: 8 927

0

Röda, 100 bytes

f a,b{["That goes nowhere, silly!"]if[a=b,a=0]else[["","South ","North "][b],["","East","West"][a]]}

Try it online!

This is a trivial solution, similar to some other answers.

fergusq

Posted 2017-03-23T21:37:35.440

Reputation: 4 867