# Zip uneven lists

In this challenge you will take two lists as input and you will zip them. The zip can be defined with this recursive expression:

$$\ \mathrm{zip}(a,b) = \begin{cases} \left[\,\,\right] & a = \left[\,\,\right] \\ [a_0]\mid\mid\mathrm{zip}(b, t) & a = [a_0] \mid\mid t \end{cases} \$$

or this Haskell program if you would like:

zip [] _ = []
zip (x:xs) ys = x : zip ys xs

In simple terms you create a list which alternates between elements of the two input lists, starting with the first element of the first list, then the first element of the second list and so on, until one of the lists doesn't have the next element, then you stop.

For example if we zip [1,2,3,4,5] and [11,12,13] we get [1,11,2,12,3,13,4]. Every element appears in the output except 5, which is missing because the second list ran out before we reached it.

As input you will take two lists of positive integers and output the result of zipping them as described above. I use the term "first" and "second" when referring to the inputs, but you may take the two lists in the opposite order (although this choice must be consistent, you cannot e.g. swap the order of the inputs depending on what they are).

This is so the goal is to minimize your source code as scored in bytes.

## Test cases

[] [] -> []
[] [1,2,3] -> []
[1,2,3] [] -> [1]
[1,2] [3] -> [1,3,2]
[1,2,3,4,5] [11, 12, 13] -> [1,11,2,12,3,13,4]
[9,9,9] [8,8,8] -> [9,8,9,8,9,8]
[1,2,3] [4,5,6,7] -> [1,4,2,5,3,6]

As a word of advice if your language has a built-in which solves the task try and solve the task without the builtin and post both solutions as a single answer. It's more interesting to read solutions like that and it will almost certainly be more fun for you to golf.

• What is the upper range of the integers in the list? Mar 13, 2022 at 10:41
• Can we assume that the inputs are lists of numbers?
Mar 13, 2022 at 13:03
• What is the lower range of the integers in the list?
Mar 13, 2022 at 13:16
• @Adám "As input you will take two lists of positive integers". Mar 13, 2022 at 13:23
• @Adám "positive integers" Mar 13, 2022 at 13:26

# Python 2, 32 bytes

def f(X,Y):print X.pop(0);f(Y,X)

Attempt This Online!

Ends with an error.

## Python, 35 bytes

f=lambda X,Y:X and X[:1]+f(Y,X[1:])

Attempt This Online!

No error.

# Whython, 33 bytes

f=lambda X,Y:[X.pop(0)]+f(Y,X)?[]

Attempt This Online!

• 35 bytes for the first one. Mar 13, 2022 at 10:53

# 05AB1E, 6 5 bytes

ζ˜#R

Input-lists in reversed order.

1 byte is added to deal with the edge case of two empty input-lists, which otherwise would result in an empty string. Otherwise the two trailing bytes could have been н (pop and push first inner list) instead.

Explanation:

ζ      # Zip/transpose the two (implicit) input-lists, with space " " as filler
˜     # Flatten this list of pairs
#    # Split it on spaces
R   # Reverse the list of lists
# Pop and push the lists to the stack
# (after which the top list is output implicitly,
# or the (implicit) input-list if both lists were empty)

(a:x)#y=a:y#x
o#_=o

Attempt This Online!

# Prolog (SWI), 37 28 bytes

-9 bytes thanks to @DLosc

[H|T]+B+[H|Y]:-B+T+Y.
A+_+A.

Try it online!

# R, 36 bytes

f=\(a,b)if(sum(a))c(a[1],f(b,a[-1]))

Attempt This Online!

Slightly longer, but without recursion:

### R, 43 bytes

\(a,b,x=rbind(c(a,0),c(b,0)))x[!cumsum(!x)]

Attempt This Online!

# J, 19 18 17 16 bytes

0(i.~{.]),@|:@,:

Try it online!

-1 thanks to ovs!

Consider 1 2 3 4 f 8 9:

• ,: Laminate with 0-fill:

1 2 3 4
8 9 0 0

• |:@ Transpose:

1 8
2 9
3 0
4 0

• ,@ Flatten:

1 8 2 9 3 0 4 0

