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
asked Sep 2, 2016 at 10:10
\$\endgroup\$
4
  • 1
    \$\begingroup\$ In languages where backslashes must be escaped on input, are we allowed to assume the input will be "\\" where appropriate? \$\endgroup\$ Commented Sep 2, 2016 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\$ Commented Sep 2, 2016 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\$ Commented Sep 2, 2016 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\$ Commented Sep 2, 2016 at 11:46

21 Answers 21

23
\$\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

answered Sep 2, 2016 at 12:14
\$\endgroup\$
1
  • \$\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\$ Commented Sep 2, 2016 at 13:31
20
\$\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.

answered Sep 2, 2016 at 10:41
\$\endgroup\$
0
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

answered Sep 2, 2016 at 12:44
\$\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

answered Sep 2, 2016 at 10:33
\$\endgroup\$
1
  • \$\begingroup\$ Clever use of ASCII comparisons to get your condition at the end playing your way... \$\endgroup\$ Commented Sep 11, 2019 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
answered Sep 2, 2016 at 10:44
\$\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
answered Sep 2, 2016 at 12:05
\$\endgroup\$
1
  • \$\begingroup\$ you can save another byte by replacing <QE with >E. \$\endgroup\$ Commented Sep 2, 2016 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!

answered Sep 2, 2016 at 13:12
\$\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

answered Sep 2, 2016 at 13:00
\$\endgroup\$
0
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
answered Sep 2, 2016 at 11:40
\$\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!

answered Sep 2, 2016 at 10:28
\$\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
}
}
answered Sep 2, 2016 at 11:40
\$\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
answered Sep 2, 2016 at 13:23
\$\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.

answered Sep 2, 2016 at 13:12
\$\endgroup\$
2
  • \$\begingroup\$ Idk, I count 96 bytes. Did you strip \r from it? \$\endgroup\$ Commented Sep 2, 2016 at 22:17
  • \$\begingroup\$ @ConorO'Brien I write my Batch files using Notepad, so, no. \$\endgroup\$ Commented Sep 2, 2016 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.

answered Sep 2, 2016 at 14:21
\$\endgroup\$
4
  • \$\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\$ Commented Sep 2, 2016 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\$ Commented Sep 2, 2016 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\$ Commented Sep 2, 2016 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\$ Commented Sep 2, 2016 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.

answered Sep 4, 2016 at 20:28
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Nice! You missed an obvious -1 byte, though: return"NWES"[...] (omit the space). \$\endgroup\$ Commented Sep 4, 2016 at 20:48
  • \$\begingroup\$ Thanks Tim, it hadn't occured to me that that would be valid C :) \$\endgroup\$ Commented Sep 5, 2016 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.
answered Sep 2, 2016 at 13:41
\$\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.

Martin Ender
198k67 gold badges455 silver badges998 bronze badges
answered Sep 2, 2016 at 14:27
\$\endgroup\$
0
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.

answered Sep 2, 2016 at 11:06
\$\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 
answered Sep 2, 2016 at 15:14
\$\endgroup\$
1
  • \$\begingroup\$ Works only on hardcoded values since uses pointer comparisons. \$\endgroup\$ Commented Sep 4, 2016 at 19:33
0
\$\begingroup\$

Pyth, 13 bytes

@."EW10`Y"sCM 

Test suite

Sum the code points, modular index, compressed string.

answered Sep 3, 2016 at 20:57
\$\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
answered Sep 4, 2016 at 21:17
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.