I am a beginner in Python-3. I was solving a level 2 challenge in Google Foobar. Given an initial amount of items (LAMBs) I have to distribute it among individuals, who are ranked according to seniority, while adhering to the following rules:
- The junior most individual gets 1 Lamb
- An immediately senior individual can't get more than twice their juniors lambs, otherwise the junior will rebel
- A senior individual can't get less lambs than the sum of their 2 previous juniors, otherwise the senior will rebel
- In case lambs are leftover and adding a senior does not violate any previous rules, they must be added.
The goal is to find the difference between how many individuals can be paid if we pay the minimum amount to each (stingy) and the maximum amount to each (generous). I noticed that stingy condition resembles a Fibonacci sequence and the generous condition is sum of powers of 2. My code is as follows:
from math import log2
def solution(total_lambs)
return (stingy(total_lambs) - generous(total_lambs))
def stingy(total_lambs)
if (total_lambs == 1): # from condition 1 at least 1 individual gets paid
return 1
elif (total_lambs == 2): # from condition 2 and 4 the most each can is 1
return 2
else:
ind, total, x0, x1 = 2, 2, 1, 1 # no. individuals, sum of Fib seq, intial Fib nos.
while (total <= total_lambs):
x0, x1 = x1, x0 + x1 # advancing the Fib seq
total = total + x1 # total is the sum of lambs paid
if (total > total_lambs):
return ind
else:
ind = ind + 1
def generous(total_lambs):
if (total_lambs == 1):
return 1
if (total_lambs == 2):
return 2
else:
ind = int(log2(capital + 1)) # typecasting to int removes decimals
if (total_lambs - 2**n + 1 >= 2**(n - 1) + 2**(n - 2)): # condition 2, 3 and 4
return ind + 1
else:
return ind
Please suggest improvements wherever possible.
-
2\$\begingroup\$ Great first question! \$\endgroup\$Reinderien– Reinderien2020年11月23日 13:06:50 +00:00Commented Nov 23, 2020 at 13:06
-
3\$\begingroup\$ Can you provide a link to the original question? \$\endgroup\$Reinderien– Reinderien2020年11月23日 13:07:11 +00:00Commented Nov 23, 2020 at 13:07
-
\$\begingroup\$ @reinderien I unfortunately submitted my response before i saved the original question so i can't copy it verbatim. However, it is available online if you search foobar Lovely lucky LAMBs. \$\endgroup\$Roni Saiba– Roni Saiba2020年11月24日 00:58:07 +00:00Commented Nov 24, 2020 at 0:58
2 Answers 2
Early-returns
else-after-return is redundant, so your stingy
is equivalent to
if (total_lambs == 1): # from condition 1 at least 1 individual gets paid
return 1
if (total_lambs == 2): # from condition 2 and 4 the most each can is 1
return 2
ind, total, x0, x1 = 2, 2, 1, 1 # no. individuals, sum of Fib seq, intial Fib nos.
while (total <= total_lambs):
x0, x1 = x1, x0 + x1 # advancing the Fib seq
total = total + x1 # total is the sum of lambs paid
if (total > total_lambs):
return ind
ind = ind + 1
Return parens
You have a mix of this style:
return 1
and this style:
return (stingy(total_lambs) - generous(total_lambs))
the latter not needing outer parens. Probably best to go with the non-parenthetical style. The same is true of
while (total <= total_lambs):
In-place addition
total = total + x1
ind = ind + 1
can be
total += x1
ind += 1
-
\$\begingroup\$ Thank you. As you mentioned in another comment, what can be a good name for storing Fibonnacci numbers? \$\endgroup\$Roni Saiba– Roni Saiba2020年11月24日 01:00:43 +00:00Commented Nov 24, 2020 at 1:00
-
\$\begingroup\$ A good name? For which variable? \$\endgroup\$Reinderien– Reinderien2020年11月24日 01:01:42 +00:00Commented Nov 24, 2020 at 1:01
-
\$\begingroup\$ Storage of the Fibonacci numbers. \$\endgroup\$Roni Saiba– Roni Saiba2020年11月24日 01:09:14 +00:00Commented Nov 24, 2020 at 1:09
-
1\$\begingroup\$ Oh, you mean
x0
andx1
.prev
andcurrent
maybe? \$\endgroup\$Reinderien– Reinderien2020年11月24日 01:25:40 +00:00Commented Nov 24, 2020 at 1:25
apart from the improvements mentioned above, for the stingy function you can also reduce the amount of code by using a list with the last 2 fibonacci members, and integrating the initial conditions into the logic
def stingy(total_lambs):
paid = 0
previous = [1, 0]
while total_lambs > 0:
paid += 1
previous = [sum(previous), previous[0]]
total_lambs -= previous[0]
return paid
-
1\$\begingroup\$ Ish. Overall this is a good suggestion, but framing this as a list doesn't make sense. Just have two variables. \$\endgroup\$Reinderien– Reinderien2020年11月23日 17:03:46 +00:00Commented Nov 23, 2020 at 17:03
-
\$\begingroup\$ In other words, keep the OP's
x0
,x1
, possibly with better names. \$\endgroup\$Reinderien– Reinderien2020年11月23日 17:05:04 +00:00Commented Nov 23, 2020 at 17:05 -
\$\begingroup\$ Thanks, i will keep this structure in mind for future coding. I framed my function in this way as the rule 3 in original question had an explanation that it is not applicable if only upto 2 individuals get paid. So I did not think of this elegant way. \$\endgroup\$Roni Saiba– Roni Saiba2020年11月24日 01:06:21 +00:00Commented Nov 24, 2020 at 1:06
Explore related questions
See similar questions with these tags.