# Klein Topololyglots

Klein is a 2D language I have designed that can be embedded on 12 different topological surfaces. A Klein program can be run on different surfaces by changing the command line arguments.

The topology determines where the instruction pointer goes when it goes off the edge of the program. When moving off of the edge the ip will jump to an edge with the matching color, and will maintain its position relative to the arrow, i.e. the pointer will conserve its distance from the arrow head.

For example topology 000, the topology used by most 2D languages, causes the instruction pointer to wrap around to the other side when if moves off an edge.

The task is pretty simple, write a Klein program that when run will output the topology it is run in. The individual numbers may be separated by spaces. (e.g. 000 and 0 0 0 are both permissible output). You may choose to either use or ignore the -A command line flag it will not cost you bytes if you use it.

This is so the shortest answer will be the winner.

Here is a online test driver that can be used to test all of the topologies at once. To run in integer mode remove the -A.

• +1 for a great example of a good language-specific challenge. :) May 24, 2017 at 20:26
• @StephenS No. I'll give it to you for free :) May 25, 2017 at 0:39
• The IP movements are hurting my head May 25, 2017 at 1:18
• Please fix the image ... May 29, 2018 at 10:05
• @JoKing I've known for a while, and have been meaning to fix it. I removed the image for now and hopefully I'll take the time to make a new one eventually. Thanks. Aug 29, 2018 at 5:58

# 52 48 bytes

./@$0<$
21\./01
..>..!\
@
.<..<\
20//\11
@01$00@  Try it online! Test Driver ## Explanation In Klein the IP starts in the top left corner going right. The first step I wanted my program to do was to send the IP off the top of the program to determine the first and third bit. The IP would reenter the program as follows depending on the topology:  ^ I|P ./..... 201, 211 -->.......<-- 100, 110 ....... ....... ....... 200, 210 -->.......<-- 101, 111 ....... ^ ^ | | 000 001 010 011  I decided that the my program would record the third bit of the topology before the second bit but swap them (using $) before the end. To that end I added code to push the first and third bits of each topology at the IP's points of entry described above.

./.....
21...01
.......
.......
.......
20...11
.0...0.


Next I focused on the topologies with 1 or 2 as their first bit. I decided to recombine them and send them off on the side not connected to the north side so I could determine their second bit.

                      ./.....
21\./01
..>....--> 200, 201, 210, 211
.......
100, 101, 110, 111 <--....<..
20/.\11
.0...0.
^ ^
| |
/ \
110 100
111 101
210 200
211 201


Conveniently this regrouped the topologies by their second bit so I could push that to the stack.

./.....
21\./01
..>....
.......
....<..
20/.\11
.01.00.


After that I just needed to swap the second and third bit and have the program terminate.

./.$... 21\./01 ..>.... @...... ....<.. 20//\11 .01$00.


Now that the topologies with 1 or 2 as their first bit worked, I could focus on making the topologies with 0 give the correct output. The first step was recombining them so that they could be separated into two groups based on their second bit.

                      ./.$... 21\./01 ..>....<-- 010, 011 @...... 000, 001, 010, 011 <--.<..<<.<-- 000, 001 20//\11 .01$00.


I first focused on those topologies with 1 as their second bit. These presented a challenge because for them the IP was on a line already used by the topologies with 2 as their first bit. Since it would be tricky to fit more than one instruction on that line (a single instruction can be jumped using the ! instruction) and I was running low on space as a whole, I decided to redirect the IP off that line and reuse an existing 1 instruction to push the second bit.

./.$... 21\./01 ..>..!\ @...... .<..<<. 20//\11 .01$00.


Now all that was left to do for the topologies with 1 as their second bit was to fix the order of the second and third bit and terminate.

       ^
|
./.$..$
21\./01
..>..!\
@......
.<..<<.
20//\11
@01$00@ ^ ^ | | 011 010  Lastly remained the topologies with 0 as their second bit. There was not much space left in the program with the largest unused space being on the top line so it was there that I redirected the IP for the topologies with 0 as their second bit. ./.$.<$21\./01 ..>..!\ @...... .<..<\. 20//\11 @01$00@


I still needed to push 0 for the second bit and fix the order of the second and third bit as well as terminate the program. Fortunately, I was able to reuse an existing $ instruction so the 0 and @ instructions could fit in the remaining spaces. ./@$0<$21\./01 ..>..!\ @...... .<..<\. 20//\11 @01$00@


Finally the nops can be stripped from the ends of lines to get the final program.

# 11688867769616059585453 50 bytes

\2..@2
/1\<$00 />!..>! 0// @0$10@1
011\.<0
\.<@>1@


Try it online!

• @WheatWizard how did you make it then 0.o and maybe you should think about creating a visual kind of like ETH made for Cubix May 25, 2017 at 1:34
• @StephenS If you run Klein with the -d flag it will do exactly that. Unfortunately it doesn't work in TIO. May 25, 2017 at 6:02

# 44 41 40 38 37 bytes

\\1.>2
/0./
@./$(\$>0!>
11$/10$.@.1


Try it online!

Test driver.

Uses a 6 by 6 square. The shortest I could get with an 8 by 8 square is 38 bytes if anyone wants to try improving it.

### Explanation:

One the first pass-through the code encodes the first two numbers for the prefixes 0 and 1. For 2, it encodes the third number then the first.

     201  200
211  210
|  |
v  v
-> \\1.>2
IP<- /../..  <- 000, 001
...$.. .>0... .1..10 <- 010, 011 ....1. ^ ^ | | 100 110 101 111  Then we pass the IPs through the third edge to decide the final number. We combine the IPs with the same prefix.  201 200 211 210 | | v v -> \\1.>2 -> 0,2 or 1,2 IP<- /../.. <- 000, 001 ...$..
.>0!>.  -> 1
.1./10  <- 010, 011
....1.
^ |^
| v|
| 0|
100  110
101  111


For the 0 and 1 prefixes, they both come out the top edge to decide the third number.

     201  200
211  210
|  |
|10|
vvvv
-> \\1.>2  -> 2
IP<- /0./..  <- 000, 001
@./$.. .>0!>. -> 1 .1./10 <- 010, 011 ....1. ^ |^ | v| | 0| 100 110 101 111  For the 2 prefix, the IPs come out the corners from the bottom edge.  201 200 211 210 | | |10| vvvv -> \\1.>2 -> 2 IP<- /0./.. <- 000, 001 @./$(\
$>0!>. -> 1 11$/10  <- 010, 011
\$.@.1.
^^ |^^
|| v||
1| 0|0
100  110
101  111


Both edges swap the first and third number, push the second number and swaps it with the third to get the correct order.