26
\$\begingroup\$

Two-dimensional programming languages often have mirror commands like / and \ to redirect the instruction pointer on the grid:

>>>>\
    v
    v
<<<</

In this challenge, you're given an incoming direction and a mirror and you need to determine the outgoing direction.

Rules

The incoming direction will be given as one of the characters NESW and the mirror will be given as either / or \. You may receive these in any order. You must use uppercase letters.

You may take input in any convenient format, including a two-character string, a string using some separator between the characters, a pair of characters in a list, or even a pair of singleton strings. If you do use a string with separator, the separator cannot use any of the characters NWSE\/.

Output should be a character from NESW or single-character string.

You may write a program or a function and use any of the our standard methods of receiving input and providing output.

You may use any programming language, but note that these loopholes are forbidden by default.

This is , so the shortest valid answer – measured in bytes – wins.

Test Cases

There are only 8 possible inputs you need to handle, so there is no excuse for not testing your code on all of them:

N /   -->   W
N \   -->   E
E /   -->   S
E \   -->   N
S /   -->   E
S \   -->   W
W /   -->   N
W \   -->   S
\$\endgroup\$
  • 1
    \$\begingroup\$ In languages where backslashes must be escaped on input, are we allowed to assume the input will be "\\" where appropriate? \$\endgroup\$ – JDL Sep 2 '16 at 10:21
  • 4
    \$\begingroup\$ @JDL The actual string (or character) should contain a single \. If your answer is a function submission that takes a string, then of course you'll need \\ in the source code to call it correctly, but if you're reading your input from standard input, for instance, then it should be a single \. In other words, if you call your language's respective string-length function on the input, the result should always be the same, regardless of whether the input contains / or \. \$\endgroup\$ – Martin Ender Sep 2 '16 at 11:10
  • \$\begingroup\$ Alright, I was expecting R to have problems when an unescaped "\" was entered via stdin, but readline() can handle it. \$\endgroup\$ – JDL Sep 2 '16 at 11:46
  • 1
    \$\begingroup\$ @JDL You probably need to enter the string escaping (duplicating) that symbol, but the resulting string will be "N\" \$\endgroup\$ – Luis Mendo Sep 2 '16 at 11:46

21 Answers 21

24
\$\begingroup\$

Python, 40 38 bytes

-2 bytes thanks to @MitchSchwartz (ord(d)+ord(m))%8 -> ord(d)+ord(m)&7

lambda d,m:' NESSWNW'[ord(d)+ord(m)&7]

plain lookup of answer in a list (AKA string) indexed by the smallest mod of the sum of ordinals that works.

Test cases are on ideone

\$\endgroup\$
  • \$\begingroup\$ Dangit, I thought I was being super clever taking the ASCII values, summing them, %8 them, and doing an index. Then I see you posted the same solution over an hour ago. Hah. Have a +1. \$\endgroup\$ – AdmBorkBork Sep 2 '16 at 13:31
21
\$\begingroup\$

Python 2, 40 bytes

lambda c,m,k="NWES":k[k.find(c)^(m>k)+1]

Sp3000 saved one byte (.index.find).

Explanation

We want to map the directions like so:

       \
  N ⇄⇄⇄⇄⇄⇄⇄ E
  ⇅         ⇅
  ⇅         ⇅
/ ⇅         ⇅ /
  ⇅         ⇅
  ⇅         ⇅
  W ⇄⇄⇄⇄⇄⇄⇄ S
       \

We can assign the directions 2-bit codes, and view both flips as XOR-ing the first and second bits:

         xor 2
     0 0 ⇄⇄⇄⇄⇄ 1 0
      ⇅         ⇅
      ⇅         ⇅
xor 1 ⇅         ⇅ xor 1
      ⇅         ⇅
      ⇅         ⇅
     0 1 ⇄⇄⇄⇄⇄ 1 1
         xor 2

The mapping between bit strings and directions happens using the string k. Now we just need to map mirror characters '/' and '\\' to the values 1 and 2. Since '/' < '\\', we could naïvely use (m>'/')+1 as a formula. But wait! Lexicographically,

'/' < 'NWES' < '\\'

and we have 'NWES' nicely assigned to k! So we can use (m>k)+1 instead.

\$\endgroup\$
12
\$\begingroup\$

CJam, 14 bytes

(@MartinEnder ported my Python answer)

l1b" NESSWNW"=

How?

l1b" NESSWNW"= -
l              - read input
 1b            - cast characters as base 1 digits
   " NESSWNW"  - the string " NESSWNW"
             = - modulo index into the string

Tests are on aditsu

\$\endgroup\$
6
\$\begingroup\$

Javascript (ES6), 50 41 40 37 bytes

d=>m=>(S="NWES")[S.search(d)^-~(m>S)]

