| Bytes | Lang | Time | Link |
|---|---|---|---|
| 175 | Swift 6 | 250428T141714Z | macOSist |
| 120 | TXR Lisp | 170802T003350Z | Kaz |
| 163 | Perl 5 | 170809T045211Z | Xcali |
| 216 | Java 8 | 170808T002225Z | Jakob |
| 023 | 05AB1E | 170807T184834Z | Emigna |
| 025 | V | 170802T142821Z | nmjcman1 |
| 129 | PHP | 170802T161540Z | Titus |
| 026 | Jelly | 170801T202146Z | Jonathan |
| 031 | Charcoal | 170801T183132Z | Neil |
| 174 | Mathematica | 170801T232524Z | ZaMoC |
| 028 | Japt | 170801T174251Z | ETHprodu |
| 028 | Jelly | 170801T183933Z | Erik the |
| 079 | V | 170801T174718Z | DJMcMayh |
| 133 | Javascript ES6 | 170801T172039Z | Luke |
| 163 | C# .NET Core | 170801T170757Z | jkelm |
| 119 | Python 2 | 170801T163903Z | Rod |
| 035 | Pyth | 170801T161738Z | Leaky 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}
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--
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˜»
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
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).
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
Woo Jelly is actually competing in a string and ascii-art challenge! \o/
V, 79 bytes
ãl}dÍ./ &
XòYf D"0Pr -Y;D"0pr +òGï"1pÓ./&ò
}dGÓ/&ò
{jpògJòÓó
|DÇ./d
MÙ"-pBr
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;}
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+' '),()))