# Elevator sequence

Totally not inspired by Lyxal repeatedly mentioning elevators in chat :P

## Challenge

In short: simulate some people filling up an elevator and then leaving it.

The elevator is simplified as a grid, where each person can occupy one cell of the grid. The height and width of the grid is the input parameter. The width is always odd, and it has an opening of 1 unit width at the center of the top side. The following diagram shows an elevator of width 5 and height 4, initially empty:

+------   ------+
| ?  ?  ?  ?  ? |
| ?  ?  ?  ?  ? |
| ?  ?  ?  ?  ? |
| ?  ?  ?  ?  ? |
+---------------+


Now, 20 people, numbered 1 to 20 in the order of boarding, start filling up the elevator. People tend to stick to the front, but cannot block other people boarding when some spots are still empty. As a simplification, let's simply assume that people fill the spots in the left-right-left-right fashion from the frontmost row, leaving the middle column empty (which is then filled by the last few people):

+------    ------+
|  1  3 20  4  2 |
|  5  7 19  8  6 |
|  9 11 18 12 10 |
| 13 15 17 16 14 |
+----------------+


When people leave the elevator, they do row-by-row, starting with the center column and then alternating left and right sides. So the order of leaving is as follows:

20, 3, 4, 1, 2, 19, 7, 8, 5, 6, 18, 11, 12, 9, 10, 17, 15, 16, 13, 14


The challenge is to produce this sequence for given width and height of the elevator (again, the width is guaranteed to be odd).

You can use 0-based numbering instead of 1-based.

I/O applies. The I/O format can be in one of three ways:

• Take width and height, and output the full sequence
• Take width, height, and index (0- or 1-based), and output the n-th number (index is guaranteed to be valid)
• Take width, height, and n (at most the number of cells), and output the first n numbers

The standard rules apply. The shortest code in bytes wins.

## More test cases

width = 1, height = 1
output = 1

width = 1, height = 10
output = 10, 9, 8, 7, 6, 5, 4, 3, 2, 1

width = 9, height = 1
output = 9, 7, 8, 5, 6, 3, 4, 1, 2

width = 7, height = 5
output = 35, 5, 6, 3, 4, 1, 2, 34, 11, 12, 9, 10, 7, 8, 33, 17, 18,
15, 16, 13, 14, 32, 23, 24, 21, 22, 19, 20, 31, 29, 30, 27, 28, 25, 26

• Relevant video: youtu.be/zvMAoPq7rXU Jun 29 at 0:47
• This challenge is triggering after a year and a half of social distancing. Now imagine person number 18 sneezes at the end... Jun 29 at 17:26

# Jelly, 12 bytes

p1Ṛ;@pỤɓḊU^1


Try it online!

Takes (height, width) arguments and returns the sequence.

Unrelated String saved two bytes. Thank you!

## Explanation for (width, height) = (7, 5)

ḊU^1 is [width..2] each XORed with 1: [6,7,4,5,2,3].

We take the Cartesian product of [1..height] and that. The result is a list of 6×5 pairs:

[[1,6], [1,7], [1,4], [1,5], [1,2], [1,3],
[2,6], [2,7], [2,4], [2,5], [2,2], [2,3],
[3,6], [3,7], [3,4], [3,5], [3,2], [3,3],
[4,6], [4,7], [4,4], [4,5], [4,2], [4,3],
[5,6], [5,7], [5,4], [5,5], [5,2], [5,3]]


Then, p1Ṛ;@ appends [[5,1],[4,1],[3,1],[2,1],[1,1]] to this list, for a total of 7×5 pairs.

[[1,6], [1,7], [1,4], [1,5], [1,2], [1,3],
[2,6], [2,7], [2,4], [2,5], [2,2], [2,3],
[3,6], [3,7], [3,4], [3,5], [3,2], [3,3],
[4,6], [4,7], [4,4], [4,5], [4,2], [4,3],
[5,6], [5,7], [5,4], [5,5], [5,2], [5,3], [5,1], [4,1], [3,1], [2,1], [1,1]]


Wow, this all seems like it's getting us nowhere! But:

• The lexicographically smallest element [1,1] is found at index 35,
• and the second smallest element [1,2] is at index 5,
• and the third smallest element [1,3] is at index 6,
• ...
• and the largest element [5,7] is at index 26.

so in other words, the "grade" Ụ is an elevator sequence, and we're done.

• Very nice. I was wondering if there was an approach like this. Jun 29 at 13:59
• As for ⁴RUW€¤, ⁹p1$Ṛ¤ can substitute for the same length, but I'm not sure how to rearrange things to be free of the $/¤. ...It also seems that this handles width 1 incorrectly, but as luck would have it at least some list builtins rangify Jun 29 at 14:23
• ...ooh, nice job actually shaving a byte off with that before I could post a worse version of it Jun 29 at 14:25
• Finally Jun 29 at 14:50
• (p;p1Ṛ¥ỤɓḊU^1 is more or less the same thing if the structure better suits your tastes) Jun 29 at 14:52

# Python 2, 75695048 45 bytes

lambda w,h,i:[w*h+~i/w,1^~i%w+i/w*~-w][i%w>0]


Try it online!

-6 bytes thanks to a suggestion from @dingledooper to persue a single for loop

-2 bytes from following a lead from @Arnauld

-3 bytes from @dingledooper

Outputs the sequence as 0-based instead of 1-based.

Given a (0-based) index i, this returns the i-th entry of the sequence as per tag defaults.