Saved 3 more bytes by using comparison, thanks to Lynn's answer

Usage

let f =
d=>m=>(S="NWES")[S.search(d)^-~(m>S)]

console.log(f("N")("/"));  //   -->   W
console.log(f("N")("\\")); //   -->   E
console.log(f("E")("/"));  //   -->   S
console.log(f("E")("\\")); //   -->   N
console.log(f("S")("/"));  //   -->   E
console.log(f("S")("\\")); //   -->   W
console.log(f("W")("/"));  //   -->   N
console.log(f("W")("\\")); //   -->   S

\$\endgroup\$
  • \$\begingroup\$ Clever use of ASCII comparisons to get your condition at the end playing your way... \$\endgroup\$ – WallyWest Sep 11 at 1:17
6
\$\begingroup\$

MATL, 19 17 bytes

'NWSE'jy&mjy+Eq-)

Try it online! Or verify the eight cases.

Explanation

'NWSE'    % Push this string
j         % Take first input, say 'W'. Stack contains: 'NWSE', 'W'
y         % Duplicate from below. Stack: 'NWSE', 'W', 'NWSE'
&m        % Index of membership. Stack: 'NWSE', 2
j         % Take second input, say '/'. Stack: 'NWSE', 2, '/'
y         % Duplicate from below. Stack: 'NWSE', 2, '/', 2
+         % Add (char '/' is converted to code point). Stack: 'NWSE', 2, 49 
Eq        % Multiply by 2, subtract 1. Stack: 'NWSE', 2, 97
-         % Subtract. Stack: 'NWSE', -95
)         % Apply -95 as (modular, 1-based) index into 'NWSE'. Stack: 'N'
          % Implicitly display
\$\endgroup\$
6
\$\begingroup\$

Pyth, 17 16 15 bytes

Thanks to @Jakube and @Maltysen for -1 byte each

@J"NWES"xxJQh>E

A program that takes input of two newline-separated quoted strings, first the direction and then the mirror, and prints the result.

This is a port of @Lynn's Python answer.

Try it online

How it works

@J"NWES"xxJQh>E  Program. Inputs: Q, E
 J"NWES"         J="NWES". Yield J
         xJQ     J.index(Q)
             >E  E>Q, lexographically (implicit input fill)
            h    +1
        x        Bitwise XOR of the above two
@                Index into J with the above
                 Implicitly print
\$\endgroup\$
  • \$\begingroup\$ you can save another byte by replacing <QE with >E. \$\endgroup\$ – Maltysen Sep 2 '16 at 14:52
4
\$\begingroup\$

05AB1E, 14 bytes

‘€Ã‘DIkI'/kÌ^è

‘€Ã‘             # from string "NEWS"
             è   # get element at index
    DIk          # index of 1st input in string "NEWS"
            ^    # XOR
       I'/k      # index of 2nd input in string "/"
           Ì     # +2               

Try it online!

\$\endgroup\$
4
\$\begingroup\$

Jelly, 14 13 12 bytes

(a port of my Python answer)
-1 byte thanks to @MartinEnder (add a space to end of the string and remove need for modulo 8)
-1 byte thanks to @LuisMendo (take a single string argument rather than two)

OSị“NESSWNW 

How?

OSị“NESSWNW  - takes a single argument "dm" (direction and mirror), in either order.
                   strings and lists are equivalent in Jelly
 O            - ordinal: [ord(d),ord(m)]
  S           - sum: ord(d)+ord(m)
    “NESSWNW  - string: "NESSWNW "
   ị          - fetch modulo index (the string is 8 long and 1-based)

Test it on TryItOnline

\$\endgroup\$
4
\$\begingroup\$

Java 7, 71 70 68 bytes

char c(int d,int m){return"NEWS".charAt("NEWS".indexOf(d)^-~(m%2));}

Too bad the charAt and indexOf takes up so much bytes..

Ungolfed & all test cases:

Try it here.

class M{
  static char c(int d, int m) {
    return "NEWS".charAt("NEWS".indexOf(d) ^ -~(m%2));
  }

  public static void main(String[] a){
    System.out.print(c('N', '/') + " ");
    System.out.print(c('N', '\\') + " ");
    System.out.print(c('E', '/') + " ");
    System.out.print(c('E', '\\') + " ");
    System.out.print(c('S', '/') + " ");
    System.out.print(c('S', '\\') + " ");
    System.out.print(c('W', '/') + " ");
    System.out.print(c('W', '\\') + " ");
  }
}

Output:

W E S N E W N S
\$\endgroup\$
3
\$\begingroup\$

Python, 63 61 59 bytes

lambda d,m,x='NESW'*2:x[x.find(d)+2*(m=='/\\'[d in'NS'])-1]

