On 8/14/2010 10:52 AM, Baba wrote:
for n_nuggets in range(50):
result1 = can_buy(n_nuggets)
result2 = can_buy(n_nuggets+1)
result3 = can_buy(n_nuggets+2)
result4 = can_buy(n_nuggets+3)
result5 = can_buy(n_nuggets+4)
result6 = can_buy(n_nuggets+5)
if result1!=[] and result2!=[] and result3!=[] and result4!=[] and
result5!=[] and result6!=[]:
if (n_nuggets+5)-n_nuggets==5:
print n_nuggets-1
break
i suppose this can be tweaked to make it shorter? For instance i
wonder if i can do the same with less variable to be defined?
[Other responders have covered a lots of the points I make below. I
guess I need to be quicker!]
First, congratulations on getting to a solution! Code can very often be
made shorter, although it's not always worth your while to do so. And
often, shorter code is less understandable code -- which makes a big
difference if you need to revisit the code later on.
Here are some things that can be done with your for-loop:
1. You don't need this "if" test, because it's always true:
if (n_nuggets+5)-n_nuggets==5:
2. Whenever you find yourself inventing a series of variables like
"result1", "result2", "result3", etc., think about using a list instead.
results = []
for i in range(6):
results.append(can_buy(n_nuggets + i))
And to get really fancy, you can use a single "list comprehension"
statement to do it all
results = [can_buy(n_nuggets + i) for i in range(6)]
3. Your "if" statement tests whether all the lists are non-empty. In
Python, expressions (a) and (b) are equivalent:
(a) if result[0] != []
(b) if result[0]
So your "if" test can be expressed as:
if (result[0] and result[1] and result[2] and result[3]
and result[4] and result[5])
(The parentheses are not required by "if", but they *do* enable you
to split the expression across two or more lines.) And you can use the
"all" function to rescue this cumbersome statement;
if all(results)
After all this work, the code is getting pretty short:
for n_nuggets in range(50):
results = [can_buy(n_nuggets + i) for i in range(6)]
if all(results):
print n_nuggets-1
break
4. The variable "results" is defined in one statement, and then is used
just once, in the very next statement. There's no harm in that, and I
think it makes the mode easier to understand, but you can get rid of it:
for n_nuggets in range(50):
if all([can_buy(n_nuggets + i) for i in range(6)]):
print n_nuggets-1
break
But wait, there's more ... :-) So far, we've just refined the
*implementation* of your algorithm. But the algorithm itself could use
some work.
* When n_nuggets==0, we compute can_buy(0), can_buy(1), can_buy(2),
can_buy(3), can_buy(4), and can_buy(5).
* When n_nuggets==1, we compute can_buy(1), can_buy(2), can_buy(3),
can_buy(4), can_buy(5), and can_buy(6).
... and so on. We can use an algorithm in which can_buy(i) is computed
just once for each value of i:
can_buy_count = 0
n_nuggets = 0
while n_nuggets < 50:
if can_buy(n_nuggets):
can_buy_count += 1
else:
can_buy_count = 0
if can_buy_count == 6:
print n_nuggets - 6
break
else:
n_nuggets += 1
And here's how you could shorten *this* code:
### cbc = "can buy count"
cbc = 0
n_nuggets = -1
while n_nuggets < 50:
n_nuggets += 1
cbc = cbc+1 if can_buy(n_nuggets) else 0
if cbc == 6:
print n_nuggets - 6
break
HTH,
John
--
http://mail.python.org/mailman/listinfo/python-list