Format: The answers can use one of the following input/output methods: ∘ Given some index n it can return the n-th entry of the list. ∘ ...

Notes: ~y == -y - 1, ~-w == w-1 (avoids parentheses), and two-argument bitwise operators have very low precedence, so w-i%w-1^1 = (w-i%w-1)^1.

• Interesting, I had come with the exact same approach, except using one for loop. It's 66 bytes with it: lambda w,h:[[w*h+~i/w,(~i%w^1)+i/w*~-w][i%w>0]for i in range(w*h)] Jun 29 at 1:52
• @dingledooper Interesting, I saw the first sentence of your comment before you deleted it and came up with almost exactly the same thing for 70 bytes (yours does not work quite right) Jun 29 at 1:54
• I think you can do -i%-w-~(i/w)*~-w^1 instead of (w-i%w-1^1)+i/w*~-w. Jun 29 at 6:23
• @Arnauld I avoided pulling out the ^1 because I thought +i/w*~-w could affect the parity, but ~-w == w-1 is always even, so it always works. With that in mind, 1^w-i%w-1+i/w*~-w or 1^w-1+i-i/w-i%w*2 both work, saving another byte. Jun 29 at 7:13
• I think w-i%w-1 can be reduced to ~i%w? Jun 29 at 7:25

# JavaScript (ES6), 39 bytes

Expects (w, h, n) and returns the n-th term. Everything is 0-indexed.

(w,h,n,y=n/w)=>n%w?-n%w-~y*~-w^1:w*h+~y


Try it online!

# Jelly, 18 17 bytes

×µð_ḶœsḂ_$Þ€ż@_ⱮF  Try it online! -1 byte trading one dyad-identity-dyad chain for another Width on the left, height on the right. 0-indexed. Still feels a bit golfable. Ties the similar, arguments-reversed _ḶœsḂ_$Þ€ż@_ⱮFð@×. (Speaking of tying, take a peek at the edit history for a good laugh.)

×                    Let the product of the arguments
µð                  be the left argument to the following dyadic chain:

_Ḷ                [0 .. product-height-1]
œs              split into as many slices as the height.
Þ€         Sort the elements of each ascending by
Ḃ_\$           (x % 2) - x.
ż@       Interleave the slices after each
_Ɱ     product - each [1 .. height],
F    and flatten to obtain the sequence.


# J, 37 36 bytes

,@(_2|.\|.)"1@i.@(,<:),@,.~[{.i.@-@*


Try it online!

Returns the full sequence.

Zips the last "height" elements, reversed, with the remaining elements taken in rows of "width - 1", with each row re-arranged by reversing it, and then taking chunks of 2 and reversing each of those. The resulting matrix is flattened.

# JavaScript (ES6), 67 bytes

w=>h=>(g=c=>[c?w*r-r-c^1:w*h-r,...++c-w?g(c):r++-h?g(0):[]])(0,r=1)


Try it online!

# Japt, 2624 23 bytes

Ugly as all hell and almost certainly golfable but it does the job without need for a mathematical formula.

Takes height as the first input, width as the second and outputs the full sequence.

N×õ
oNg)íUòVÉ mò mw)c f


Try it

N×õ\noNg)íUòVÉ mò mw)c f     :Implicit input of integers U=height & V=width
N                            :The array of all inputs (i.e [U,V])
×                           :Reduce by multiplication
õ                          :Range [0,N×]
\n                        :Reassign to U
o                       :Remove and return the last
Ng                     :  First element of N (i.e., original U) elements
)                    :End remove
í                   :Interleave
Uò                  :  Partitions of the remaining elements of U of length
VÉ                :    V-1
m              :  Map
ò             :    Partitions of length 2
m           :  Map
w          :    Reverse
)         :End interleave
c        :Flatten
f      :Filter


# Jelly, 34 bytes

R}Uð×RœṖ@’×‘ɗœsL}¹;"U}¥ʋ/s€2Ṛ€FðỊ?


Try it online!

# Charcoal, 29 bytes

ＮθＮηＦηＩＥθ⎇κ⁺⁻×⊖θ⊕ικ⊗¬﹪κ²⁻×θηι


Try it online! Link is to verbose version of code. Outputs the 1-indexed list. Explanation:

ＮθＮηＦη


Input the width and height and loop over each row of the lift.

ＩＥθ⎇κ


Loop over each column of the lift; ...

⁺⁻×⊖θ⊕ικ⊗¬﹪κ²


... the columns leave in swapped pairs, ...

⁻×θηι


... but the centre column of the row leaves first.

Example for the 3rd (0-indexed row i=2) row of the 7×5 lift: the 0-indexed column variable k loops from 0 to 6; 0 gets mapped to the centre column, which is 7×5-i=33, while the columns 1 to 6 get mapped first to 6×3-k or 17, 16, 15, 14, 13, 12, but 2 is then added to alternate terms, yielding the desired result 17, 18, 15, 16, 13, 14.

# VyxalR, 13 bytes

ɽ›Ṙ1꘍Ẋ⁰1v"ṘJ⇧


Try it Online! Returns 0-indexed.

A port of Lynn's excellent Jelly answer - go upvote that, and have a look at their explanation, which is much better than this. Returns 0-indexed.

ɽ›Ṙ           # Width...2
1꘍         # xor 1
Ẋ        # Cartesian product with 1...height
⁰       # 1...height
1v"    # Each paired with 1
Ṙ   # Reverse
J  # Append that to the previous