As mentioned in @rolfl comment. What this program does is that it "resequences the cards using a fixed system and count the number of times the resequencing happens before the output is the same as the input."
I was wondering how I could make this program faster or perhaps use less memory. I thought about using dictionaries
instead of lists
as they have faster look ups. I'm not sure how to decrease the memory size of this program.
num_cards = input("Please enter the number of cards in the deck: ")
def num_of_round(num_cards):
rounds = 0
orig_order = range(1,num_cards + 1)
card_list = list(orig_order)
table_list = []
while 1:
while len(card_list) > 0:
table_list.append(card_list[0]) # STEP 1: add top card to table
card_list.remove(card_list[0]) # remove top card from deck
if len(card_list) == 0:
break
card_list.append(card_list[0]) # STEP 2: after removal of card, put top card on bottom of deck
card_list.remove(card_list[0]) # update ordering of deck
rounds += 1 # a round has passed
table_list.reverse()
card_list, table_list = table_list, card_list
if card_list == orig_order:
break
print rounds
num_of_round(num_cards)
-
\$\begingroup\$ Is this 'shuffle' code? It appears to resequence the cards using a fixed system and count the number of times the resequencing happens before the output is the same as the input.... right? \$\endgroup\$rolfl– rolfl2013年11月18日 02:22:21 +00:00Commented Nov 18, 2013 at 2:22
-
\$\begingroup\$ @rolfl yes it is \$\endgroup\$Liondancer– Liondancer2013年11月18日 02:23:12 +00:00Commented Nov 18, 2013 at 2:23
-
1\$\begingroup\$ Sounds like if you wanted to, you could reduce this to essentially no memory, and no time, by working out what the function is that describes the problem, and then just do the math rather than doing the actual work \$\endgroup\$rolfl– rolfl2013年11月18日 02:27:32 +00:00Commented Nov 18, 2013 at 2:27
-
\$\begingroup\$ @rolfl that is something I also considered. I thought it would be too hard to come up with a formula to compute this. \$\endgroup\$Liondancer– Liondancer2013年11月18日 02:31:11 +00:00Commented Nov 18, 2013 at 2:31
1 Answer 1
Here is a good opportunity to break out a couple of tools from the standard library.
collections.deque
offers fast appends and pops on both ends and is thus perfect to represent your deck of cards, when you take cards from the top and put some back to the bottom.
itertools.cycle
can be used to switch between the two destinations of the cards: the top of the pile (table_list.appendleft
) and the bottom of the deck (card_list.append
). Using appendleft
there avoids the need to reverse the pile each round.
Also, a while True
loop with a round += 1
inside could be a for round ...
loop instead.
from collections import deque
from itertools import cycle, count
def num_of_round(num_cards):
orig_order = deque(xrange(num_cards))
card_list = deque(orig_order)
table_list = deque()
for rounds in count(1):
appendfunc = cycle((table_list.appendleft, card_list.append))
while card_list:
append = next(appendfunc)
append(card_list.popleft())
card_list, table_list = table_list, card_list
if card_list == orig_order:
return rounds
Explore related questions
See similar questions with these tags.