• 0(i.~{.[) Take everything up to the first 0:

1 8 2 9 3

• 16: 0(i.~{.]),@|:@,:
– ovs
Mar 13, 2022 at 17:18
• Very nice. Now we're tied with APL. Mar 13, 2022 at 17:23
• For now ;) APL can be a bit shorter (I have 11) if it relies on no 0's in the input.
– ovs
Mar 13, 2022 at 17:26

# Retina 0.8.2, 40 bytes

^
;
+;(\d+),?(.*);(.*)
$1,;$3;$2 ,?;.* Try it online! Link includes test cases. Explanation: ^ ; Start with an empty output list. + Until the first input list is empty, ... ;(\d+),?(.*);(.*) ... match the first element of the first input list, the rest of the first input list and the second input list, and...$1,;$3;$2

... move the first element of the input list to the output list and swap the rest of the first input list with the second list.

,?;.*

Delete the input lists.

# APL (Dyalog Unicode), 16 bytes

Anonymous tacit prefix function taking a list of two lists.

((>+2×⌊)/≢¨)⍴⍉∘↑

Try it online!

# Perl 6, 51 bytes

sub f(@a,@b){if @a {@a[0],|f(@b,@a[1..*])}else{()}}

Try it online!

# HBL, 6.5 bytes

?.(211.'?,(2.

The branch macro isn't implemented in the online interpreter at the moment, so here's a 7.5-byte equivalent without it:

?.(1(1.)('?,(2.

Try it!

### Explanation

The longer version implements the spec directly:

?.(1(1.)('?,(2.
?                If
.               The first argument is truthy:
(1               Cons
(1.)           The head of the first argument to
('?        A recursive call with
,       The second argument and
(2.    The tail of the first argument
Otherwise, return the first argument (empty list)

The branch macro (2, in golfed HBL) takes several expressions and restructures them into a function call with two arguments. With six expressions, it works like this:

(2 a b c d e f)  ->  (a (b c) (d e f))

In this case, we have:

2 1 1 . '? , (2.)  ->  (1 (1 .) ('? , (2.)))

# Ruby, 32 bytes

f=->a,b{r,*a=a;r ?[r,*f[b,a]]:a}

Try it online!

# Desmos, 139 bytes

l=[1...a.length+b.length]
g(A)=join(A,0l)[ceil(l/2)]
L=\{\mod(l,2)=1:g(a),g(b)\}
f(a,b)=\{a.\length=0:a,L[1...\min(\{L=0:l,l.\max+1\})-1]\}

Holy crap, it took me forever for me to get an actually working solution for this challenge in Desmos. I don't know if I'm severely overcomplicating this or what, but I got it to work so...

¯\_(ツ)_/¯

I'll see if I can golf this some more later, too tired to think about this right now :P

Try It On Desmos!

Try It On Desmos! - Prettified

# Curry (PAKCS), 21 bytes

(a:b)#c=a:c#b
[]#_=[]

Try it online!

The Haskell answer almost works in Curry, but because of non-determinism it matches any prefix of the result. We can restrain it by adding two more bytes.

# APL+WIN, 27 bytes

Prompts for two lists as a nested vector

(^\0≠v)/v←,⍉⊃(⌈/⍴¨v)↑¨v←,¨⎕

Try it online! Thanks to Dyalog APL Classic

• Fails on (0 0 0)(1 1 1)
Mar 13, 2022 at 13:17
• @Adám Is zero a positive integer. You did not get a "positive" answer to you question of 2 minutes ago Mar 13, 2022 at 13:29
• Yeah, I'm "frantically" trying to get a precise answer from OP.
Mar 13, 2022 at 13:30

# Charcoal, 13 bytes

ＵＭθ⮌ιＷ§θⅉ⟦Ｉ⊟ι

Try it online! Takes input as a pair of lists. Explanation:

ＵＭθ⮌ι

Reverse each of the two lists.

Ｗ§θⅉ

Cyclically index the lists according to the number of values already output and repeat until that list is empty.

⟦Ｉ⊟ι

Output the "next" value from that list on its own line.

# Jelly, 5 bytes

Uses Kevin Cruijssen's method from their 05AB1E answer.

z⁶FḲḢ

A monadic Link that accepts a pair of lists, [a, b], and yields a zipped list.

Try it online! Or see the test-suite.

### How?

z⁶FḲḢ - Link: pair of lists [a,b]
⁶    - space character
z     - transpose [a,b] with space-filler
F   - flatten
Ḳ  - split at spaces

# Factor, 43 39 bytes

[ f pad-longest vmerge { f } split1 . ]

Try it online!

## Explanation

! { 1 2 3 4 5 } { 11 12 13 }
f               ! { 1 2 3 4 5 } { 11 12 13 } f
pad-longest     ! { 1 2 3 4 5 } { 11 12 13 f f }
vmerge          ! { 1 11 2 12 3 13 4 f 5 f }
{ f }           ! { 1 11 2 12 3 13 4 f 5 f } { f }
split1          ! { 1 11 2 12 3 13 4 } { 5 f }
.               ! { 1 11 2 12 3 13 4 }

# JavaScript (ES6), 33 bytes

f=([v,...a],b)=>v?[v,...f(b,a)]:a

Try it online!

# Husk, 5 bytes

↑_ΣT0

Try it online!

Input is list of the two lists.

Transposes using 0 to fill shorter rows, flattens (Σ) the result, and takes the longest prefix with all elements that are truthy using the function _ (=negate; it would have been more-intuitive to use the Identity function here, but for reasons that I don't understand this doesn't seem to work).

Pretty-much the same approach as Kevin Cruijssen's answer but independently found.

Note that the Husk interpreter will not accept input consisting of only empty lists, presumably since it's unable to infer their type. The TIO link above successfully runs all the test cases (including the first, only-empty-lists one), since these are grouped together and run side-by-side, allowing the interpreter to infer that all lists are of numbers; but it fails when given the first test case on its own. I can't currently see a way to avoid this.

# x86 machine code (32-bit), 39 bytes

\x31\xC0\x89\xC5\x55\x87\x2C\x24\x39\xCD\x74\x19\xFF\x34\xAE\x8F\x04\x87
\x45\x40\x87\x2C\x24\x39\xD5\x74\x0A\xFF\x34\xAB\x8F\x04\x87\x45\x40\xEB
\xE0\x5D\xC3

Try it online!

The algorithm is quite straightforward, but 32-bit x86 really needs more registers. Some ugly stack hacks are used to cope with the lack of registers.

The test cases in TIO relies on a GCC extension supporting C arrays of length 0. ISO C and C++ forbid 0-length arrays.

Since OP didn't specify the upper bound of integers, I tried to find some clever way using an array of bytes, and interleaving them with pdep or some SSE shuffle instruction, but that ended up using too many bytes.

# edi: dst, esi: arr0, ecx: len0, ebx: arr1, edx: len1
# eax: return, ebp: clobber

0:  31 c0                   xor    eax,eax
2:  89 c5                   mov    ebp,eax
4:  55                      push   ebp
5:  87 2c 24                xchg   DWORD PTR [esp],ebp
8:  39 cd                   cmp    ebp,ecx
a:  74 19                   je     0x25
c:  ff 34 ae                push   DWORD PTR [esi+ebp*4]
f:  8f 04 87                pop    DWORD PTR [edi+eax*4]
12: 45                      inc    ebp
13: 40                      inc    eax
14: 87 2c 24                xchg   DWORD PTR [esp],ebp
17: 39 d5                   cmp    ebp,edx
19: 74 0a                   je     0x25
1b: ff 34 ab                push   DWORD PTR [ebx+ebp*4]
1e: 8f 04 87                pop    DWORD PTR [edi+eax*4]
21: 45                      inc    ebp
22: 40                      inc    eax
23: eb e0                   jmp    0x5
25: 5d                      pop    ebp
26: c3                      ret

# PARI/GP, 38 bytes

f(a,b)=if(a,concat(a[1],f(b,a[^1])),a)

Attempt This Online!

a[^1] means skiping the first item in a.

# Bash, 27 bytes

read x<$1&&echo$x&&f $2$1

Try it online!

Port of pxeger's python solution to Bash.

Input lists are taken as files (one entry per line). Output is one entry per line. Output contains extra blanks, which may be illegal and could be fixed at the price of some bytes, but I liked the simplicity of the translation.

# PowerShell Core, 45 bytes

param($a,$b)for(;$a){$h,$t=$a
$a,$b=$b,$t
$h} Try it online! One test case returns 1 instead of [1] as PowerShell tends to flatten arrays -1 byte thanks to mazzy • nice ConvertTo-Json Mar 14, 2022 at 8:07 • non-recursive Try it online! Mar 14, 2022 at 8:16 # Julia 1.0, 25 bytes a^b=@show(a[1])b^a[2:end] Try it online! prints the values and ends with an error # Julia 1.0, 30 bytes >(b)=[] >(b,a,A...)=[a;A>b...] Try it online! expects b>a..., returns an actual list # C (gcc), 68 bytes Takes 0-terminated arrays as input. f(a,b)int*a,*b;{for(;*a;!*b?a=b:b++)printf("%d %d "+3*!*b,*a++,*b);} Try it online! # Vyxal, 6 bytes Zf0€÷^ Try it Online! Looks like 05AB1E beats Vyxal this time. Takes input in reversed order. Zf0€÷^ # Leaving out this comment makes the explanation kinda feel empty Z # Zip the lists f # Flatten 0€ # Split on 0 ÷ # Push every item ^ # Reverse the stack # Vyxal, 6 bytes Zf:0ḟẎ Try it Online! A slightly different approach. Still 6 bytes. Zf:0ḟẎ # Leaving out this comment makes the explanation kinda feel empty Z # Zip the lists f # Flatten : # Duplicate the top of the stack 0ḟ # Index of the first 0 Ẏ # Take everything up until that index # Vyxal, 5 bytes Zf0€h Try it Online! Takes input in reversed order. Returns 0 for the case of 2 empty lists, so does not meet the spec. Zf0€h # Leaving out this comment makes the explanation kinda feel empty Z # Zip the 2 lists f # Flatten them 0€ # Split on 0 h # Get the first item # Arturo, 42 bytes f:$[a,b][([]=a)?->a->@[a\0]++f b drop a 1]

Try it

f:\$[a,b][          ; a function f taking two lists a and b
([]=a)?          ; is a empty?
->a              ; if so, return a
->               ; otherwise,
@[a\0]         ; the first element of a as a list
++             ; concatenated with
f b drop a 1   ; the result of calling f with b and a without its first element
]                  ; end function

# Japt-g, 7 bytes

íV c óÏ

Try it

íV c óÏ     :Implicit input of arrays U & V
íV          :Interleave U with V, padding V with null
c        :Flatten
ó      :Partition before elements
Ï     :That are falsey
:Implicit input of first element

## 5 bytes

By taking input as a 2D array, with the order reversed.

ÕcÔóÏ

Try it

ÕcÔóÏ     :Implicit input of 2D array
Õ         :Transpose, padding the first array with null
c        :Flat map
Ô       :Reverse
óÏ     :As above
:Implicit input of first element