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 code-golf, 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
21 Answers 21
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
-
\$\begingroup\$ Dangit, I thought I was being super clever taking the ASCII values, summing them,
%8them, and doing an index. Then I see you posted the same solution over an hour ago. Hah. Have a +1. \$\endgroup\$AdmBorkBork– AdmBorkBork2016年09月02日 13:31:17 +00:00Commented Sep 2, 2016 at 13:31
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.
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
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
-
\$\begingroup\$ Clever use of ASCII comparisons to get your condition at the end playing your way... \$\endgroup\$Eliseo D'Annunzio– Eliseo D'Annunzio2019年09月11日 01:17:03 +00:00Commented Sep 11, 2019 at 1:17
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
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.
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
-
\$\begingroup\$ you can save another byte by replacing
<QEwith>E. \$\endgroup\$Maltysen– Maltysen2016年09月02日 14:52:01 +00:00Commented Sep 2, 2016 at 14:52
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
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:
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
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=.
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
}
}
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
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.
-
\$\begingroup\$ Idk, I count 96 bytes. Did you strip
\rfrom it? \$\endgroup\$Conor O'Brien– Conor O'Brien2016年09月02日 22:17:55 +00:00Commented Sep 2, 2016 at 22:17 -
\$\begingroup\$ @ConorO'Brien I write my Batch files using Notepad, so, no. \$\endgroup\$Neil– Neil2016年09月02日 22:33:11 +00:00Commented Sep 2, 2016 at 22:33
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.
-
\$\begingroup\$ Nice! You may want to port to MATL:
'NESSWNW 'is)(see all test cases).iisinput,sissum, and)is indexing, which is modular. I added a space in the string so that the modulo is 8 \$\endgroup\$Luis Mendo– Luis Mendo2016年09月02日 18:59:22 +00:00Commented 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\$Stewie Griffin– Stewie Griffin2016年09月02日 19:03:27 +00:00Commented 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\$Luis Mendo– Luis Mendo2016年09月02日 19:05:36 +00:00Commented 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\$Stewie Griffin– Stewie Griffin2016年09月02日 19:08:43 +00:00Commented Sep 2, 2016 at 19:08
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.
-
2\$\begingroup\$ Nice! You missed an obvious -1 byte, though:
return"NWES"[...](omit the space). \$\endgroup\$Tim Čas– Tim Čas2016年09月04日 20:48:49 +00:00Commented Sep 4, 2016 at 20:48 -
\$\begingroup\$ Thanks Tim, it hadn't occured to me that that would be valid C :) \$\endgroup\$G. Sliepen– G. Sliepen2016年09月05日 06:48:31 +00:00Commented Sep 5, 2016 at 6:48
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.
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.
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.
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
-
\$\begingroup\$ Works only on hardcoded values since uses pointer comparisons. \$\endgroup\$Sami Kuhmonen– Sami Kuhmonen2016年09月04日 19:33:45 +00:00Commented Sep 4, 2016 at 19:33
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
\. 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\$readline()can handle it. \$\endgroup\$