~,v>v
~f<^ s
>,^ >-:9w>'0+
^+W' ]^
This takes input in lowercase, outputs the answer in lowercase, then enters an infinite loop.
Try it online!
40 byte version that terminates
Explanation
~,v
This gets the first character of the input (which is always #
), outputs it unchanged, and enters the loop.
~f< s
At the start of the loop, f
pushes 15
onto the stack, ~
gets the next character of the input, and s
puts that character one space to its left in the source code (without executing it).
>v
^I
(I'm using I
to represent the character from the input that is now in the source code.) This section loops back around to execute that character. Every character in the range 0-9
or a-f
pushes the corresponding hex value on the stack.
>-:9w
The hex value is subtracted from 15
(the previous top of the stack) to get its complement. :9w
creates a copy of the complement, and compares the copy with 9
, with the IP going down, up or right depending on whether it is greater, less than, or equal.
>
]^
If the complement is greater than 9, the IP goes down and hits the ]
("turn right") from above, turning to move left. If the copy was less than 9, the IP goes up and hits the ]
from below, turning to move right. In that case, it gets redirected back to the third line. If the copy was exactly 9, the IP goes right and hits the >
immediately.
'0+
If the complement is less than or equal to 9 (i.e. a digit), it is added to ASCII 48 (0
) to produce the correct digit.
^+W'
If the complement is greater than 9, it is added to ASCII 87 (W
) to produce the correct character (in the range a-f
).
<
>,^
In all cases, the character corresponding to the complement is printed and the IP moves back to the start of the loop.
The loop repeats, outputting the complement of every hex digit in the input.
After we print the answer, the input has been completely used up. Once EOF is reached, ~
reflects the IP. This means that ~f<
is now an infinite loop that pushes 15
on the stack forever. This doesn't produce any effects (except for possibly crashing), so we don't care about it.