Pretty simple. Can definitely be golfed more. Decides whether to add 1 or -1 to the input's index in 'NESW'.

This is a lambda expression; to use it, prefix it with f=.

Ideone it!

\$\endgroup\$
3
\$\begingroup\$

Java 8, 62 58 56 bytes

(d,m)->"SEWN".charAt("NWES".indexOf(d)^m.indexOf(47)+2);

Ungolfed test program

import java.util.function.BiFunction;

public class Mirror {

public static void main(String[] args) {
    BiFunction<String, String, Character> function = (d,m)->"SEWN".charAt("NWES".indexOf(d)^m.indexOf(47)+2);

    System.out.println(function.apply("N", "/")); //W
    System.out.println(function.apply("N", "\\")); //E
    System.out.println(function.apply("W", "/")); //N
    System.out.println(function.apply("W", "\\")); //S
    System.out.println(function.apply("E", "/")); //S
    System.out.println(function.apply("E", "\\")); //N
    System.out.println(function.apply("S", "/")); //E
    System.out.println(function.apply("S", "\\")); //W
}

}
\$\endgroup\$
3
\$\begingroup\$

PowerShell v2+, 34 bytes

param($a,$b)"xNESSWNW"[(+$a+$b)%8]

Takes input as two explicit chars, outputs a char.

This works as follows: If we sort the output, we want S / to somehow equal the same as N \, W / to equal E \, etc. Or, at least, produce numbers that are "close enough" yet still distinct. If we look at the ASCII values, we get a table like the below:

In1   In2       Res.    Sum
S 83  / 47  --> E 69 -> 130
N 78  \ 92  --> E 69 -> 170
W 87  / 47  --> N 78 -> 134
E 69  \ 92  --> N 78 -> 161
W 87  \ 92  --> S 83 -> 179
E 69  / 47  --> S 83 -> 116
N 78  / 47  --> W 87 -> 125
S 83  \ 92  --> W 87 -> 175

Running a quick brute-forcer on the summations column (derived from summing the ASCII code points of the inputs) shows that if we take the sums modulo 8, we get the following 2 2 | 6 1 | 3 4 | 5 7. That's evidenced in the string "xNESSWNW", as E is at index 2, N is at 6 and 1, and so on.

So, we just need to sum the inputs (implicitly casting from char to int32 along the way), take that %8, and use that to index into our string.

Test Cases

PS C:\Tools\Scripts\golfing> ('N','/'),('N','\'),('E','/'),('E','\'),('S','/'),('S','\'),('W','/'),('W','\')|%{"$($_[0]) $($_[1]) --> "+(.\mirror-mirror-in-the-code.ps1 ([char]$_[0]) ([char]$_[1]))}
N / --> W
N \ --> E
E / --> S
E \ --> N
S / --> E
S \ --> W
W / --> N
W \ --> S
\$\endgroup\$
2
\$\begingroup\$

Batch, 111 bytes

:goto %1
:W/
:E\
@echo N
@exit/b
:S/
:N\
@echo E
@exit/b
:E/
:W\
@echo S
@exit/b
:N/
:S\
@echo W

Accepts e.g. W/ as a two-character string command line parameter. The \ and / make looping awkward; it would have taken 124 bytes.

\$\endgroup\$
  • \$\begingroup\$ Idk, I count 96 bytes. Did you strip \r from it? \$\endgroup\$ – Conor O'Brien Sep 2 '16 at 22:17
  • \$\begingroup\$ @ConorO'Brien I write my Batch files using Notepad, so, no. \$\endgroup\$ – Neil Sep 2 '16 at 22:33
2
\$\begingroup\$

Octave, 30 bytes

Used the same order of arguments as Jonathan Allan.

Takes the input as two-character string 'W\'.

@(x)['NESSWNW'](mod(sum(x),8))

Try it online.

\$\endgroup\$
  • \$\begingroup\$ Nice! You may want to port to MATL: 'NESSWNW 'is) (see all test cases). i is input, s is sum, and ) is indexing, which is modular. I added a space in the string so that the modulo is 8 \$\endgroup\$ – Luis Mendo Sep 2 '16 at 18:59
  • \$\begingroup\$ Thanks :) I feel it's cheating if I add that as a separate answer, since I haven't written it myself. I can add it to this answer though if you don't want to answer it yourself :) \$\endgroup\$ – Stewie Griffin Sep 2 '16 at 19:03
  • \$\begingroup\$ I understand, I would probably do the same :-) I don't want to modify my answer, as it's a totally different approach I didn't come up with. Not sure it adding it to your answer makes sense, though, as it would be two different languages in the answer \$\endgroup\$ – Luis Mendo Sep 2 '16 at 19:05
  • \$\begingroup\$ It would be my first MATL answer though :P I see it's longer than your MATL answer, so I don't think I'll add it... \$\endgroup\$ – Stewie Griffin Sep 2 '16 at 19:08
