g | x | w | all
Bytes Lang Time Link
175Swift 6250428T141714ZmacOSist
120TXR Lisp170802T003350ZKaz
163Perl 5170809T045211ZXcali
216Java 8170808T002225ZJakob
02305AB1E170807T184834ZEmigna
025V170802T142821Znmjcman1
129PHP170802T161540ZTitus
026Jelly170801T202146ZJonathan
031Charcoal170801T183132ZNeil
174Mathematica170801T232524ZZaMoC
028Japt170801T174251ZETHprodu
028Jelly170801T183933ZErik the
079V170801T174718ZDJMcMayh
133Javascript ES6170801T172039ZLuke
163C# .NET Core170801T170757Zjkelm
119Python 2170801T163903ZRod
035Pyth170801T161738ZLeaky Nu

Swift 6, 175 bytes

let n="\n",z={s,t in[""]+s+t
var l=s.count,o="",p=o
(l/2..<l).map{o+=t[$0]+s[$0]
p+="  "}
o=p+o+t[l]+n
while l>0{l-=2
{o=" "+$0+s[l/2]+n+o+$0+t[l/2]+n}(p.prefix(l))}
return o}

Try it on SwiftFiddle!

Takes input as two arrays of single-character strings (what you get when you run "hello world".map(String.init). The shorter string comes first.

This is the same general idea as this Java answer, just a lot golfier.

TXR Lisp, 126 123 122 120 bytes

(defun f(a b :(n 0))(if(>(*(len a)2)n)` @{""n}@[a 0]\n@(f(cdr a)(cdr b)(+ n 2))\n@{""n}@[b 0]``@{""n}@{(weave b a)""}`))

Check that it runs after 8 years:

2> (put-line (f "zippered" "paragraph"))
 z
   i
     p
       p
        gerraepdh
      a
    r
  a
p
t

Perl 5, 163 bytes

@a=map{$s=.5*length;[/./g]}<>;say(($"x(2*$_)).$a[0][$_])for 0..$s-1;print$"x(2*$s);print$a[0][$_].$a[1][$_]for$s..@{$a[1]};print$/.($"x(1+2*$s)).$a[1][$s]while$s--

Try it online!

Takes the longer string first.

Java 8, 216 bytes

A curried lambda: takes String and returns a lambda from String to String. The parameter to the outer lambda is the shorter string.

Not being able to index into Strings with array syntax is...unfortunate.

s->t->{int l=s.length(),i=l/2;String o="",p=o,n="\n";for(;i<l;p+="  ")o=o+t.charAt(i)+s.charAt(i++);o=p+o+t.charAt(i)+n;for(;i-->0;)o=p.substring(l-i--)+s.charAt(i/2)+n+o+p.substring(l-i)+t.charAt(i/2)+n;return o;}

Ungolfed lambda

s ->
    t -> {
        int
            l = s.length(),
            i = l / 2
        ;
        String
            o = "",
            p = o,
            n = "\n"
        ;
        for (; i < l; p += "  ")
            o = o + t.charAt(i) + s.charAt(i++);
        o = p + o + t.charAt(i) + n;
        for (; i-- > 0; )
            o =
                p.substring(l-i--)
                + s.charAt(i / 2)
                + n
                + o
                + p.substring(l-i)
                + t.charAt(i / 2)
                + n
            ;
        return o;
    }

Explanation

l is the length of the shorter input and i is a multipurpose index, initialized to refer to the first character of the second half of the shorter input. o accumulates the result, p ultimately stores spaces for padding, and n is an alias for "\n".

The first loop interleaves the second halves of the two strings (excluding the last character of the longer input) and builds p to the proper amount of padding for the middle line.

The next line completes the middle line of output.

I would like to apologize to James Gosling for the second loop. It adds the lines above and below the middle line from the inside out. Entering the loop, i is l - 1, so one character of padding is prepended along with the last character of the first half of the shorter string. i is decremented so that the next padding (appended to the result) is a character shorter. By integer division, the same position character of the longer string is appended. This repeats, and the completed result is returned.

Cool stuff

Line 13 used to be

o+=t.charAt(i)+""+s.charAt(i++);

because without the empty string, + added the character values together and appended a numeric string. By expanding the compound assignment, the concatenation of o and t.charAt(i) is evaluated first, which yields the desired result without need for the empty string, saving 2 bytes. This is the first time I've seen a compound assignment behave differently from its expansion.

05AB1E, 26 23 bytes

øS2ä`JIθ«¸«vyNúr})2äR˜»

Try it online!

Explanation

With example input = ppcg, tests

ø                           # zip the input strings
                            # STACK: ['tp', 'ep', 'sc', 'tg']
 S                          # split to a list of characters
                            # STACK: ['t', 'p', 'e', 'p', 's', 'c', 't', 'g'
  2ä                        # divide the list into 2 parts
    `                       # push them as separate to stack
                            # STACK: ['t', 'p', 'e', 'p'], ['s', 'c', 't', 'g']
     J                      # join the second part to a single string
      Iθ«                   # append the tail of the second input
         ¸«                 # concatenate the 2 lists
                            # STACK: ['t', 'p', 'e', 'p', 'sctgs']
           v                # for each y,N (element, index) in the list
            yNú             # prepend N spaces to y
               r            # reverse the stack
                })          # end loop and wrap the stack in a list
                            # STACK: ['    sctgs', '  e', 't', ' p', '   p']
                  2ä        # split the list into 2 parts
                    R       # reverse the list
                            # STACK: [[' p', '   p'], ['    sctgs', '  e', 't']]
                     ˜»     # flatten the list and join on newlines

V, 47 38 30 27 26 25 bytes

Finally beat the current Jelly answer \o/

Takes input with the longer word on top

Explanation coming, don't think there's much more to golf.

òGxplòxãòd|>HÏpd|>GGÏphl

Try it online!

Explanation

ò     ò      ' <M-r>ecursively
             |abc
             def
 Gx          ' (G)oto the last line and (x) the first character
             abc
             |ef
            ' <C-O> Go back to the previous location
             |abc
             ef
    p        ' (p)aste the character cut
             a|dbc
             ef
     l       ' move one character right
             ad|bc
             ef

x                  ' (x) the last extraneous character from the previous loop
 ã                 ' <M-c>enter the cursor
  ò                ' <M-r>ecursively
   d|              ' (d)elete to the first co(|)umn
     >H            ' (>) Indent every line from here to (H)ome (first line)
                   ' this leaves the cursor on the first line
       Ïp          ' <M-O>n a newline above this (the first) (p)aste the deleted section
                   ' this leaves the cursor on the last character
         d|        ' (d)elete to the first co(|)umn
           >G      ' (>) Indent every line from here to the end (G)
                   ' unfortunately the cursor stays on the first line
             G     ' (G)oto the last line
              Ïp   ' <M-O>n a newline above this (the last) (p)aste the deleted section
                hl ' move left and then right (break the loop at the end)

PHP, 149 129 bytes

for($r=" ";$x+1<$w=2*$e=strlen($argv[2]);++$x&1||$r[++$i*$w-1]="
")$r[$w*($x&1?$y-1:$e-$y+=$y<$e/2)+$x]=$argv[2-$x%2][$i];echo$r;

Run with -nr or try it online.

Jelly,  27  26 bytes

-1 byte thanks to Erik the Outgolfer (use repeat, ¡, to replace if, ?, and a passed else clause ¹)

JCḂ¡€ṚH
żµL⁶ẋ;ЀFṙ"ÇZṙÇṀ$Y

A full program that prints the result with leading white-space, as allowed in the question (or a dyadic link returning a list of characters).

Try it online!

How?

JCḂ¡€ṚH - Link 1, get rotations: list p        e.g.: ["a1","b2","c3","d4","e5","f6","g"]
J       - range of length of p                       [ 1, 2, 3, 4, 5, 6, 7]
    €   - for €ach:
   ¡    -   repeat link:
  Ḃ     - ...# of times: modulo 2                      1  0  1  0  1  0  1
 C      - ...link: complement (1-x)                    0  2 -2  4 -4  6 -6
     Ṛ  - reverse                                    [-6, 6,-4, 4,-2, 2, 0]
      H - halve                                      [-3, 3,-2, 2,-1, 1, 0]

żµL⁶ẋ;ЀFṙ"ÇZṙÇṀ$Y - Main link: longer (odd length); shorter (even length)
                   -                           e.g.: "abcdefg", "123456"
ż                  - zip them together               ["a1","b2","c3","d4","e5","f6","g"]
 µ                 - monadic chain separation, call that p
  L                - length of p                     7
   ⁶               - literal space character         ' '
    ẋ              - repeat                          "       "
        F          - flatten p                       "a1b2c3d4e5f"
      Ѐ           - map with:
     ;             -   concatenation                 ["       a","       1","       b","       2","       c","       3","       d","       4","       e","       5","       f","       6","       g"]
           Ç       - call last link (1) as a monad with argument p
          "        - zip with (no action on left by trailing values of right):
         ṙ         -   rotate left by                ["  a     ","    1   "," b      ","     2  ","c       ","      3 ","       d","       4","       e","       5","       f","       6","       g"]
            Z      - transpose                       ["    c        ","  b          ","a            ","             "," 1           ","   2         ","     3       ","      d4e5f6g"]
                $  - last two links as a monad:
              Ç    -   call last link (1) as a monad with argument p
               Ṁ   -   maximum                       3
             ṙ     - rotate left by                  ["             "," 1           ","   2         ","     3       ","      d4e5f6g","    c        ","  b          ","a            "]
                 Y - join with newlines            '''             \n
                                                       1           \n
                                                         2         \n
                                                           3       \n
                                                            d4e5f6g\n
                                                          c        \n
                                                        b          \n
                                                      a            '''
                   - as full program: implicit print

Charcoal, 33 31 bytes

→F²«FLθ«§θκ→¿‹κ÷Lθ²¿ι↑↓»J⁰LθAηθ

Try it online! Link is to verbose version of code. Takes the shorter string first. Edit: Saved 2 bytes by tweaking the midpoint detection. Explanation:

→F²«

Loop over each string in turn.

FLθ«

Loop over each character of the string in turn.

§θκ→

Print the character and move an extra square to the right.

¿‹κ÷Lθ²¿ι↑↓»

For the first half of the string, also move the cursor down or up as appropriate.

J⁰LθAηθ

After printing the first string, jump to the second string's starting point, and replace the first string with the second, so that it gets printed for the second loop. (The code runs on both loops, but the second time it's a no-op.)

Mathematica, 174 bytes

(a=(c=Characters)@#;b=c@#2;T=Table;Column[Join[T[T["  ",i]<>a[[i]],{i,g=Length@a/2}],{T["  ",g+1]<>Riffle[b[[-g-1;;]],a[[-g;;]]]},Reverse@T[T["  ",i]<>b[[i+1]],{i,0,g-1}]]])&


Input

["zippered", "paragraph"]

Japt, 31 28 bytes

N®¬£ç iXYm½*Ul
uUo mw
y c ·y

Test it online! Takes the shorter string first.

Explanation

N®¬£ç iXYm½*Ul    First line: Set U to the result.
N®                Map each item (there's exactly 2 of them) in the input to
  ¬                 the item split into chars,
   £                with each item X and index Y mapped to
    ç                 the first input filled with spaces,
      iX              with X inserted at index
        Ym½*Ul          min(Y, 0.5 * U.length).
                  At the end each input is an array like
                  ["p    ", " p   ", "  c  ", "  g  "]
                  ["t    ", " e   ", "  s  ", "  t  ", "  s  "]

uUo mw    Second line: Set V to the result (though that's not important).
 Uo       Pop the last item (the array representing the second string) from U.
    m     Map each item by
     w      reversing.
u         Push the result to the beginning of U.
          At the end we have e.g.
          ["    t", "   e ", "  s  ", "  t  ", "  s  "]
          ["p    ", " p   ", "  c  ", "  g  "]

y c ·y    Last line: Output the result of this line.
y         Transpose: map [[A,B,C,...],[a,b,c,...]] to [[A,a],[B,b],[C,c],...].
  c       Flatten into one array. [A,a,B,b,C,c,...]
    ·     Join on newlines. Now we have the output transposed.
     y    Transpose rows with columns.

Jelly, 28 bytes

HĊ©«Rµ®Ḥ_,Ṗ
ZLÇṬ€a"¥"o⁶ZẎz⁶Y

Try it online!

Woo Jelly is actually competing in a and challenge! \o/

V, 79 bytes

ãl}dÍ./ &
XòYf D"0Pr -Y;D"0pr +òGï"1pÓ./&ò
}dGÓ/&ò
{jpògJòÓó
|DÇ./d
MÙ"-pBr 

Try it online!

The following should be read with plenty of sarcasm and air-quotes.

Here's an answer in my golfing-language that's good at short answers to string-based and ASCII-art challenges.

Why do I keep doing this to myself?

Hexdump:

00000000: e36c 167d 64cd 2e2f 2026 0a58 f259 6620  .l.}d../ &.X.Yf 
00000010: 4422 3050 7220 2d59 3b44 2230 7072 202b  D"0Pr -Y;D"0pr +
00000020: f247 ef22 3170 d32e 2f26 f20a 0f16 7d64  .G."1p../&....}d
00000030: 47d3 2f26 f20a 7b6a 70f2 674a f2d3 f30a  G./&..{jp.gJ....
00000040: 7c44 c72e 2f64 0a4d d922 2d70 4272 20    |D../d.M."-pBr 

Javascript (ES6), 140 137 133 bytes

A=(a,b,c=0)=>a[c/2]?` `[d=`repeat`](c+1)+a[0]+`
`+A(a.slice(1),b.slice(1),c+2)+`
`+` `[d](c)+b[0]:` `[d](c)+[...a].map((e,f)=>e+b[f])

Quite sure this can be golfed further

C# (.NET Core), 163 bytes

(l,s)=>{var o="";int i=0,k=s.Length;for(;i<k;)o+=i<k/2?s[i++]+"\n"+"".PadLeft(i):l[i]+""+s[i++];o+=l[i]+"\n";for(i=k/2;i>0;)o+="".PadLeft(--i)+l[i]+"\n";return o;}

Try it online!

Probably a lot of golfing to do here, but here's an initial non-LINQ attempt. Lambda function that takes the longer word first, and returns a string with the ouput.

Python 2, 128 119 bytes

f=lambda a,b,n=0:n/2<len(a)and' '*-~n+a[0]+'\n'+f(a[1:],b[1:],n+2)+'\n'+' '*n+b[0]or' '*n+''.join(sum(zip(b,a+' '),()))

Try it online!

Pyth, 35 bytes

AQj.t.e+*d+lG*<klH*^_1k/h-lGk2b.iHG

Try it online!