Relative vs Absolute
CJam, 57 53 49
{"NESW""FRBL"_3$&!!:Q$:R^^f#0\{{+0\}Q*_@-R=\}%);}
Previous version
{"NESW""FRBL"_3$0=#W>:Q{\}*:R;f#0\{{+0\}Q*_@-R=\}%);}
Example:
{"NESW""FRBL"_3$0=#W>:Q{\}*:R;f#0\{{+0\}Q*_@-R=\}%);}:T;
"NNWEESEE"T
N
"FFLBFRLF"T
Output:
FFLBFRLF
NNWEESEE
How it works
{
"NESW""FRBL" " Push the two strings. ";
_3$0=#W> " Check if the first character is in FRBL. ";
:Q " Assign the result to Q. ";
{\}* " Swap the two strings if true. ";
:R; " Assign the top string to R and discard it. ";
f# " Find each character of the input in the string. ";
0\ " Push a 0 under the top of the stack. ";
{ " For each item (index of character): ";
{ " If Q: ";
+0\ " A B -> 0 (A+B) ";
}Q*
_@- " C D -> D (D-C) ";
R= " E -> E-th character in R ";
\ " Swap the top two items. ";
}%
); " Discard the last item in the list. ";
}
JavaScript (E6) 84 86 88 92 104
Edit: using & instead of %, different operator precedence (less brackets) and works better with negative numbers
Edit2: | instead of +, op precedence again, -2. Thanks DocMax
Edit3: array comprehension is 2 chars shorter than map(), for strings
F=p=>[o+=c[d=n,n=c.search(i),n<4?4|n-d&3:n=n+d&3]for(i of n=o='',c='NESWFRBL',p)]&&o
Test In FireFox/FireBug console
console.log(F('NNWEESEE'),F('FFLBFRLF'))
Output
FFLBFRLF NNWEESEE
C++, 99 97 94 bytes
−3 bytes thans to ceilingcat
The following is formatted as a lambda expression. It takes one char*
argument and overwrites it.
[](char*s){for(int d=0,n=0,c=*s*9%37&4;*s;*s++="NESWFRBL"[c|n&3])d+=n=c?*s%11/3-d:n+*s%73%10;}
For those who are not familiar with this feature (like myself 1 hour ago), use it as follows:
#include <iostream>
int main()
{
char s[] = "NNWEESEE";
auto x = [](char*s){for(int d=0,n=0,c=*s*9%37&4;*s;d+=n)c?n=*s%11/3-d:n+=*s%73%10,*s++="NESWFRBL"[c|n&3];};
x(s); // transform from absolute to relative
std::cout << s << '\n';
x(s); // transform from relative to absolute
std::cout << s << '\n';
}
Some explanations:
- When using code like
flag ? (x = y) : (x += z)
, the second pair of parentheses is required in C. So I used C++ instead! - C++ requires specifying a return type for a function. Unless I use a lambda expression, that is! An added bonus is I don't need to waste 1 character on the name of the function.
- The code
*s*9%37&4
tests the first byte; the result is 4 if it's one ofNESW
; 0 otherwise - The code
*s%11/3
converts the bytesNESW
to 0, 1, 2, 3 - The code
*s%73%10
converts the bytesFRBL
to 0, 9, 6, 3 (which is 0, 1, 2, 3 modulo 4) - When converting relative directions to absolute, I don't need the
d
variable. I tried rearranging code to eliminate it completely, but it seems impossible...