2
\$\begingroup\$

C, 44, 35, 34 bytes

f(a,b){return"NWES"[a&a/2&3^b&3];}

It requires two characters as two variables. It takes both lower and upper case. It uses a lot of bit manipulation. The fragment a&a/2 results in a value that has unique values for the lower two bits, &3 cuts off all higher bits. This used as an index into the string "NWES" for the \ mirror. Luckily, the lower two bits of the ASCII characters \ and / are 00 and 11 respectively, which is perfect to XOR with the aforementioned index to get the correct direction for the / mirror.

\$\endgroup\$
  • 2
    \$\begingroup\$ Nice! You missed an obvious -1 byte, though: return"NWES"[...] (omit the space). \$\endgroup\$ – Tim Čas Sep 4 '16 at 20:48
  • \$\begingroup\$ Thanks Tim, it hadn't occured to me that that would be valid C :) \$\endgroup\$ – G. Sliepen Sep 5 '16 at 6:48
1
\$\begingroup\$

CJam, 17 bytes

r"SWEN"_e!r'/#=er

Input is space-separated.

Try it online! (As a linefeed-separated test suite.)

This is the solution I found before posting the challenge. Not as short as Jonathan's cyclic indexing, but I thought this approach is quite interesting (and novel).

Explanation

The goal is use transliteration (i.e. using a character-to-character mapping) to replace the input character with the output character. To do this, we need to select the correct map based on whether the mirror is / or \. We'll map from the SWEN list to another one which we'll select conditionally. If the input list is SWEN, the two output maps need to be the following:

in  SWEN
/   ENSW
\   WSNE

Note that these are in sorted and reverse-sorted order (which is why we chose the seemingly random SWEN order as the input set). We could generate these by sorting the input list and the reversing the result if the input has \, but there's a better way:

r       e# Read incoming direction.
"SWEN"  e# Push input list for transliteration.
_e!     e# Duplicate and get all permutations. The way, `e!` is implemented, it
        e# always gives the permutations in sort order, regardless of the order
        e# of the input set. Specifically that means that "ENSW" will be first
        e# and "WSNE" will be last in this list.
r       e# Read the mirror.
'/#     e# Find the index of / in this string. If the mirror is '/', then this
        e# gives 0. Otherwise, this gives -1, indicating that '/' was not found.
=       e# Select the corresponding permutation. Indexing is zero-based and
        e# cyclic so that 0 (input '/') gives the first permutation "ENSW" and
        e# -1 (input '\') gives the last permutation "WSNE".
er      e# Perform the transliteration on the incoming direction.
        e# Printing is implicit.
\$\endgroup\$
1
\$\begingroup\$

SED 48 (42 + 1 for -r) 43

Saved 5 thanks to Martin Ender♦

s,N/|S\\,W,;s,E/|W\\,S,;s,N.|S/,E,;s,..,N,

Takes input as a two character string.

\$\endgroup\$
0
\$\begingroup\$

Mathematica, 98 bytes

If[#2=="/",{"S",,,,,,,,,"W",,,,,"E",,,,"N"},{"N",,,,,,,,,"E",,,,,"W",,,,"S"}][[LetterNumber@#-4]]&

Anonymous function. Takes two strings as input and returns a string as output.

\$\endgroup\$
0
\$\begingroup\$

C, 81 bytes

f(char*a){return a!="N/"&a!="S\\"?a!="N\\"&a!="S/"?a!="W\\"&a!="E/"?78:83:69:87;}

Usage

main()
{
    printf("N/ \t %c\n",f("N/"));
    printf("N\\\t %c\n",f("N\\"));
    printf("E/ \t %c\n",f("E/"));
    printf("E\\\t %c\n",f("E\\"));
    printf("S/ \t %c\n",f("S/"));
    printf("S\\\t %c\n",f("S\\"));
    printf("W/ \t %c\n",f("W/"));
    printf("W\\\t %c\n",f("W\\"));
}

Output:

N/      : W  
N\      : E  
E/      : S  
E\      : N  
S/      : E  
S\      : W  
W/      : N  
W\      : S  
\$\endgroup\$
  • \$\begingroup\$ Works only on hardcoded values since uses pointer comparisons. \$\endgroup\$ – Sami Kuhmonen Sep 4 '16 at 19:33
0
\$\begingroup\$

Pyth, 13 bytes

@."EW¹0`Y"sCM    

Test suite

Sum the code points, modular index, compressed string.

\$\endgroup\$
0
\$\begingroup\$

TI-Basic, 40 bytes

Hardcodes the inputs. Boring, but the shortest way.

sub("NEWS",1+int(inString("E/W\N\S/N/S\E\W/",Ans)/4),1
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.