Surjection from one string to two strings This is the inverse of negative seven's question.

Write a program or function which, given any single, possibly-empty string of printable ASCII (codes \$[32,126]\$) outputs or returns two strings of printable ASCII.

For any two ordered, possibly empty strings \$s_1\$ and \$s_2\$, there must be third string \$s_0\$, which input to your program, outputs \$s_1\$ and \$s_2\$.



In other words, if \$\mathbb S\$ is the set of all ASCII strings (including the empty string):

\$f\$ is well-defined on \$\mathbb S\$: \$(\forall s\in\mathbb S)(f(s)\in\mathbb S\times\mathbb S)\$

\$f\$ is a surjection to \$\mathbb S\times\mathbb S\$: \$(\forall s_1,s_2\in\mathbb S)(\exists s_0\in\mathbb S)(f(s_0)=(s_1,s_2))\$

Test cases:

For each of these strings (surrounding «quotes» excluded), your output should be two strings:

«»
«hello world»
«'one' 'two' 'three' 'four'»
«"one" "two" "three" "four"»
«["one", "two", "three"]»
«; exit()»


For each of these pairs of strings, there must be at least one string you can provide to your program such that that pair is output (surrounding «quotes» excluded):

 s_1     |  s_2
---------|----------
«hello » | «world»
«hell»   | «o world»
«hello»  | « world»
« »      | «»
«»       | « »
«»       | « !"#$%&amp;'()*+,-./0123456789:;&lt;=&gt;?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~»
«\r\n»   | «\r\n»


As always, you are encouraged to add test cases pertinent to your method.

Rules:


Input must be a single string/character array/byte array consisting of only ASCII characters.
Output is  ordered; \$(a,b)\neq(b,a)\$. Output can be any ordered structure in your language, or printed with a newline (LF or CR LF) separator and optional trailing newline.
I/O must be consistent. If one case handles input as an argument and outputs to stdout with a trailing newline, all cases must handle input as an argument and output to stdout with a trailing newline.
Standard loopholes are forbidden.
This is code-golf, so shorter programs are better!


As a reminder, this is only a surjection, not a bijection: Your program/function will likely map many different strings to the same output.
Python 2, 42 bytes



lambda s:(s.split("1"+len(s)/2*"0")*2)[:2]


Try it online!

The inverse is:

def F(a,b):
    return a+"1"+len(a+b)*"0"+b


A tempting idea for the inverse is to encode the pair of input strings by putting some separator string in between them. That way, we can extract the pair by splitting on this separator. The issue is that the separator may appear in the inputs string.

We get around this by making the separator longer than the total length of both strings. We use 1 followed by a number of 0's equal to the number of characters in both strings. For example,

abc, defgh -&gt; abc100000000defgh


Note that no matter how many 0's and 1's are in the two inputs, there's no way to get another copy of the separator to appear.

We can recover the separator from the combined string by using a number of zeroes equal to half its length rounded down. I had wanted to compute this as 10**_, but Python's repr appends an annoying L to large numbers, which messes it up.

We need to the submission function still give two outputs when the input string doesn't contain the required separator. In this case, splitting just gives the original string, but we copy it twice to be compliant.



Python 2, 35 bytes (not working)



lambda s:s.split(s[:len(s)/3])[-2:]


Try it online!

This would work except it gives an error for the empty string. The idea is to have the inverse encode a,b -&gt; sep + a + sep + b, where the separator sep has the same length as a+b so we can extract it as the first third of the string. A similar idea of putting the separator interspersed runs into the same issue.



Python 2, 43 bytes



lambda s:[s[i::2].lstrip()[1:]for i in 0,1]


Try it online!

The idea for encoding is to intersperse the two input strings with alternating characters. The problem there is that they may have different lengths. So, we pad them to the same length by prepending each one with some number of leading spaces then | (any non-space char will do). For example, abcd, ef goes to

|abcd
  |ef


This can be undone for each string by stripping off all leading spaces then removing the first character. Note that any spaces or | in the actual strings are left unharmed.

Python 3.8 (pre-release), 44 bytes



lambda s:(s[(i:=s.find('_'))+1:2*i],s[2*i:])


Try it online!

Inverse:

F=lambda a,b:(len(a)+1)*"?"+"_"+a+b


For instance, F("ab","cdef") = ???_abcdef. The number of symbols before the _ tells us where to split the remainder -- it's one more than the length of the first string. 

We need the submission not to error when there's no _, but this works out because Python's string find uses -1 for missing, which still gives valid slices.