[Question]
  [
## Input:
Two strings (NOTE: the order of input is important).
## Output:
Both words/sentences start on lines with one empty line in between them. They 'walk' horizontally 'next to each other'. But when they have the same character at the same position, they cross each other, and then continue walking 'next to each other'.
Confusing you say? Let's give an example:
Input: `Words crossing over` & `Ducks quacking`:
```
Word  quack n 
    s      i g
Duck  cross n  over
```
[![As you can see, these are the paths:](https://i.stack.imgur.com/wFSpg.png)](https://i.stack.imgur.com/wFSpg.png)  
*Excuse the bad MS paint..*
## Challenge rules:
* We always first go back walking a straight line after we've 'crossed over' before we can cross over again (see test case above {1} - where `ing` is equal, but after we've crossed on `i`, we first have to go back walking straight (thus ignoring `n`), before we can cross again on `g`).
* The inputs can be of different length, in which case the longer one continues walking in a straight line (see test cases 1, 2, 4 & 6).
* Both inputs can be the same (see test case 3).
* The inputs won't contain any tabs nor new-lines.
* **Spaces are ignored as characters that are the same (as an edge case)**, in which case the next (non-space) character after that - if any - is crossing over instead (see test cases 3, 5 & 6).
* The inputs can have no adjacent (non-space) characters on the same position at all, in which case both just walk in a straight line horizontally (see test cases 2).
* Even if the first character is equal, we always start two lines apart (see test cases 3 & 6).
* Trailing spaces and a single trailing new-line are optional.
* You can assume the inputs will only contain printable ASCII characters (new-lines and tabs excluded).
* The inputs are case-sensitive, so `A` and `a` aren't equal, and won't cross over (see test case 7).
* Both the inputs lengths will always be at least 2.
* Input & output can be in any reasonable format. Can be a single String with new-lines; a String-array/list; printed to STDOUT; 2D array of characters; etc.
## General rules:
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so shortest answer in bytes wins.  
Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
* [Standard rules apply](https://codegolf.meta.stackexchange.com/questions/2419/default-for-code-golf-program-function-or-snippet/2422#2422) for your answer, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
* [Default Loopholes](https://codegolf.meta.stackexchange.com/questions/1061/loopholes-that-are-forbidden-by-default) are forbidden.
* If possible, please add a link with a test for your code.
* Also, please add an explanation if necessary.
## Test cases:
```
1. Input: "Words crossing over" & "Ducks quacking"
1. Output:
Word  quack n 
    s      i g
Duck  cross n  over
2. Input: "bananas" & "ananas"
2. Output:
bananas
ananas
3. Input: "I see my twin!" & "I see my twin!"
3. Output:
I  e   y  w n 
  s e m  t i !
I  e   y  w n 
4. Input: "Is the weather nice?" & "Not really, no.."
4. Output:
Is th ally, no..
     e
Not r  weather nice?
5. Input: "Codegolf & Programming Puzzles" & "The golfer might solve puzzles"
5. Output:
Code o f & Programming P z l s
    g l                 u z e
The  o fer might solve p z l s
6. Input: "Can you turn the lights off?" & "Can you try to solve this?"
6. Output:
C n  o   urn the  ve  s off?
 a  y u t        l   t 
C n  o   ry to so igh his?
7. Input: "one Ampere" & "two apples"
7. Output:
one Am les
      p
two ap ere
8. Input: "Words crossing" & "Words Quacking"
8. Output:
W r s cross n 
 o d       i g
W r s Quack n 
```
  
[Answer]
# [APL (Dyalog)](https://www.dyalog.com/), 64 bytes
```
{C←⎕UCS⋄1↓e⊖' '⍪1 0 1⍀⍵⊖⍨≠\e←C(2/⊃l)⎕R(l←C⌽⍳2)C(0@0=⌿⍵)∧' '≠1⌷⍵}
```
[Try it online!](https://tio.run/##XZDNSsNAFIX3PsV1Y1rQmnQvVeKmG61/uHEzptM0dJKJM0lLK4KgFFsbUUTX3SluRVyJ73JfpN6xVWMZmJ8z3zlzGBaLlXqXCelP8Oahuo39W3viKqk17U5dmkg@cPfw@tLB/j3H4aMFFmYvDtjgYHaO2RtpmD3jYHzEiXcL5VUcXogiGXcLwig4@sDstVx0C/a6vYajTzIV8erJJA3GDo7eSTibTN8F7N9Zh1LVNXjmHEQ@yDZXBG@mXkvDScq8FqnWwh9/zCIampjZJndXBc05hF1IOkG0SMickEc1JE0OHc5oURAFHq@QYUsmoDgTorsMkSyV8hZX1rkvRQOWoKakr1gYmsa1tNcT3BTap0ADUF4Y@M0EtBRtDvEMyEexCLoyhSRV0XcPYXgNstEwLX6vFTWXs5ikGehKPkRGHDbCmCtOlqQjgcXx3Dv/P5ewqbDz869f "APL (Dyalog Unicode) – Try It Online")
[Answer]
# [Japt](https://github.com/ETHproductions/japt), ~~56~~ ~~47~~ 33 bytes
```
y ®m+S éBv ©Zê¬©Zx ?°B:B=c2)¯3Ã·y
```
[Test it online!](http://ethproductions.github.io/japt/?v=1.4.5&code=eSCubStTIOlCdiCpWuqsqVp4ID+wQjpCPWMyKa8zw7d5&input=WyJDYW4geW91IHR1cm4gdGhlIGxpZ2h0cyBvZmY/IiAmICJDYW4geW91IHRyeSB0byBzb2x2ZSB0aGlzPyJd) Takes input as an array of two strings.
I am a total moron... `y ®` is a million times easier to use on two different-length strings than `U¬íV¬@`...
### Explanation
```
y ®   m+S éBv © Zê¬ © Zx ?° B:B= c2)¯  3Ã ·  y
y mZ{Zm+S éBv &&Zêq &&Zx ?++B:B=Bc2)s0,3} qR y
              Implicit: U = array of two strings
y             Transpose U, padding the shorter string with spaces in the process.
mZ{        }  Map each pair of chars Z by this function: (we'll call the chars X and Y)
  Zm+S          Append a space to each char, giving X + " " + Y + " ".
  Bv            If B is divisible by 2
  &&Zêq           and Z is a palindrome (X and Y are the same)
  &&Zx ?          and Z.trim() is not empty (X and Y are not spaces):
    ++B           Increment B. B is now odd; the top and bottom strings are swapping.
  :             Otherwise:
    B=Bc2         Ceiling B to a multiple of 2. (0 -> 0, 1 -> 2, 2 -> 2, etc.)
  é       )     Rotate the string generated earlier this many chars to the right.
  s0,3          Take only the first 3 chars of the result.
qR            Join the resulting array of strings with newlines.
y             Transpose rows with columns.
              Implicit: output result of last expression
```
`B` is a variable that keeps track of which state we're in:
* `B % 4 == 0` means first word on top, but ready to switch;
* `B % 4 == 1` means we've just switched;
* `B % 4 == 2` means second word on top, but ready to switch;
* `B % 4 == 3` means we've just switched back.
`B` happens to be preset to `11`; since `11 % 4 == 3`, the first column always has the first word on top. We increment `B` any time the words swap positions, or any time it's odd (with `B=c2`).
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 69 bytes
```
ＡＥ⮌θιθＡＥ⮌ηιηＷ∧θη«Ａ⊟θεＡ⊟ηδＡ∧¬∨φ⁼ε ⁼εδφ¿φ«εＡθδＡηθＡδη»«↑↓ε↓↗δ»»¿θ↑↓↑⮌⁺θη
```
[Try it online!](https://tio.run/##bVBLasMwEF3bpxiyGoFzgWQRQttlUhPIAUwsRQIhWR87hOKzq5YsGxe60GLedzQP3tiHbmQIZ@fEU@Gl6fBGB2odRUMqENMz5Fj@Q/NM84l@cSEp4Fm1aCJC4KcssqfWXYqik26LRX@7waL5qj1@W2QVfJm@kQ5pBTvYEUK2SBtHFq2CAbJUVtRWKI@pZEk0uWCZ@fyXdW7n5YsRqHQ0pVz0QPFw75Jsjjx86pfK62c@IlvFvbuJJ/e5bizHMi5mCKxxc8Mf9@qtYDlpLXuXD0iOIXw0Ct66B99bBZ5TkLHFgWbsVK6kfYPX4LQc6CQS7hT2Q9g7@Qs "Charcoal – Try It Online") Link is to verbose version of code. Explanation:
```
ＡＥ⮌θιθＡＥ⮌ηιη        Turn the input strings into arrays and reverse them
Ｗ∧θη«               While both valus still have characters left
     Ａ⊟θεＡ⊟ηδ       Extract the next pair of characters
     Ａ∧¬∨φ⁼ε ⁼εδφ   Determine whether this is a crossing point
     ¿φ«εＡθδＡηθＡδη  If so then print the character and switch the value
      »«↑↓ε↓↗δ»»     Otherwise print the two characters apart
¿θ↑↓                Move to print any remaining characters accordingly
↑⮌⁺θη               Print any remaining characters
```
[Answer]
# [Python 2](https://docs.python.org/2/), ~~217~~ 210 bytes
-1 byte thanks to officialaimm
```
a,b=map(list,input())
n=max(len(a),len(b))
c=[' ']*n
a=(a+c)[:n]
b=(b+c)[:n]
for i in range(1,n):
 if a[i]==b[i]!=' '==c[i-1]:c[i]=a[i];a[i]=b[i]=' ';a[i:],b[i:]=b[i:],a[i:]
print'\n'.join(map(''.join,[a,c,b]))
```
[Try it online!](https://tio.run/##RY7BTsQwDETv@QrTSxIwSMuxKNoDnxFySKJ2a9R1qjRF9OtLUoS4jMdvRpaXvUyJX4/DYzB3v6iZ1oLEy1aU1oIr@1bzwMprbCNUGI2VIN0jC2@Uf4ra9uxEMCr8@TFlICCG7Pk2qAuy7gXQCN6SMyZUfTD1hjHR0vPF9bHxFr6djVZoedt6h6GpORVPIpZMXOQHy5fPRKza4/LXo/UYMTitj6N79wx72qBsmaFMA8x0m8oKaRyvHSD8F/IOJcGa5q@hFmm9dj8 "Python 2 – Try It Online")
[Answer]
## Haskell, ~~142~~ 138 bytes
```
g(a:b)f(c:d)|f>0,a==c,a>' '=[' ',a,' ']:g d 0b|1<2=[a,' ',c]:g b 1d
g[]_[]=[]
g b f d=g(max" "b)f$max" "d
a&b=[[j!!i|j<-g a 0b]|i<-[0..2]]
```
[Try it online!](https://tio.run/##jZJfa8IwFMXf/RTHIv6BKrpHscrYXgbbcGywh1LGbZvGapt0SapT/O4ubYewsYcSSC6He37nJmRDesey7HLhQ5qHo2QYzePROVlOXfK8yKXlAAPPt5tLrt2DOUeMaXieLW48v5bcqBJDzOIO94MPP/D8oFMJCWKPD3P6cuBYcq@p4g71Q8/3t91uet4uxhxkecE5XYz96WRyEwSXnFIBD7HsAMipePpAUZpXox4FenDepYo1IiW1TgWH3DPloA/nvox2Gp8lRTurO5X5anOc/1khCbt07f8pW/keoBlDfoQ5pKJb2/9I7TAaZsNwYGQPBZFGbFXDnqWBYpRlRxdCTibtcHcyZlxmiSWsleSK8rx6oXV5OmWsueSbjatabFqe8o2BltmeWUrT0i6GBI6yhCmVqOfPKpKGTJJm@muDsq8hfyLMJtWrdgFSMNzmBVOsxpmDBBVF6/l@f5Aa0Ugv179x@QY "Haskell – Try It Online")
How it works:
```
g                    -- function g constructs a list of lists of three characters
                     --   the 1st char belongs to the upper line,
                     --   the 2nd char to the middle line and
                     --   the 3rd char to the lower line
      f              -- flag f indicates if crossing is allowed or not
 (a:b) (c:d)         -- strings to cross
  |f>0               -- if crossing is allowed
      ,a==c          -- and both strings start with the same char
           ,a>' '    --   that is not a space
   =[' ',a,' ']      -- return space for upper/lower line and char a for the middle line
      :g d 0b        -- and go on with crossing disabled and strings swapped
 |1<2=               -- else
   [a,' ',c]         -- keep chars in their lines and
      :g b 1d        --  go on with crossing enabled
g[]_[]=[]            -- base case: stop when both strings are empty
g b f d=             -- if exactly one string runs out of characters
 g(max" "b)f$max" "d --   replace it with a single space and retry
a&b=                 -- main function
          i<-[0..2]  -- for each line i from [0,1,2]    
       j<-g a 0b     -- walk through the result of a call to g with crossing disabled
    j!!i             -- and pick the char for the current line  
```
[Answer]
# JavaScript (ES6), 112 bytes
```
(a,b,c='',g=([a,...A],[b,...B],w)=>a?w&a==b&a>' '?' '+g(B,A,c+=a):a+g(A,B,1,c+=' '):'')=>g(a,b)+`
`+c+`
`+g(b,a)
```
**Ungolfed:**
```
f=
(a,b,                                    //the inputs
 c='',                                   //c will hold the middle sentence
 g=([a,...A],[b,...B],w)=>               //define a function to walk through the strings
                                         //w will be false if we're at the beginning,
                                         //... or if we've just done a swap
     a?                                  //are there any letters left?
       w&a==b&a>' '?' '+g(B,A,c+=a):     //if we haven't just swapped and the letters match,
                                         //... add the current letter to c 
                                         //... and recurse swapping the strings
                    a+g(A,B,1,c+=' '):   //else add a space to c and continue processing
                    ''
)=>
g(a,b)+'\n'+                             //call g with a, b
c+'\n'+                                  //output c
g(b,a)                                   //call g with b, a
```
**Test cases:**
```
f=
(a,b,c='',g=([a,...A],[b,...B],w)=>a?w&a==b&a>' '?' '+g(B,A,c+=a):a+g(A,B,1,c+=' '):'')=>g(a,b)+`
`+c+`
`+g(b,a)
console.log(f('Words crossing over','Ducks quacking'));
console.log('____________');
console.log(f('bananas','ananas'));
console.log('____________');
console.log(f('I see my twin!', 'I see my twin!'));
console.log('____________');
console.log(f('Is the weather nice?', 'Not really, no..'));
console.log('____________');
console.log(f('Codegolf & Programming Puzzles', 'The golfer might solve puzzles'));
console.log('____________');
console.log(f('Can you turn the lights off?', 'Can you try to solve this?'));
console.log('____________');
console.log(f('one Ampere', 'two apples'))
console.log('____________');
console.log(f('Words crossing','Words Quacking'));
console.log('____________');
```
[Answer]
# [APL (Dyalog)](https://www.dyalog.com/), 50 bytes
```
{3↑(0,+\2∨/2|{⍵⌈a×1+1,¯1↓⍵}⍣≡a←>⌿2=⌿3↑⍵)⊖⍵⍀⍨¯1*⍳4}
```
[Try it online!](https://tio.run/##XZC/SgNBEMZ7n2JsjJo/JtFWg2iTRiMINjbrZe9yZG/n3L1LuMSAVYiSE4OotdiksxBrQd9kXyTOJqeiLMwu3/y@b4ZloSg2EybQKzqCae07M3NzXz80w9vyzKXa3zTDyWq5kD@tmtF0o3rRN@mbGY/Y52MlXyl8vFTM8I6kgUmfzdUTI8uOGb9Xt6lYK7XWzPWDNaWXJp2SYd2kr1uDmY2f5E5QNTU4Cmm29AA7XOUgtx87bQ3nMXPapOaW5ugZk3Q0tbPHQq6D5hyCBKKuL5ep@0/IKA1Ri0OXM7oUSN/hNWIPMALFmRBJASSWShm9h03uoXBhBRoKPcWCwG7XiHs9we0Gx5RlAYoKfK8VgUbR4RBmQJbCJCQYQxQrOZ8uLKoBXdfO/mkrWhWzhKjl61rmR8lhNwi54kRHXQQWhr/pf3@OiIVw9P1pXw "APL (Dyalog Classic) – Try It Online")
`⍵⍀⍨¯1*⍳4` gives the matrix:
```
Words.crossing.over
...................
Ducks.quacking.....
...................
```
(the dots represent spaces). Its columns will be rotated by different amounts so the first three rows end up looking like the desired result - hence the `3↑` near the beginning. The rest of the algorithm computes the rotation amounts.
Within the parens: `3↑⍵` creates a matrix like
```
Words.crossing.over
Ducks.quacking.....
...................
```
and `2=⌿` compares its rows pairwise, i.e. first string vs second string and
second string vs the all-spaces row.
```
0 0 0 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1
```
We are interested in where the former is true (1) and the latter false (0), so
we reduce with `>⌿` to get a boolean vector named `a`.
```
0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0
```
Now, in every stretch of 1-s we need to zero out the even occurrences because
no two twists can occur next to each other. First we obtain a numbering like:
```
0 0 0 0 1 0 0 0 0 0 0 1 2 3 0 0 0 0 0
```
by, loosely speaking, replacing `a[i]` with `a[i]*max(a[i-1]+1, a[i])` until
the result stabilises: `{⍵⌈a×1+1,¯1↓⍵}⍣≡`, and we take that mod 2: `2|`
```
0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0
```
Now we know where the twists will occur. We copy each `1` to the left - `2∨/`
(pairwise "or"):
```
0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 0 0
```
and compute the partial sums - `+\`
```
0 0 0 0 1 2 2 2 2 2 2 3 4 5 6 6 6 6 6
```
That gives us the column rotation amounts we needed in the beginning. Modulo 4 is implied.
[Answer]
# [Perl 5](https://www.perl.org/), 211 bytes
```
@a=map[/./g],<>;$b=1;($f,@{$r[$i]})=$a[0][$i]eq$a[1][$i]&&$f&&$a[0][$i]ne$"?(0,$",$a[0][$i],$",$t=$b++):(1,$a[$t%2][$i],$",$a[$b%2][$i]),$i++while$a[0][$i]||$a[1][$i];for$i(0..2){print$r[$_][$i]for 0..$#r;say''}
```
[Try it online!](https://tio.run/##RY7BjoIwEIbv@xSNjgqhYiHhIoua7HmfgJBNSVppgi3bVg1RX327hSgeJvm/@WYy0zHdZs4daHGiXbmJN8cKf@5yqIskD4Djww10CaJ6hAXQklRDZr8@JmNcLoH7ehnJYLYPCIYZnnoj2ALqKAq3QTIIsIv07TzXTw4xiCi6NqJl0/79Pl3LudIgAhLHaXjrtJB2eO5ndF4hL2Cuc0P71erh3BeVqFdnZM9aItsw1IpjYw1SnH9MTvfIKmRUe2F@Rpg/1VmhpHHr7ywmCfkH "Perl 5 – Try It Online")
~~# [Perl 5](https://www.perl.org/), 234 bytes~~
*fixed the bug Kevin pointed out*
```
@a=map[/./g],<>;$l=@{$a[0]}>@{$a[1]}?@{$a[0]}:@{$a[1]};$b=1;@{$r[$_]}=$a[0][$_]eq$a[1][$_]&&$_&&$r[$_-1][1]eq$"&&$a[0][$_]ne$"?($",$a[0][$_],$",$t=$b++):($a[$t%2][$_],$",$a[$b%2][$_])for 0..$l;for$i(0..2){print$r[$_][$i]for 0..$l;say}
```
[Try it online!](https://tio.run/##RY7BisIwFEX38xWhvJEWa20FN3aiwqznC0qQFFINZJKaRKFIf30yL52pLh6ce@5dvF5YtQ3hyOk375t1sT6z/GNfg6LHB/CmZON@goqNh9nsZlNDS6sak23gxEY61RHFdRpEXCzghBcXKzRV7BIU81QLSA4pJPnT5DF4Cu1yme1S1ODfN68Gc/ufs85YUhYFqBoJZIq8yR69ldr//dSAZK@R48MYwifXZDA34m9WE38RRMnzxTtiuu7t2dmBeEOcUXeBG@l@TO@l0S6svrZFWZW/ "Perl 5 – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 31 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
ζεËNĀ¾Èyðå_Pi¼ë¾É½}yð«S¾._¨}øJ»
```
Port of [*@ETHproductions*'s Japt answer](https://codegolf.stackexchange.com/a/138546/52210), but with two minor differences:  
1) I take the input as a 2D list of characters instead of list of strings.  
2) The `counter_variable` in 05AB1E is 0 by default, instead of 11 (or 3) like the `B` in Japt, so the `NĀ` is added as additional check inside the map (and I rotate towards the right instead of left).
[Try it online](https://tio.run/##yy9OTMpM/f//3LZzWw93@x1pOLTvcEfl4Q2Hl8YHZB7ac3g1kN95aG8tUOjQ6uBD@/TiD62oPbzD69Du//@jo5XClXSU8oG4CIhTgLgYiBWAOBkqlg8VA@FMIM4D4nSoGpBcGRCngtXG6uA2LRCIS4E4EWpyNoppsbEA) or [verify all test cases](https://tio.run/##nVTBSsNAEP2VmoOnkF8oohc9lIiChxBK2qYxmCY1SVMiFDwqfocg9OKlRVB72PTcX4qT9C0ZQkKlh0d2Z@e9NzuzbRBZA9fOkzTfrXer7K23fRab7CXNPrP3vu6Kn2xJ@1fxu6CQWN6IjdYXH4vs60p856pYdzWxyg3DUO4UVQkIIWFEiAgdwhCxALECLsEnOMgpzhKCXeaaqqFc0GoG9gNTe0TcYmeVmmmqHSplgAS/9o1K6ZaTPfUSPhGqsbGfEFKsY8Kc@Z6UskcyK9uIJd0zgTnWVu0sxLkPwSHi3bKcHtoaIytkKh5QlKUylSJfK4GyzhEcgexgX5DHIJ7iq7M5O1hbuP@kYeY6JvkEePDYD@m21oS6M2@AVHfAidkkJCdhWtN25@ra8nV00KcAJDmhGQrwW6bmNRQVsec@BvbT@o9jWHtIwYFryopc5HTl9QIYycQz9HDK@mqXZcn3Kq0sZE2bunbcH0Bh08a8PvBjN/8A).
**Explanation:**
```
ζ                  # Zip/transpose (swapping rows/columns) the (implicit) input-list
                   # with space filler by default to create pairs
 ε          }      # Map each pair `y` to:
  Ë                #  Check if both values in the pair are equal
  NĀ               #  Check if the map-index is not 0
  ¾È               #  Check if the counter_variable is even
  yðå_             #  Check if the pair contains no spaces " "
  Pi               #  If all checks are truthy:
    ¼              #   Increase the counter_variable by 1:
   ë               #  Else:
    ¾É             #   Check if the counter_variable is odd
      ½            #   And if it is: increase the counter_variable by 1
   }               #  Close the if-else
    yð«            #  Add a space after both characters in the pair
       S           #  Convert it to a list of characters (implicitly flattens)
        ¾._        #  Rotate this list the counter_variable amount of times towards the right
           ¨       #  And then remove the last character
             ø     # Zip/transpose; swapping rows/columns
              J    # Join each inner character-list to a single string
               »   # Join everything by newlines (and output implicitly)
```
]