Mathgeek mathematics geometry path-finding

This is a fairly simple question in concept. Shouldn't be too hard to make a simple program for - the tricky part is finding how to shave off those extra characters. Good luck!
## Task
Input is a string of indeterminate length, composed of any number of eight characters; [ ⭢⭠⭡⭣⭧⭨⭦⭩ ]
For a pointer starting at (0,0) on a Cartesian plane, of the form (X, Y), below is the list of what each of the arrows will do to the pointer.
|Input | Hex Value | Action | Cartesian|
|:-:|:-:| :-- |:-:|
|⭠|0x2b60| X decreases by 1.|(-1,0)
|⭡|0x2b61| Y increases by 1.|(0,+1)|
|⭢|0x2b62| X increases by 1.|(+1,0)|
|⭣|0x2b63| Y decreases by 1.|(0,-1)|
|⭦|0x2b66| Perform ⭡ and ⭠.|(-1,+1)|
|⭧|0x2b67| Perform ⭡ and ⭢.|(+1,+1)|
|⭨|0x2b68| Perform ⭣ and ⭢.|(+1,-1)|
|⭩|0x2b69| Perform ⭣ and ⭠.|(-1,-1)|
The output should print where this pointer ends up.
## Sample Test Cases
| Input | Output|
| :-: | :-: |
|⭠⭠⭣⭧⭨⭢⭢⭩⭡ | (1,-1)|
|⭡⭣⭨⭨⭦⭩⭦⭩⭩⭠⭡⭡ | (-4,-1)|
|⭡⭡⭡ | (0,3)|
| [blank string] | (0,0) |

Top Answer

Bubbler # [APL (Dyalog Unicode)], 28 bytes ([SBCS])
[SBCS]:https://github.com/abrudz/SBCS
+/∘×9 11∘.○0j¯1*.5⊥7 10⊤⎕UCS
[Try it online!][TIO-k69z6lrw]
[APL (Dyalog Unicode)]: https://www.dyalog.com/
[TIO-k69z6lrw]: https://tio.run/##SyzI0U2pTMzJT///X1v/UceMw9MtFQwNgQy9R9O7DbIOrTfU0jN91LXUXMHQ4FHXkkd9U0Odg/@nPWqb8Ki3D8jz9H/U1XxovfGjtolAXnCQM5AM8fAEKlFQf7R2waO1Cx@tXfRo7eJHa5c9Wrv80doVj9auVOeCSS4Ay0CEF4HRSqAOdQWFR71zFQwVgLZDlC4Eq1sBRsvAiiDkSpgVMD2H1pug6EKSMlAwBgnDeQYA "APL (Dyalog Unicode) – Try It Online"
### How it works
First, observe that the decimal values have a pattern:
| Input | Hex value | Decimal value | `a=(n/10)%7` | `b=n%10` | `c=a/2+b` | `(-i)**c` |
| :-: | :-: | :-: | :-: | :-: | :-: | :-: |
| ⭠ | 0x2b60 | 11104 | 4 | 4 | 6 | $-1$ |
| ⭡ | 0x2b61 | 11105 | 4 | 5 | 7 | $i$ |
| ⭢ | 0x2b62 | 11106 | 4 | 6 | 8 | $1$ |
| ⭣ | 0x2b63 | 11107 | 4 | 7 | 9 | $-i$ |
| ⭦ | 0x2b66 | 11110 | 5 | 0 | 2.5 | $(-1+i)/\sqrt2$ |
| ⭧ | 0x2b67 | 11111 | 5 | 1 | 3.5 | $(1+i)/\sqrt2$ |
| ⭨ | 0x2b68 | 11112 | 5 | 2 | 4.5 | $(1-i)/\sqrt2$ |
| ⭩ | 0x2b69 | 11113 | 5 | 3 | 5.5 | $(-1-i)/\sqrt2$ |
If we represent the movements with a complex number, we can see that clockwise rotation (power of `-i`) on ⭠ and ⭦ gives the other arrows in the respective group. And ⭦ can also be derived from ⭠ by 45° rotation followed by scaling.
+/∘×9 11∘.○0j¯1*.5⊥7 10⊤⎕UCS
⎕UCS ⍝ Convert to Unicode codepoints
7 10⊤ ⍝ a=(n/10)%7 and b=n%10 for each n
.5⊥ ⍝ .5×a+b for each n
0j¯1* ⍝ Power of -i
9 11∘.○ ⍝ Extract real and imaginary parts
× ⍝ Signum of each number; effectively scale 45deg-rotations
+/∘ ⍝ Sum of real and imaginary part respectively

