# 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
• Is it okay to ignore 0-sized arrays? C and C++ does not permit them in the language as per the standard, although some compilers allow them as an extension. Mar 13, 2022 at 16:52
• In all languages I have used zip is typically defined as transforming a tuple of lists into a list of tuples; I cannot say if it's universal, but it's prevalent enough that I would recommend not using zip here, but interleave instead. Mar 16, 2022 at 10:07
• Doesn't zipping require the same number of items from each group? Your test cases have three that don't. Should they be these instead? [1,2,3] [] -> [] [1,2] [3] -> [1,3] [1,2,3,4,5] [11, 12, 13] -> [1,11,2,12,3,13] Jan 7 at 22:59
• @LeroyScandal The number of items between the two lists can differ by up to one, although the input that provides more values must always be the first one. That's a direct result of the way its described. Jan 8 at 5:33

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


# Haskell, 19 bytes

(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!

Port of the Haskell solution.

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

# 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


# 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  # Uiua, 9 bytes SBCS ↙⊗0.♭⍉⬚0⊟  Try it! Port of Jonah's J answer. # Vyxal 3, 5 bytes Zf0sh  Try it Online! takes input in reverse order # Perl 5-MList::Util=min, 65 bytes sub{($a,$b)=@_;grep/./,map{$_,shift@$b}@$a[0..min(@$b+0,$#{\$a})]}


Try it online!