Words crossing over

APL (Dyalog), 64 bytes

{C←⎕UCS⋄1↓e⊖' '⍪1 0 1⍀⍵⊖⍨≠\e←C(2/⊃l)⎕R(l←C⌽⍳2)C([email protected]=⌿⍵)∧' '≠1⌷⍵}

Try it online!

Charcoal, 69 bytes

AE⮌θιθAE⮌ηιηW∧θη«A⊟θεA⊟ηδA∧¬∨φ⁼ε ⁼εδφ¿φ«εAθδAηθAδη»«↑↓ε↓↗δ»»¿θ↑↓↑⮌⁺θη

Try it online! Link is to verbose version of code. Explanation:

AE⮌θιθAE⮌ηιη        Turn the input strings into arrays and reverse them
W∧θη«               While both valus still have characters left
     A⊟θεA⊟ηδ       Extract the next pair of characters
     A∧¬∨φ⁼ε ⁼εδφ   Determine whether this is a crossing point
     ¿φ«εAθδAηθAδη  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

Japt, 56 47 33 bytes

y ®m+S éBv ©ZꬩZx ?°B:B=c2)¯3÷y

Test it online! 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¬@...


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).