Answer #2

Mathgeek # [Golfscript](https://http://www.golfscript.com/), ~~71 bytes~~ 58 bytes
Line breaks are stylistic and for readability, they do not contribute to character count.
~~This is not a particularly elegant solution, but it works and is likely very shrinkable.~~
Shrunk by 13 characters using a rotating array.
My guess is a nested block loop that can somehow generate these particular arrays without needing to spell them out.
~~In a perfect world, you wouldn't need to duplicate the original array, meaning we could cut out the whole third line and another few characters.~~
Kinda half-done. Still wanna get rid of the loop, I think this can be brought down to 40 characters.
Will continue optimizing - just wanted to get a concrete solution out.
~~One character can be shaved by swapping the order of the arrays, but it's less clear, and I'd like it to be clear until I've golfed it much lower.~~
This is no longer true.
```
2\+.[-1 1 1 -1 -1 0 1 0]:a;
{10%a\=+}*\
{10%a(+\=+}*
{50-\}2*
```
Explanation;
```
2\+. # Put an ASCII 50 at the start of the given array.
[-1 1 1 -1 -1 0 1 0]:a;
# Remember this encoding of directionality for later.
{ # Open a block (X encoding)
10% # Mod the arrows by 10
a\= # Check that number against a, as the index
+ # Add it to our running tally at the front (to the 50)
}* # Do this to every element in the array, iterating,
# and pumping out a value. This is a bit tricky to
# explain, but in essence, this is a weird workaround
# the usual loop command, since that loop outputs
# a bunch of non-arrayed elements, which we can't
# handle effectively. This lets us output one number
# (The sum of them all), but skips the first element.
# This is why we added 2 at the beginning, since it's
# read as ASCII 50. We subtract that later.
\ # Take our duplicated string
{10%a(+\=+}*
# Repeat the previous process with the Y array.
{50-\}2*
# Take away that pesky 50 from the sum of both indices
```
Then our stack is X, Y, which gets automatically outputted.
This is more elegant that my previous solution, but the array itself takes a lot of space, and I'd like to shorten it.

Answer #3

Skillmon # LuaTeX, ~~191~~ 190 bytes
This is just a simple switch cases answer. The string should be delimited by `~` on the left and `⭤` (U+2b64) on the right end.
Function definition:
```tex
\def~#1{\catcode`#1"D}~:~;~.~,~|\let|\def\let:\newcount:.:,|:{\advance.}|;{\advance,}|~#1{\ifcase\numexpr`#1-`⭠:-1|;1|:1|;-1|\2||:-1;1|:1;1|:1;-1|:-1;-1\fi~}|\2#1~{ \fi\the. \the,}\let|\or
```
Complete script:
```tex
\def~#1{\catcode`#1"D}~:~;~.~,~|\let|\def\let:\newcount:.:,|:{\advance.}|;{\advance,}|~#1{\ifcase\numexpr`#1-`⭠:-1|;1|:1|;-1|\2||:-1;1|:1;1|:1;-1|:-1;-1\fi~}|\2#1~{ \fi\the. \the,}\let|\or
~⭠⭠⭣⭧⭨⭢⭢⭩⭡⭤
.0,0%reset counters
~⭡⭣⭨⭨⭦⭩⭦⭩⭩⭠⭡⭡⭤
.0,0%reset counters
~⭡⭡⭡⭤
.0,0%reset counters
~⭤
\bye
```
Output (as PDF):
![cg_directions2.png](/image?hash=69177df5a63fe41f9d5f2290d1806e7478e6397231dace9aed1045af934e5219)