Serp
Serp

Reputation: 37

Interview question medium, a little help please

A train has a maximum capacity of n passengers overall, which means each carriage's capacity will share an equal proportion of the maximum capacity.

Create a function which returns the index of the first carriage which holds 50% or less of its maximum capacity. If no such carriage exists, return -1.

find_a_seat(200, [35, 23, 18, 10, 40]) ➞ 2

# There are 5 carriages which each have a maximum capacity of 40 (200 / 5 = 40).
# Index 0's carriage is too full (35 is 87.5% of the maximum).
# Index 1's carriage is too full (23 is 57.5% of the maximum).
# Index 2's carriage is good enough (18 is 45% of the maximum).
# Return 2.

def find_a_seat(n, lst):
    a = n // len(lst)
    return [[i for i, j in enumerate(lst) if j / a <= 0.5]+[-1]][0][0]



print(find_a_seat(200, [35, 23, 18, 10, 40]))

Can you please explain why are we looping i for i, and not using it futher, and the end of solution --> [-1]][0][0] -- what does it exactly do

Upvotes: 0

Views: 152

Answers (1)

mozway
mozway

Reputation: 262149

[i for i, j in enumerate(lst) if j / a <= 0.5] returns the list of carriages with capacity ≤ 50%, if any. This means that if there are none, this will be an empty list.

The [i for i in X if condition] acts as a filter: for each element in X, keep them if they match the condition. Here enumerate(lst) give the index (i) and the value (j) for each step of the loop.

Then +[-1] adds -1 at the end of the list. If will thus be the first item if the previous list is empty.

Finally [0][0] slices the first item, either the first carriage number with capacity ≤ 50%, or -1

demonstration with provided example:

>>> [i for i, j in enumerate(lst) if j / a <= 0.5]
[2, 3]
>>> [[i for i, j in enumerate(lst) if j / a <= 0.5]+[-1]]
[[2, 3, -1]]
>>> [[i for i, j in enumerate(lst) if j / a <= 0.5]+[-1]][0]
[2, 3, -1]
>>> [[i for i, j in enumerate(lst) if j / a <= 0.5]+[-1]][0][0]
2

possible alternative

This solution stops at the first match (if any), else returns -1

from itertools import dropwhile
a = n // len(lst)
n = 200
lst = [35, 23, 18, 10, 40]
next(dropwhile(lambda i: lst[i]/a>0.5, range(len(lst))), -1)

Upvotes: 1

Related Questions