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.
18+1 for a great example of a good language-specific challenge. :) – Martin Ender – 2017-05-24T20:26:02.010
Would the
-A
flag cost bytes? I'm assuming so. – Stephen – 2017-05-25T00:28:42.5831@StephenS No. I'll give it to you for free :) – Post Rock Garf Hunter – 2017-05-25T00:39:42.463
1The IP movements are hurting my head – MickyT – 2017-05-25T01:18:06.040
2Please fix the image ... – user202729 – 2018-05-29T10:05:55.090
1@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. – Post Rock Garf Hunter – 2018-08-29T05:58:59.367