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.
sequence 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 code-golf 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
-
4\$\begingroup\$ Relevant video: youtu.be/zvMAoPq7rXU \$\endgroup\$lyxal– lyxal ♦2021年06月29日 00:47:46 +00:00Commented Jun 29, 2021 at 0:47
-
1\$\begingroup\$ This challenge is triggering after a year and a half of social distancing. Now imagine person number 18 sneezes at the end... \$\endgroup\$Darrel Hoffman– Darrel Hoffman2021年06月29日 17:26:51 +00:00Commented Jun 29, 2021 at 17:26
10 Answers 10
Jelly, 12 bytes
p1Ṛ;@pỤɓḊU^1
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 p
roduct of [1..height]
and that. The result is a list of ×ばつ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 ×ばつ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 index35
, - and the second smallest element
[1,2]
is at index5
, - and the third smallest element
[1,3]
is at index6
, - ...
- and the largest element
[5,7]
is at index26
.
so in other words, the "grade" Ụ
is an elevator sequence, and we're done.
-
3\$\begingroup\$ Very nice. I was wondering if there was an approach like this. \$\endgroup\$Jonah– Jonah2021年06月29日 13:59:57 +00:00Commented Jun 29, 2021 at 13:59
-
\$\begingroup\$ As for
4RUW€¤
,9p1$Ṛ¤
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 \$\endgroup\$Unrelated String– Unrelated String2021年06月29日 14:23:17 +00:00Commented Jun 29, 2021 at 14:23 -
\$\begingroup\$ ...ooh, nice job actually shaving a byte off with that before I could post a worse version of it \$\endgroup\$Unrelated String– Unrelated String2021年06月29日 14:25:58 +00:00Commented Jun 29, 2021 at 14:25
-
1\$\begingroup\$ Finally \$\endgroup\$Unrelated String– Unrelated String2021年06月29日 14:50:14 +00:00Commented Jun 29, 2021 at 14:50
-
\$\begingroup\$ (
p;p1Ṛ¥ỤɓḊU^1
is more or less the same thing if the structure better suits your tastes) \$\endgroup\$Unrelated String– Unrelated String2021年06月29日 14:52:27 +00:00Commented Jun 29, 2021 at 14:52
Python 2, (削除) 75 (削除ここまで) (削除) 69 (削除ここまで) (削除) 50 (削除ここまで) (削除) 48 (削除ここまで) 45 bytes
lambda w,h,i:[w*h+~i/w,1^~i%w+i/w*~-w][i%w>0]
-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 sequence 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
.
-
\$\begingroup\$ 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)]
\$\endgroup\$dingledooper– dingledooper2021年06月29日 01:52:10 +00:00Commented Jun 29, 2021 at 1:52 -
\$\begingroup\$ @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) \$\endgroup\$fireflame241– fireflame2412021年06月29日 01:54:28 +00:00Commented Jun 29, 2021 at 1:54
-
\$\begingroup\$ I think you can do
-i%-w-~(i/w)*~-w^1
instead of(w-i%w-1^1)+i/w*~-w
. \$\endgroup\$Arnauld– Arnauld2021年06月29日 06:23:12 +00:00Commented Jun 29, 2021 at 6:23 -
\$\begingroup\$ @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
or1^w-1+i-i/w-i%w*2
both work, saving another byte. \$\endgroup\$fireflame241– fireflame2412021年06月29日 07:13:51 +00:00Commented Jun 29, 2021 at 7:13 -
\$\begingroup\$ I think
w-i%w-1
can be reduced to~i%w
? \$\endgroup\$dingledooper– dingledooper2021年06月29日 07:25:24 +00:00Commented Jun 29, 2021 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
Jelly, (削除) 18 (削除ここまで) 17 bytes
×ばつμð_ḶœsḂ_$Þ€ż@_ⱮF
-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Ḃ_$Þ€ż@_×ばつ
. (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.@-@*
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)
Japt, (削除) 26 (削除ここまで) (削除) 24 (削除ここまで) 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.
×ばつõ
oNg)íUòVÉ mò mw)c f
×ばつõ\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 ×ばつ]
\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
-
\$\begingroup\$ Looks like your middle column exits backwards \$\endgroup\$Unrelated String– Unrelated String2021年06月29日 10:47:07 +00:00Commented Jun 29, 2021 at 10:47
-
1\$\begingroup\$ @UnrelatedString lol fixed \$\endgroup\$2021年06月29日 13:14:22 +00:00Commented Jun 29, 2021 at 13:14
Charcoal, 29 bytes
×ばつθηι
Try it online! Link is to verbose version of code. Outputs the 1-indexed list. Explanation:
NθNηFη
Input the width and height and loop over each row of the lift.
IEθ⎇κ
Loop over each column of the lift; ...
×ばつ⊖θ⊕ικ⊗¬%κ2
... 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 ×ばつ5
lift: the 0-indexed column variable k
loops from 0
to 6
; 0
gets mapped to the centre column, which is ×ばつ5-i=33
, while the columns 1
to 6
get mapped first to ×ばつ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
.
Vyxal R
, 13 bytes
ɽ›Ṙ1꘍Ẋ01v"Ṙ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
0 # 1...height
1v" # Each paired with 1
Ṙ # Reverse
J # Append that to the previous
⇧ # Grade